Reputation: 555
If i execute it like that my application wouldn't respond until find all files and them to the listbox my question is How i can make this function multi threded to avoid unresponding situation! i am still Delphi novoice
procedure TfrMain.FileSearch(const PathName, FileName : string; txtToSearch : string; const InDir : boolean);
var Rec : TSearchRec;
Path : string;
txt : string;
fh : TextFile;
i : integer;
begin
Path := IncludeTrailingBackslash(PathName);
if FindFirst(Path + FileName, faAnyFile - faDirectory, Rec) = 0 then
try
repeat
AssignFile(fh, Path + Rec.Name);
Reset(fh);
Readln(fh,txt);
if ContainsStr(txt, txtToSearch) then
ListBox1.Items.Add(Path + Rec.Name);
until FindNext(Rec) <> 0;
finally
FindClose(Rec);
end;
If not InDir then Exit;
if FindFirst(Path + '*.*', faDirectory, Rec) = 0 then
try
repeat
if ((Rec.Attr and faDirectory) <> 0) and (Rec.Name<>'.') and (Rec.Name<>'..') then
FileSearch(Path + Rec.Name, FileName, txtToSearch, True);
until FindNext(Rec) <> 0;
finally
FindClose(Rec);
end;
end;
Upvotes: 6
Views: 1175
Reputation: 16620
You can put the file scanning stuff into a thread and whenver work is finished send a windows message to the main form, which then updates the list box (code not tested, take it as pseudo code):
const
WM_FILESEARCH_FINISHED = WM_USER + 1;
TFileSearchThread = class (TThread)
private
FPath : String;
FFileNames : TStringList;
protected
procedure Execute; override;
public
constructor Create (const Path : String);
destructor Destroy; override;
property FileNames : TStrings read FFileNames;
end;
constructor TFileSearchThread.Create (const Path : String);
begin
inherited Create (True);
FPath := Path;
FFileNames := TStringList.Create;
end;
destructor TFileSearchThread.Destroy;
begin
FreeAndNil (FFileNames);
inherited;
end;
procedure TFileSearchThread.Execute;
begin
// do your file search here, adding each file to FFileNames
PostMessage (MainForm.Handle, WM_FILESEARCH_FINISHED, 0, 0);
end;
You could use it like this:
Thead := TFileSearchThread.Create (Path);
Thread.Start;
and the main form would have a message handler like this:
type
TMainForm = class(TForm)
ListBox1: TListBox;
private
procedure WMFileSearchFinished (var Msg : TMessage); message WM_FILESEARCH_FINISHED;
public
{ Public declarations }
end;
implementation
procedure TMainForm.WMFileSearchFinished (var Msg : TMessage);
begin
ListBox1.Items.AddStrings (Thread.FileNames);
end;
Upvotes: 6
Reputation: 26850
Here you can find an article about the background file scanner implemented with OmniThreadLibrary.
Upvotes: 5