![]() |
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05: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