![]() |
Re: Klasse für FindFirstFile/FindNextFile
Pöhser Frank, pöhser :lol:
|
Re: Klasse für FindFirstFile/FindNextFile
@Luckie,
mal so nebenbei und aus aktuellem Anlass ein Kompliment für deinen sauberen Programmierstil, da kann man sagen: das lässt sich sehr flüssig lesen und man sieht sofort die Fehler die hätten drinnen sein können wenn es anders formatiert wäre ;) Zum Glück keine Fehler, weil sauber geschrieben. Gruß Hagen |
Re: Klasse für FindFirstFile/FindNextFile
Zitat:
|
Re: Klasse für FindFirstFile/FindNextFile
Kann man da irgendwie noch ein Ereignis einbauen, wenn wieder in das übergeordnete Verzeichnis gewechselt wird? Als Parameter wären beide Verzeichnisse, also aus dem zurückgesprungen wird und in welches zurückgesprungen wird, wünschenswert.
|
Re: Klasse für FindFirstFile/FindNextFile
Was soll die Frage? Wie wäre es mit realisieren...
Delphi-Quellcode:
unit FindFilesCls;
interface uses Windows; type TOnFindFile = procedure(Filename: string; const Info: TWin32FindData; var Cancel: Boolean) of object; TOnDirectoryFind = procedure(Directory: string; const Info: TWin32FindData; var Cancel: Boolean) of object; TOnDirectoryUp = procedure(FromDirectory, ToDirectory: string; var Cancel: Boolean) of object; TFindFiles = class private FSubfolders: Boolean; FMask: string; FOnFindFile: TOnFindFile; FOnFindDirectory: TOnDirectoryFind; FOnDirectoryUp: TOnDirectoryUp; FCancel: Boolean; procedure Search(RootFolder: string); public constructor Create; property SubFolders: Boolean read FSubFolders write FSubFolders; property Mask: string read FMask write FMask; property OnFileFind: TOnFindFile read FOnFindFile write FOnFindFile; property OnDirectoryFind: TOnDirectoryFind read FOnFindDirectory write FOnFindDirectory; property OnDirectoryUp: TOnDirectoryUp read FOnDirectoryUp write FOnDirectoryUp; procedure Find(RootFolder: string); end; implementation { TFindFiles } constructor TFindFiles.Create; begin inherited; FSubfolders := False; FMask := '*.*'; FOnFindFile:=nil; FOnFindDirectory:=nil; FOnDirectoryUp:=nil; end; procedure TFindFiles.Search(RootFolder: string); var wfd: TWin32FindData; hFile: THandle; 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 try repeat if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then if (string(wfd.cFileName) <> '.') and (string(wfd.cFileName) <> '..') then begin if Assigned(OnDirectoryFind) then OnDirectoryFind(RootFolder + wfd.cFileName, wfd, FCancel); Find(RootFolder + wfd.cFileName + '\'); if Assigned(OnDirectoryUp) then OnDirectoryUp(RootFolder + wfd.cFileName, RootFolder, FCancel); end; until FCancel or not FindNextFile(hFile, wfd); finally windows.FindClose(hFile); end; end; if not FCancel and Assigned(OnFileFind) then begin hFile := FindFirstFile(PChar(RootFolder + FMask), wfd); if hFile <> INVALID_HANDLE_VALUE then try repeat if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then OnFileFind(RootFolder + wfd.cFileName, wfd, FCancel); until FCancel or not FindNextFile(hFile, wfd); finally Windows.FindClose(hFile); end; end; end; procedure TFindFiles.Find(RootFolder: string); begin FCancel := False; Search(RootFolder); end; end. |
Re: Klasse für FindFirstFile/FindNextFile
Nur noch eine kleine Änderung,
Code:
damit OnDirectoryUp nicht aufgerufen wird, wenn in damit OnDirectoryFind abgerochen wurde.
if [b]not FCancel and[/b] Assigned(FOnDirectoryUp) then
[edit] Code hier entfernt und dafür in Beitrag #5 geändert |
Re: Klasse für FindFirstFile/FindNextFile
Hi,
wäre es nicht auch nützlich, in das FOnDirectoryFind noch einen Parameter IgnoreDirectory einzuführen?
Delphi-Quellcode:
TOnDirectoryFind = procedure(Directory: string;
const Info: TWin32FindData; var Cancel: Boolean; var IgnoreDirectory: Boolean) of object; |
Re: Klasse für FindFirstFile/FindNextFile
Zitat:
Hatte zwar überlegt, ob man die beiden sich beeinflussenden Cancel und IgnoreDirectory kombinieren könnte und es dann nur einen Parameter gäbe, aber nur für diese eine Prozedur einen neuen Enum einzuführen spart nicht wirklich was ein. |
Re: Klasse für FindFirstFile/FindNextFile
Dann sollte in die Doku mit rein, ob der neue Parameter nur dazu führt, das aktuelle Verzeichnis zu überspringen oder auch ggf. alle Unterverzeichnisse gleich mit.
|
Re: Klasse für FindFirstFile/FindNextFile
@omata: Ja, hätte ich auch machen können, nur ich hatte gestern Abend etwas Matsch in der Birne und habe die Stelle einfach nicht mehr gesehen. ;)
Hier jetzt der aktuelle Code:
Delphi-Quellcode:
Ich habe mal himitsu und omata* als Co-Autoren eingetragen. Falls ich jemanden vergessen habe, bitte melden.
// 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; const Info: TWin32FindData; var Cancel: Boolean) of object; TOnFindDirectory = procedure(Directory: string; 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; 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 OnFindFile: TOnFindFile read FOnFindFile write FOnFindFile; property OnFindDirectory: TOnFindDirectory read FOnFindDirectory write FOnFindDirectory; property OnDirectoryUp: TOnDirectoryUp read FOnDirectoryUp write FOnDirectoryUp; end; implementation { TFindFiles } constructor TFindFiles.Create; begin inherited; FSubfolders := False; FMask := '*.*'; 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 try repeat if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then if (string(wfd.cFileName) <> '.') and (string(wfd.cFileName) <> '..') then begin Ignore := False; if Assigned(FOnFindDirectory) then FOnFindDirectory(RootFolder + wfd.cFileName, wfd, FCancel, Ignore); if not FCancel and not Ignore then Find(RootFolder + wfd.cFileName + '\'); if not FCancel and Assigned(FOnDirectoryUp) then FOnDirectoryUp(RootFolder + wfd.cFileName, RootFolder, FCancel); end; until FCancel or not FindNextFile(hFile, wfd); finally windows.FindClose(hFile); end; end; if not FCancel and Assigned(OnFindFile) then begin hFile := FindFirstFile(PChar(RootFolder + FMask), wfd); if hFile <> INVALID_HANDLE_VALUE then try repeat if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then OnFindFile(RootFolder + wfd.cFileName, wfd, FCancel); until FCancel or not FindNextFile(hFile, wfd); finally Windows.FindClose(hFile); end; end; end; procedure TFindFiles.Find(RootFolder: string); begin FCancel := False; Search(RootFolder); end; end. @himitsu: Du hattest zwei kleine Fehler drin. Und ich habe die Ereignisse umbenannte, so klingt es besser, finde ich. @Daniel: Ja der Parameter IgnoreDirectory müsste Dokumentiert werden, es sei denn uns fällt noch ein besserer Name ein, was mir eigentlich lieber wäre. *) Falls ihr mit richtigen Namen genannt werden wollt, sagt Bescheid. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:46 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