![]() |
Suchmaske nach FindFirst verändern?
Hallo, weiß jemand wie man NACH FindFirst die Suchmaske verändern kann, sodass FindNext dann diese veränderte Suchmaske verwendet?
|
Re: Suchmaske nach FindFirst verändern?
Ganz einfach: Es ist nicht möglich.
Wie auch? Ich meine zuerst holst du mit FindFirst eine Liste von passenden Dateien, die du dann mit FindNext durchgehen kannst. Und dann willst du eine neue Suche mit einer neuen Liste starten, nur mit der alten Liste von Dateien. :pale: |
Re: Suchmaske nach FindFirst verändern?
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
FindFirst initialisiert die Suche und stellt quasi intern eine Dateiliste zusammen
und es liefert auch gleich das erste Suchergebnis. FindNext liefert dann sozusagen die nächste Datei aus dieser Liste. |
Re: Suchmaske nach FindFirst verändern?
Ja, aber irgendwo muss dann diese "Liste von gefundenen passenden Dateien" sich doch befinden - in einem anderen Universum?
|
Re: Suchmaske nach FindFirst verändern?
Kann das sein, dass du eine Auswahl von Dateien suchen möchtest, und diese dann nochmal filtern möchtest? Warum prüfst du dann nicht nach jedem FindNext, ob die Datei deinem neuen Muster entspricht? Oder, was hindert dich daran, das Muster schon am Anfang zu nutzen?
|
Re: Suchmaske nach FindFirst verändern?
Nein, ich möchte u.a. herausfinden, wie FindFirst und Findnext WIRKLICH funktionieren.
Wenn FindFirst wirklich wie oben behauptet eine "Liste der passenden Dateien" erstellt, dann müsste: 1. FindFirst in einem Verzeichnis mit sehr vielen Dateien (z.B. 100.000) erheblich langsamer sein als in einem Verzeichnis mit z.B. nur 3 Dateien, was nach meiner Erfahrung nicht zutrifft, 2. diese Liste sich irgendwo in unserem Universum befinden. |
Re: Suchmaske nach FindFirst verändern?
Also:
FindFirst erstellt ein SearchHandle, und listet die erste Datei auf, die Windows findet, die zu den Parametern passt. FindNext nutzt dann diese Handle, und findet die nächste Datei, die eben genau zu diesem Handle passt. Und ja, je mehr Dateien vorhanden sind, umso länger dauert das. Ist das bei dir nicht der Fall, dann hat der Cache zugeschlagen. Interessant dazu auch die Remarks-Sektionen der MSDN-Einträge zu ![]() ![]() Das hat nix mit dem Universum zu tun. Sollte dir aber klar sein. //Edit: Wobei man hier "länger" vielleicht noch genauer definieren sollte. ;) |
Re: Suchmaske nach FindFirst verändern?
Zitat:
So wie ich die Sache jetzt sehe, beauftragt FindFirst Windows mit der Suche und erhält von Windows: 1. ein Such-Ergebnis zurück, das im SearchRecord gespeichert wird, und 2. ein Handle auf eben diese von Windows erstellte/durchgeführte Suche (das ebenfalls im SearchRecord gespeichert wird), das dann FindNext (über SearchRecord) übergeben werden kann. Ergebnis: Die Suche wird von Windows durchgeführt und die Parameter einer einmal durchgeführten/erstellten Suche können nicht mehr über die WinAPI beeinflusst werden. Könnte man das so stehen lassen? |
Re: Suchmaske nach FindFirst verändern?
Zitat:
es sei denn, man geht direkt auf die grundlegenden und undokumentierten WinAPI's los, denn da wird quasi jedesmal in FindNext die Suchmaske auf die nächsten Dateien angewendet, bis eine passende Datei gefunden wird und diese wird dann zurückgegeben. Aber diese interen APIs können sich auch mal ändern, und dann geht es z.B. mit der nächsten Windowsversion nicht mehr und da undokumentiert, gibt es fast keine, welche wissen, wie man diese AOIs aktuell nutzt. Was aber möglich ist: alles liefern lassen und dann selber filtern. |
Re: Suchmaske nach FindFirst verändern?
Zitat:
1. Im Verzeichnis der aktuell geladenen Datei alle Dateien des gewünschten Dateityps suchen und dann in einer eigenen Liste SLNaechsteDateien speichern. Wenn der Anwender die Funktion "Lade nächste Datei im Verzeichnis der aktuell geladenen Datei" ausführt, wird die nächste Datei aus der Liste SLNaechsteDateien geladen und der Listeneintrag dann gelöscht, usw. Diese Methode hat einige Nachteile: a) Die Liste könnte nicht mehr aktuell sein, weil unterdessen Dateien im Verzeichnis etwa gelöscht wurden. b) Aufwändige und fehleranfällige Verwaltung der Liste: Wenn der Anwender manuell eine Datei aus einem anderen Verzeichnis lädt, muss die Liste zurückgesetzt und neu eingelesen werden, usw. 2. Wenn der Anwender die Funktion "Lade nächste Datei im Verzeichnis der aktuell geladenen Datei" ausführt, sucht das Programm mit FindFirst und der Dateimaske des gewünschten Dateityps im Verzeichnis der aktuell geladenen Datei und lädt die gefundene Datei. SearchRecord wird in einer globalen Variable gespeichert, sodass beim nächsten Ausführen der Funktion "Lade nächste Datei im Verzeichnis der aktuell geladenen Datei" nur mehr FindNext mit der vorher initiierten globalen Variable SearchRecord aufgerufen werden muss. Vorteil: a) FindNext findet nur real existierende Dateien (s. Nachteil 1a). Nachteil: b) Ebenso aufwändige Verwaltung, da irgendwann FindClose aufgerufen werden und immer wieder überprüft werden muss, ob SearchRecord noch geöffnet bzw. das Searchhandle noch gültig ist. 3. Meine ursprüngliche Absicht - die sich nun wohl als unrealistisch herausgestellt hat - war: Mit FindFirst nach der aktuell geladenen Datei suchen und dann FindNext mit der Dateimaske des gewünschten Dateityps ausführen:
Delphi-Quellcode:
Welche Methode würdet ihr bevorzugen?
// Prototyp:
function HoleNaechsteDatei: string; var SR: TSearchRec; begin SearchDir := VerzeichnisDerAktuellGeladenenDatei; if FindFirst(SearchDir + AktuellGeladeneDatei, faAnyFile, SR) = 0 then begin AendereDateimaske; // <<<<< nicht möglich!? if FindNext(SR) = 0 then DateiLaden(SR.Name); FindClose(SR); end; end; [Edit: Schreibfehler korrigiert] |
Re: Suchmaske nach FindFirst verändern?
Guten Abend,
vielleich geht es so?
Delphi-Quellcode:
// auch ein Prototyp:
function HoleNaechsteDatei: string; var SR: TSearchRec; begin SearchDir := VerzeichnisDerAktuellGeladenenDatei; if FindFirst(SearchDir + AktuellGeladeneDatei, faAnyFile, SR) = 0 then begin FindClose(SR); AendereDateimaske; // <<<<< nicht möglich!? if FindFirst(AndereDateimaske,faAnyFile,SR) = 0 then //if FindNext(SR) = 0 then DateiLaden(SR.Name); FindClose(SR); end; end; Grüße Klaus |
Re: Suchmaske nach FindFirst verändern?
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Zitat:
Weiß nicht, ob ich dich jetzt richtig verstanden habe... :gruebel: |
Re: Suchmaske nach FindFirst verändern?
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Zitat:
Aber vom Prinzip ist der Weg gleich ja, bis auf die Sache mit dem Namen Pfad und dem entsprechenden Vergleich. |
Re: Suchmaske nach FindFirst verändern?
> Verzeichnisinhalt (gefiltert) auflisten
> Verzeichnisüberwachung einrichten > > wird datei gelöscht, dann wird sie auch aus der Liste gelöscht (wenn sie da drinnen ist) > > wird eine Datei erstellt/reinkopiert, dann wird sie mit der Suchmaske verlichen und wenn es stimmt, dann wird sie an die Liste angehängt |
Re: Suchmaske nach FindFirst verändern?
Habe gerade den Vorschlag von Klaus01 und Daniel G probiert - funktioniert leider nicht:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin // Verzeichnis, das mehrere JPG-Dateien enthält: Form1.Caption := 'F:\test\test1.jpg'; end; procedure TForm1.btnGetNextFileClick(Sender: TObject); var SR: TSearchRec; begin if FindFirst(Form1.Caption, faAnyFile, SR) = 0 then begin FindClose(SR); if FindFirst('F:\test\*.jpg', faAnyFile, SR) = 0 then Form1.Caption := 'F:\test\' + SR.Name; FindClose(SR); end; end; |
Re: Suchmaske nach FindFirst verändern?
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Jetzt hab ich erst gerafft, was du willst... :wall:
Der Vorschlag von Himi, mit der Überwachung des Verzeichnis, dürfte dich zum Ziel führen... |
Re: Suchmaske nach FindFirst verändern?
Zitat:
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
und noch ein Versuch.
Delphi-Quellcode:
Die Rückgabe, wenn keine weitere Datei gefunden wurde sollte noch geregelt werden.
procedure TForm1.FormCreate(Sender: TObject);
begin // Verzeichnis, das mehrere JPG-Dateien enthält: Form1.Caption := 'F:\test\test1.jpg'; bereitsBearbeiteteDateien := TStringList.Create; end; procedure TForm1.btnGetNextFileClick(Sender: TObject); var SR: TSearchRec; fileName: AnsiString; noMoreFiles : Boolean; begin if FindFirst(Form1.Caption, faAnyFile, SR) = 0 then begin fileName := SR.Name; FindClose(SR); if FindFirst('F:\test\*.jpg', faAnyFile, SR) = 0 then begin noMoreFiles := false; while (bereitsBearbeiteteDateien.indexOf(SR.Name) >= 0) and not noMoreFile do begin if FindNext(SR) > 0 then noMoreFiles:= true; end; end; Form1.Caption := 'F:\test\' + SR.Name; FindClose(SR); end; end; Die StringList (bereitsBearbeiteteDateien) muss natürlich entsprechend gepflegt werden. Grüße Klaus |
Re: Suchmaske nach FindFirst verändern?
Liste der Anhänge anzeigen (Anzahl: 1)
Habe jetzt eine ultimative Lösung geschrieben und möchte sie euch nicht vorenthalten:
Delphi-Quellcode:
Ausgehend von einer geladenen Datei wird die nächste Datei im Verzeichnis der geladenen Datei gesucht. Dabei kann bestimmt werden, ob die Suche am Ende des Verzeichnisses gestoppt oder am Beginn des Verzeichnisses fortgesetzt werden soll. So kann man unabhängig von der Position im Verzeichnis der zuerst geladenen Datei alle Dateien durchgehen.
procedure TForm1.LoadAFile(const AFile: string);
var ThisFilePath, ThisFileName: string; begin Form1.Caption := AFile; mmoFilesInDirectory.Lines.Add(AFile); end; procedure TForm1.btnManuallyLoadAFileClick(Sender: TObject); begin if dlgOpen.Execute(Handle) then begin mmoFilesInDirectory.Lines.Clear; LoadAFile(dlgOpen.FileName); end; end; procedure TForm1.FormCreate(Sender: TObject); begin LoadAFile(ExtractFilePath(Application.ExeName) + 'Unit1.dfm'); end; procedure TForm1.btnGetNextFileClick(Sender: TObject); var ActualFilePath, NextFile: string; NextFileFound: Boolean; SearchRec: TSearchRec; begin NextFileFound := False; ActualFilePath := ExtractFilePath(Form1.Caption); // Geladene Datei suchen: if FindFirst(ActualFilePath + '*.*', faAnyFile, SearchRec) = 0 then begin repeat if not (SearchRec.Attr and faDirectory > 0) then begin if AnsiCompareText(ActualFilePath + SearchRec.Name, Form1.Caption) = 0 then BREAK; end; until FindNext(SearchRec) <> 0; end; // Nächste Datei nach der geladenen Datei suchen: while FindNext(SearchRec) = 0 do begin if not (SearchRec.Attr and faDirectory > 0) then begin NextFile := ActualFilePath + SearchRec.Name; // Geladene Datei ausschließen: if AnsiCompareText(NextFile, Form1.Caption) <> 0 then begin LoadAFile(NextFile); NextFileFound := True; BREAK; end; end; end; FindClose(SearchRec); if not NextFileFound then begin if chkStopAtEndOfDirectory.Checked then MessageDlg('Ende des Verzeichnisses!', mtInformation, [mbOK], 0) else begin // Suche erneut am Beginn des Verzeichnisses fortsetzen: if FindFirst(ActualFilePath + '*.*', faAnyFile, SearchRec) = 0 then begin repeat if not (SearchRec.Attr and faDirectory > 0) then begin mmoFilesInDirectory.Lines.Add(''); LoadAFile(ActualFilePath + SearchRec.Name); BREAK; end; until FindNext(SearchRec) <> 0; end; FindClose(SearchRec); end; end; end; Im Anhang befindet sich ein schönes Demo-Programm, mit dem man alles ausprobieren kann. Der Code kann nach Wunsch auch gerne zur Code-Lib hinzugefügt werden. |
Re: Suchmaske nach FindFirst verändern?
Du bist Dir aber schon im Klaren, daß FindFile keine bestimmte Reihenfolge zurück gibt, oder?
|
Re: Suchmaske nach FindFirst verändern?
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Zitat:
![]() Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Zitat:
Zitat:
![]() ![]() Es wird nur zufällig vom Dateisystemtreiber sortiert und daß dieser sortieren muß, ist nicht vorgeschrieben. |
Re: Suchmaske nach FindFirst verändern?
Hier nochmals mein Begleittext zum Demoprogramm: "Ausgehend von einer geladenen Datei wird die nächste Datei [also die Datei nach der geladenen Datei, Anm.] im Verzeichnis der geladenen Datei gesucht."
Wenn dann mit FindFirst die Suche am Beginn des Verzeichnisses fortgesetzt wird, so wird auf diese Weise durch alle Dateien des Verzeichnisses so iteriert, dass beim Erreichen der ursprünglichen Datei jede Datei einmal drangekommen ist. Das ist das Ziel und der Zweck des Programms, nicht mehr und nicht weniger. Und es funktioniert. Probier es einfach mal aus! |
Re: Suchmaske nach FindFirst verändern?
Zitat:
Zitat:
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Das hat insofern damit zu tun, daß die Reihenfolge der Dateien zwar zufällig sortiert und vorallem nicht "statisch" ist.
Bei CD-Laufwerken ist es sortiert, weil die Brennprogramme sortieren und auf der Festplatte sort meistens der NTFS-FileSystem-Treiber dafür. Wenn man jetzt aber vor schlimmsten Fall ausgeht, dann ist bei jedem erneuten SuchStart (FindFirst) die Dateiliste in einer anderen Reihenfolge und somit würde dein "Ziel des Programms" nicht ereichbar. Immerhin hast du es ja für veränderliche Verzeichnisse geplant, wo sich quasi unvorhersehbar die Dateiliste ändern kann. Am Sichersten arbeitet dennach der Code aus Beitrag #22, obwohl er auch einen kleinen Nachteil hat. > geänderte/überschiebene und gelöschte+neu_erstellte Dateien werden nicht erkannt. Dein Code (#23) hat ein/zwei kleine Probleme, z.B. - wenn die Datei aus Form1.Caption gelöscht wurde - oder die Dateiliste mal nicht sortiert ist. In beiden Fällen wäre auch das Suchergebnis nicht sortiert und es könnte auch etwas übersprungen oder mehrfach aufgelistet werden. |
Re: Suchmaske nach FindFirst verändern?
Zitat:
Wann glaubst Du, dass es regnet: Wenn es der Wetterbericht meldet oder wenn Du auf der Straße nass wirst? ;-) |
Re: Suchmaske nach FindFirst verändern?
Zitat:
![]() ![]() Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Zitat:
Zitat:
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Zitat:
Zitat:
Zitat:
Im Endeffekt ist jedwede weitere Unterhaltung sinnbefreit. Himitsu und ich haben Dich auf Deinen Denkfehler hingewiesen. Was Du daraus machst ist Deine Sache. EOD. |
Re: Suchmaske nach FindFirst verändern?
Zitat:
Zitat:
Zitat:
|
Re: Suchmaske nach FindFirst verändern?
Conclusio: Der Denkfehler, den himitsu und Fridolin Walther offensichtlich begangen haben, rührt m.E. daher, dass sie zwei Begriffe miteinander verwechselt haben: UNSORTIERT und ZUFÄLLIG. Das sind Begriffe, die wir durch empirische Erkenntnis in der Alltagserfahrung immer wieder im Zusammenhang erlebt haben und die deshalb in unserem Denken fest aneinander gekettet sind: Wenn etwa der kleine Neffe seine Spielzeugkiste umschmeißt, dann liegen alle Bauklötze UNSORTIERT und in scheinbar ZUFÄLLIGEN Mustern auf dem Boden herum. Nun könnte man allerdings ins Detail gehen und die scheinbar zufällige Anordnung der Bauklötze auf kausale Gesetzmäßigkeiten zurückführen und würden dann schnell erkennen, dass die Anordnung der Bauklötze auf dem Fußboden doch nicht zufällig ist, sondern gut nachvollziehbaren statistischen und physikalischen Gesetzmäßigkeiten folgt, also nicht einem "Zufall" unterliegt, der eigentlich der Chaostheorie vorbehalten bleibt. Nur tun wir das in der Praxis des Alltags eben nicht, und betrachten den Begriff "Zufall" als praktische Handhabe, um damit die Abwesenheit von vordergründig erkennbaren Ordnungsmustern zu beschreiben.
Deshalb besteht die Behebung des besagten Denkfehlers in einem ersten Schritt darin, zu erkennen, dass die Eigenschaft UNSORTIERT zwar die Abwesenheit von bekannten Ordnungsmustern beschreibt (etwa Sortierung nach Datum, Größe, usw.), was aber nicht bedeutet, dass UNSORTIERT die Abwesenheit eines JEGLICHEN anderen Ordnungsprinzips impliziert. Der zweite Schritt ist die Erkenntnis, dass es eine zufällige Anordnung in einem deterministischen System eines durch logischen Code gesteuerten Computers NICHT gibt! Auch dort, wo uns eine solche Anordnung als zufällig erscheint, kann immer von determinierter Kausalität ausgegangen werden. Das bedeutet, dass Code (also Programm und Betriebssystem), der keine explizit "randomistischen" Komponenten enthält, IMMER zum gleichen Ergebnis führen muss. Aus diesem Grund können die mit FindFirst und FindNext gelieferten Suchergebnisse nicht einmal so und ein anderes Mal anders sortiert sein. Das würde aller Logik entbehren. Q.E.D. |
Re: Suchmaske nach FindFirst verändern?
Zitat:
Was deinen Code und sein "aktuelles" Funktionieren angeht. Du hast diesen nur Quellen getestet, welche "zufälliger" Weise geordnet sind (weil es irgendwer so implementiert hat, obwohl er es nicht müßte) und da es dort funktioniert, stellst du hier die Behauptung auf, daß es dann immer funktionieren muß, welches du damit aber nicht bewiesen ist. Wir haben nur gesagt, daß es in anderen Fällen nicht funktionieren KÖNNTE (nicht daß es auf jeden Fall nicht geht) und haben dich deshalb auf den Umstand hingewiesen, daß die Eingangsinformationen für deinen Code eben nicht dem "Format" entsprechen MÜSSEN, wie du es beschrieben hast. Also müßtest du uns beweisen, daß dein Code auch bei entsprechenden Eingangsinformationen funktioniert, oder du ignorierst es, schreibst einen Hinweis an deinen Code und hoffst, daß die Eingangsinformationen "zufällig" dem Format entsprechen, welches dein Code benötigt um auf jeden Fall richtig zu funktioniert. Zitat:
- es wird eine interne Liste angelegt > bewiesen - diese muß nicht geordnet sein > es gibt keine Gegenbeweise, daß es IMMER geordnet/sortiert ist Dieses Verhalten der aktuellen Treiber stammt daher, daß NTFS und Andere sortieren, bei FAT stammt es von dem verwenden Speicherformat und bei CDFS liegt es an den sortierenden Schreibprogrammen und dem Speicherformat. Was aber "exotische" und zukünftige Dateisystemtreiber betrifft, kann man da keine Aussage treffen, also MUß man vom Schlimmsten ausgehen. Welches auch der Grund ist, warum ich in meinen Programmen, wo es wichtig ist, bei den Dateilisten selber nochmal eine Sortierung über die zwar aktuell sortierten Listen laufen laß. |
Re: Suchmaske nach FindFirst verändern?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz