Delphi-PRAXiS
Seite 3 von 6     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Suchmaske nach FindFirst verändern? (https://www.delphipraxis.net/143694-suchmaske-nach-findfirst-veraendern.html)

PeterPanino 21. Nov 2009 18:32

Re: Suchmaske nach FindFirst verändern?
 
Zitat:

Zitat von Daniel G
Jetzt hab ich erst gerafft, was du willst... :wall:

War mein Beitrag um 18:04 nicht deutlich genug? :gruebel:

Zitat:

Zitat von Daniel G
Der Vorschlag von Himi, mit der Überwachung des Verzeichnis, dürfte dich zum Ziel führen...

Das wäre dann ja noch aufwändiger als 18:04/Methode 2

Klaus01 21. Nov 2009 20:00

Re: Suchmaske nach FindFirst verändern?
 
und noch ein Versuch.

Delphi-Quellcode:
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 Rückgabe, wenn keine weitere Datei gefunden wurde sollte noch geregelt werden.
Die StringList (bereitsBearbeiteteDateien) muss natürlich entsprechend gepflegt werden.

Grüße
Klaus

PeterPanino 28. Nov 2009 20:05

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:
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;
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.

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.

Fridolin Walther 29. Nov 2009 18:58

Re: Suchmaske nach FindFirst verändern?
 
Du bist Dir aber schon im Klaren, daß FindFile keine bestimmte Reihenfolge zurück gibt, oder?

PeterPanino 29. Nov 2009 19:17

Re: Suchmaske nach FindFirst verändern?
 
Zitat:

Zitat von Fridolin Walther
Du bist Dir aber schon im Klaren, daß FindFile keine bestimmte Reihenfolge zurück gibt, oder?

Erstens handelt es sich nicht um "FindFile", und zweitens gibt FindNext eine bestimmte gleichbleibende Reihenfolge wieder. Probier das Demoprogramm doch mal aus!

Fridolin Walther 29. Nov 2009 19:24

Re: Suchmaske nach FindFirst verändern?
 
Zitat:

Zitat von PeterPanino
Erstens handelt es sich nicht um "FindFile", und zweitens gibt FindNext eine bestimmte gleichbleibende Reihenfolge wieder. Probier das Demoprogramm doch mal aus!

Nur weil die Reihenfolge konstant zu sein scheint, heißt es nicht, daß sie es ist. Ich verweise auf den entsprechenden Absatz in der MSDN Doku zu FindFirstFile:

MSDN-Library durchsuchenFindFirstFile
Zitat:

The FindFirstFile function opens a search handle and returns information about the first file that the file system finds with a name that matches the specified pattern. This may or may not be the first file or directory that appears in a directory-listing application (such as the dir command) when given the same file name string pattern. This is because FindFirstFile does no sorting of the search results. For additional information, see FindNextFile.

himitsu 29. Nov 2009 19:24

Re: Suchmaske nach FindFirst verändern?
 
Zitat:

Zitat von PeterPanino
Erstens handelt es sich nicht um "FindFile",

Ist ja soweit egal, da diese ja zusammengehören.

Zitat:

Zitat von PeterPanino
und zweitens gibt FindNext eine bestimmte gleichbleibende Reihenfolge wieder.

Das ist zufall und keineswegs Standard.

MSDN-Library durchsuchenFindFirstFile/MSDN-Library durchsuchenFindNextFile sortieren nicht und die Delphi-Wraper auch nicht.
Es wird nur zufällig vom Dateisystemtreiber sortiert und daß dieser sortieren muß, ist nicht vorgeschrieben.

PeterPanino 29. Nov 2009 19:33

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!

PeterPanino 29. Nov 2009 19:37

Re: Suchmaske nach FindFirst verändern?
 
Zitat:

Zitat von himitsu
Das ist zufall und keineswegs Standard.

Habe ich etwa das Gegenteil behauptet? Noch was: Beim Programmieren gibt es keinen "Zufall" - nicht einmal bei Random. D.h. im Computer passiert überhaupt nichts, was mit Zufall zu tun hat. ;-)

Zitat:

Zitat von himitsu
MSDN-Library durchsuchenFindFirstFile/MSDN-Library durchsuchenFindNextFile sortieren nicht und die Delphi-Wraper auch nicht.

Habe ich das etwa behauptet?

Zitat:

Zitat von himitsu
Es wird nur zufällig vom Dateisystemtreiber sortiert und daß dieser sortieren muß, ist nicht vorgeschrieben.

Was hat das mit meinem Code zu tun?

Fridolin Walther 29. Nov 2009 19:55

Re: Suchmaske nach FindFirst verändern?
 
Zitat:

Zitat von PeterPanino
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!

Und genau da liegst Du falsch. Von einer offensichtlichen Race Condition, die eintritt, wenn neue Einträge hinzukommen während der Iteration, einmal abgesehen, funktioniert Dein Ansatz nur, wenn die Dateiliste die FindFirstFile erstellt bei jedem Aufruf exakt gleich ist - sowohl vom Inhalt her als auch von der Position jedes einzelnen Dateirecords. Das ist aber keineswegs garantiert. Um dies zu garantieren, müsste die Liste nach identischen Kriterien sortiert werden jedes Mal, was aber nicht getan wird.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:33 Uhr.
Seite 3 von 6     123 45     Letzte »    

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