unit uFileSearch;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
type
{ TFileSearch }
TOnSearching = procedure(Sender: TObject; APath: String; AFileCount: Integer) of object;
TOnSearchComplete = procedure(Sender: TObject; AFileList: TStringList) of object;
TFileSearch = class(TThread)
private
FPath: String;
FFileList: TStringList;
FDone: Boolean;
FNeedToBreak: Boolean;
FOnSearching: TOnSearching;
FOnSearchComplete: TOnSearchComplete;
procedure FindFiles(const APath: String);
procedure UpdateSearching(const APath: String);
procedure UpdateSearchComplete;
protected
procedure Execute; override;
public
constructor Create(APath: String);
destructor Destroy; override;
public
property NeedToBreak: Boolean read FNeedToBreak write FNeedToBreak;
property OnSearching: TOnSearching read FOnSearching write FOnSearching;
property OnSearchComplete: TOnSearchComplete read FOnSearchComplete write FOnSearchComplete;
end;
implementation
{ TFileSearch }
procedure TFileSearch.FindFiles(const APath: String);
procedure Search(const APath: String);
var
SearchRec: TSearchRec;
Path: String;
begin
Path := IncludeTrailingBackslash(APath);
if FindFirst(Path + '*.*', faAnyFile - faDirectory, SearchRec) = 0 then
begin
repeat
if FNeedToBreak then
Break;
FFileList.Add(Path + SearchRec.Name);
UpdateSearching(Path + SearchRec.Name);
until FindNext(SearchRec) <> 0;
FindClose(SearchRec);
end;
if FindFirst(Path + '*.*', faAnyFile, SearchRec) = 0 then
begin
repeat
if FNeedToBreak then
Break;
if ((SearchRec.Attr and faDirectory) <> 0) and (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
Search(Path + SearchRec.Name)
until FindNext(SearchRec) <> 0;
FindClose(SearchRec);
end;
end;
begin
Search(APath);
FDone := True;
end;
procedure TFileSearch.UpdateSearching(const APath: String);
begin
if Assigned(FOnSearching) then
FOnSearching(Self, APath, FFileList.Count);
end;
procedure TFileSearch.UpdateSearchComplete;
begin
if Assigned(FOnSearchComplete) then
FOnSearchComplete(Self, FFileList);
end;
procedure TFileSearch.Execute;
begin
FindFiles(FPath);
while not (FDone or Terminated) do
Sleep(0);
Synchronize(@UpdateSearchComplete);
end;
constructor TFileSearch.Create(APath: String);
begin
inherited Create(True);
FPath := IncludeTrailingBackslash(APath);
FFileList := TStringList.Create;
FFileList.Sorted := True;
FDone := False;
FNeedToBreak := False;
end;
destructor TFileSearch.Destroy;
begin
FFileList.Free;
inherited Destroy;
end;
end.