2012-03-30 22 views
6

Uygulamam tüm dosyaları ve onları liste kutusu listelemeye kadar benim uygulama yanıt vermeyecek gibi idam edersem sorumuz, bu durumun yanıt vermemesi için çok işlevli hale getirilebilir. ben hala OmniThreadLibrary ile uygulanan arka plan dosya tarayıcı hakkında bir makale bulabilirsinizdelphi dosya arama multithreading

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; 

cevap

5

Bir iplik haline dosya tarama şeyler koymak ve çalışma ardından liste kutusu günceller ana formuna bir windows ileti göndermek bittikten whenver (kod test edilmedi, sözde kodu olarak götürün) olabilir:

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; 

Thead := TFileSearchThread.Create (Path); 
Thread.Start; 

ve ana form böyle bir ileti işleyicisi olurdu:

böyle kullanabiliriz

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; 
+1

+1, Basit, temiz bir çözüm. Bu fazlaca ters gidebilir. –

+0

'PostMessage (MainForm.Handle, WM_FILESEARCH_FINISHED, 0, 0); '' Synchronize' ile kullanılabilir mi? – kobik

+1

@kobik, endişelenmenize gerek yok, 'Sap' özelliği salt okunur ve okuması atomiktir. Ve 0'dan farklı olmalı (kontrol ölmüş olacak ve herhangi bir mesaj alamayacaktı), böylece alıcı hiçbir zaman "CreateHandle" işlemini tutacağı zaman 0 yapmaz. Risk, nesne örneğinin kendisidir. MainForm'u yok edin ve ona erişmeye çalışın, AV'yi genelde alırsınız. Ve, Emba ['uses'] (http://edn.embarcadero.com/article/22411) bu da :-) – TLama