![]() |
Re: Klasse für FindFirstFile/FindNextFile
Zitat:
Aber wie zählst du jetzt mit deinem Sender? Hänge doch mal den Code eines kleines Demos an. |
Re: Klasse für FindFirstFile/FindNextFile
Zählen tu ich es wie bei deinem Code.
> via Inc(FCountFiles) im Code Ja und auf den Wert kann man leicht über dir öffentlichen Property zugreifen:
Delphi-Quellcode:
procedure TMyClass.FindFile(Sender: TFindFiles; Filename: string; const Info: TWin32FindData; var Cancel: Boolean);
begin Labe11.Caption := IntToStr(Sender.CountFiles); Labe12.Caption := Filename; Application.ProcessMessages; end; F := TFindFile.Create; F.OnFindFile := FindFile; F.Find; |
Re: Klasse für FindFirstFile/FindNextFile
Ich denke gerade auch über die Events nach, wie wäre es denn hiermit:
Delphi-Quellcode:
ParentFolder + Filename (bzw. + Folder) läßt sich im Event einfacher zusammensetzen als trennen und die Angabe der Tiefe vereinfacht ggf. die Anzeige.
TFindFileEvent = procedure(Sender: TFindFiles; ParentFolder, Filename: string; FolderDeep: Byte; const Info: TWin32FindData; var Cancel: Boolean);
Grüsse, Dirk |
Re: Klasse für FindFirstFile/FindNextFile
Zitat:
|
Re: Klasse für FindFirstFile/FindNextFile
Zitat:
Grüsse, Dirk |
Re: Klasse für FindFirstFile/FindNextFile
Zitat:
|
Re: Klasse für FindFirstFile/FindNextFile
Hi,
CountDirectories ist immer 0, da direkt nach dem Inkrementieren wieder Find() aufgerufen wird und der Wert dort wieder auf null gesetzt wird:
Delphi-Quellcode:
Leider fällt mir auser einer zusätzlichen privaten Find() Prozedur nichts ein um das Problem zu beheben
Inc(FCountDirectories);
Error := Find(RootFolder + wfd.cFileName + '\'); @ EDIT oder Find() durch Search() ersetzen
Delphi-Quellcode:
Inc(FCountDirectories);
Error := Search(RootFolder + wfd.cFileName + '\'); |
Re: Klasse für FindFirstFile/FindNextFile
Korrigiert.
|
Re: Klasse für FindFirstFile/FindNextFile
Zitat:
wurde in Beitrag #5 schonmal geändert :) Das private Search hatte ich ja gerade aus dem Grund eingeführt, damit man unabhängig "extern" etwas beim Start setzen kann ... nur ist irgendwie dieser rekursive Aufruf wohl vergessen oder nochmals falsch überschrieben wurden. :shock: |
Re: Klasse für FindFirstFile/FindNextFile
Neue Version.
+ Datei- und Verzeichniszähler werden als Parameter der Ereignisse übergeben. + Fehlerbehandlung mittels eigener Exceptions. + Zähler für die Verzeichnistiefe. Wird auch als Parameter an das OnFindDirectory übergeben.
Delphi-Quellcode:
Wir haben hier zur Zeit zwei Versionen, die von himitsu und meine. Ich habe nicht beide zusammengefasst, weil ich mit himitsus Code nicht ganz konform gehen kann. In der Code-Lib sollten wir deswegen beide Versionen ablegen, wenn wir hier fertig sind. Da die Beiträge ziemlich verflochten sind, ist es jetzt nicht mehr ganz einfach die Beiträge zu trennen.
// FindFiles - Klasse zum Durchsuchen von Ordnern
// Michael Puff [[url]http://www.michael-puff.de][/url], himitsu, omata unit MpuFindFilesCls; interface uses Windows; type TOnFindFile = procedure(Filename: string; CountFiles: Cardinal; const Info: TWin32FindData; var Cancel: Boolean) of object; TOnFindDirectory = procedure(Directory: string; CountDirectories: Cardinal; Level: Cardinal; const Info: TWin32FindData; var Cancel: Boolean; var IgnoreDirectory: Boolean) of object; TOnDirectoryUp = procedure(FromDirectory, ToDirectory: string; var Cancel: Boolean) of object; TFindFiles = class(TObject) private FSubfolders: Boolean; FMask: string; FCountFiles: Cardinal; FCountDirectories: Cardinal; FLevel: Cardinal; FCancel: Boolean; FOnFindFile: TOnFindFile; FOnFindDirectory: TOnFindDirectory; FOnDirectoryUp: TOnDirectoryUp; procedure Search(RootFolder: string); public constructor Create; procedure Find(RootFolder: string); property SubFolders: Boolean read FSubFolders write FSubFolders; property Mask: string read FMask write FMask; property CountFiles: Cardinal read FCountFiles; property CountDirectories: Cardinal read FCountDirectories; property OnFindFile: TOnFindFile read FOnFindFile write FOnFindFile; property OnFindDirectory: TOnFindDirectory read FOnFindDirectory write FOnFindDirectory; property OnDirectoryUp: TOnDirectoryUp read FOnDirectoryUp write FOnDirectoryUp; end; type Exception = class(TObject) private FMsg: string; class function SysErrorMessage(ErrorCode: Integer): string; public constructor Create(Msg: string); property Msg: string read FMsg; end; EFindFiles = class(Exception) public constructor Create(Msg: string); end; implementation { TFindFiles } constructor TFindFiles.Create; begin inherited; FSubfolders := False; FMask := '*.*'; FCountFiles := 0; FCountDirectories := 0; end; procedure TFindFiles.Search(RootFolder: string); var wfd: TWin32FindData; hFile: THandle; Ignore: Boolean; begin if (RootFolder <> '') and (RootFolder[Length(RootFolder)] <> '\') then RootFolder := RootFolder + '\'; if not FCancel and FSubFolders then begin hFile := FindFirstFile(PChar(RootFolder + '*.*'), wfd); if hFile <> INVALID_HANDLE_VALUE then begin try repeat if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then if (string(wfd.cFileName) <> '.') and (string(wfd.cFileName) <> '..') then begin Inc(FCountDirectories); Inc(FLevel); Ignore := False; if Assigned(FOnFindDirectory) then FOnFindDirectory(RootFolder + wfd.cFileName, FCountDirectories, FLevel, wfd, FCancel, Ignore); if not FCancel and not Ignore then Search(RootFolder + wfd.cFileName + '\'); if not FCancel and Assigned(FOnDirectoryUp) then begin FOnDirectoryUp(RootFolder + wfd.cFileName, RootFolder, FCancel); end; Dec(FLevel); end; until FCancel or not FindNextFile(hFile, wfd); finally windows.FindClose(hFile); end; end else begin raise EFindFiles.Create(Exception.SysErrorMessage(GetLastError)); end; end; if not FCancel and Assigned(OnFindFile) then begin hFile := FindFirstFile(PChar(RootFolder + FMask), wfd); if hFile <> INVALID_HANDLE_VALUE then begin try repeat Inc(FCountFiles); if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then OnFindFile(RootFolder + wfd.cFileName, FCountFiles, wfd, FCancel); until FCancel or not FindNextFile(hFile, wfd); finally Windows.FindClose(hFile); end; end else begin if GetLastError <> ERROR_FILE_NOT_FOUND then raise EFindFiles.Create(Exception.SysErrorMessage(GetLastError)); end; end; end; procedure TFindFiles.Find(RootFolder: string); begin FCancel := False; FCountFiles := 0; FCountDirectories := 0; FLevel := 0; Search(RootFolder); end; { Exception } constructor Exception.Create(Msg: string); begin FMsg := Msg; end; class function Exception.SysErrorMessage(ErrorCode: Integer): string; var Len: Integer; Buffer: array[0..255] of Char; begin Len := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ARGUMENT_ARRAY, nil, ErrorCode, 0, Buffer, SizeOf(Buffer), nil); while (Len > 0) and (Buffer[Len - 1] in [#0..#32, '.']) do Dec(Len); SetString(Result, Buffer, Len); end; { EFindFiles } constructor EFindFiles.Create(Msg: string); begin inherited Create(Msg); end; end. Ich betrachte meine Version zur Zeit als feature complete. |
Re: Klasse für FindFirstFile/FindNextFile
Ein bissl aufgeräumt und bei sowas wie die SysUtils kann man nun selbst entscheiden, ob sie eingebunden werden sollen oder nicht.
Mir ist grade aufgefallen, daß man unsere Klassen auch nehmen, um ganz leicht nur Dateien zu zählen ... einfach nur keine Callback-Prozeduren übergeben. Zitat:
Oder ich behaupte einfach es wäre ein Feature. :stupid: |
Re: Klasse für FindFirstFile/FindNextFile
Zitat:
|
Re: Klasse für FindFirstFile/FindNextFile
Hi,
Da himitsu die Sache mit dem Dateienzählen angedeutet hatt hätte ich noch ein Feature vorzuschlagen ein Property welches die Anzahl der Dateien im Aktuellen Verzeichnis zurückgibt
Delphi-Quellcode:
Nicht getestet sollte aber klappen
// Hier und möglicherweise bei Find() Initialiseren
end; FilesInFolder := 0; // neu Dec(FLevel); // Hier erhöhen repeat Inc(FCountFiles); Inc(FilesInFolder ); // neu |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:50 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