Recent

Author Topic: TListFileSearcher.OnFileFound doesn't work. [Solved by myself]  (Read 2573 times)

totya

  • Hero Member
  • *****
  • Posts: 720
Hi!

In this code, listbox1 is empty after button is pressed. What's wrong with this code?

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     ListBox1: TListBox;
  17.     ListBox2: TListBox;
  18.     procedure Button1Click(Sender: TObject);
  19.   private
  20.     Searcher: TListFileSearcher;
  21.   public
  22.     procedure FindAllFilesInDirectory (AList: TStrings; const SearchPath: String; SearchMask: String; SearchSubDirs: Boolean);
  23.     procedure FileFoundEvent(FileIterator: TFileIterator);
  24.   end;
  25.  
  26. var
  27.   Form1: TForm1;
  28.  
  29. implementation
  30.  
  31. {$R *.lfm}
  32.  
  33. { TForm1 }
  34.  
  35. procedure TForm1.Button1Click(Sender: TObject);
  36. var SL:TStringList;
  37. begin
  38.   SL:= TStringList.Create;
  39.   try
  40.   FindAllFilesInDirectory(SL, 'c:\', '*.*', false);
  41.  
  42.   ListBox2.Items.Assign(SL);
  43.  
  44.   finally
  45.     SL.Free;
  46.   end;
  47. end;
  48.  
  49. procedure TForm1.FindAllFilesInDirectory
  50.            (AList: TStrings; const SearchPath: String; SearchMask: String; SearchSubDirs: Boolean);
  51.  
  52. begin
  53.   Searcher:= nil;
  54.   Searcher:= TListFileSearcher.Create(AList);
  55.  
  56.  if Assigned(Searcher) then
  57.    try
  58.      Searcher.OnFileFound:= @FileFoundEvent;
  59.      Searcher.Search(SearchPath, SearchMask, SearchSubDirs);
  60.    finally
  61.      FreeAndNil(Searcher);
  62.    end;
  63. end;
  64.  
  65. procedure TForm1.FileFoundEvent(FileIterator: TFileIterator);
  66. begin
  67.   Application.ProcessMessages;
  68.  
  69.   ListBox1.Items.Add(FileIterator.FileName);
  70. end;
  71.  
  72. end.
  73.  
« Last Edit: May 24, 2018, 05:48:42 pm by totya »

jamie

  • Hero Member
  • *****
  • Posts: 6077
Re: TListFileSearcher.OnFileFound doesn't work.
« Reply #1 on: May 24, 2018, 01:58:22 am »
I've never seen "TListFileSearcher" code, but what ever, looks like old hat to me.. :)

Have you tried using "VAR" in the declaration ?

FileAllFilesInDirectory(Var Alist :Tstrings;...…….

                             ^^^^^^

Not sure if that will fix your issue but it's worth a try..
The only true wisdom is knowing you know nothing

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: TListFileSearcher.OnFileFound doesn't work.
« Reply #2 on: May 24, 2018, 02:45:02 am »
In this code, listbox1 is empty after button is pressed. What's wrong with this code?
well lets take it step by step.
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. procedure TForm1.FindAllFilesInDirectory
  3.            (AList: TStrings; const SearchPath: String; SearchMask: String; SearchSubDirs: Boolean);
  4.  
  5. begin
  6.   Searcher:= nil;
  7.   Searcher:= TListFileSearcher.Create(AList);
  8.  
  9.  if Assigned(Searcher) then
  10.    try
  11.      Searcher.OnFileFound:= @FileFoundEvent;
  12.      Searcher.Search(SearchPath, SearchMask, SearchSubDirs);
  13.    finally
  14.      FreeAndNil(Searcher);
  15.    end;
  16. end;
this code creates a TlistFileSearcher and assigns it the FileFoundEvent as its event handler.
Now the handler does a most inappropriate process messages here and after that adds the filename that was just found to the the listbox1.items.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FileFoundEvent(FileIterator: TFileIterator);
  2. begin
  3.   Application.ProcessMessages;
  4.  
  5.   ListBox1.Items.Add(FileIterator.FileName);
  6. end;
  7.  
  8. end.
  9.  
so far so good that should be enough. Now lets see how do you call it.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var SL:TStringList;
  3. begin
  4.   SL:= TStringList.Create;
  5.   try
  6.   FindAllFilesInDirectory(SL, 'c:\', '*.*', false);
  7.  
  8.   ListBox2.Items.Assign(SL);
  9.  
  10.   finally
  11.     SL.Free;
  12.   end;
  13. end;
ok now you have a problem at this point you know that the filefoundEvent event handler has no knowledge about the SL string list and it does not add items to it but you assume it does and try to feed them to listbox2 ofcourse the sl is unknown to the event handler and it will never get filled with the data you want.

happy hunting.
« Last Edit: May 24, 2018, 07:24:11 am by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

totya

  • Hero Member
  • *****
  • Posts: 720
Re: TListFileSearcher.OnFileFound doesn't work.
« Reply #3 on: May 24, 2018, 06:21:50 am »
I've never seen "TListFileSearcher" code, but what ever, looks like old hat to me.. :)

Have you tried using "VAR" in the declaration ?

FileAllFilesInDirectory(Var Alist :Tstrings;...…….

                             ^^^^^^

Not sure if that will fix your issue but it's worth a try..

Hi!

FindAllFiles function use the TListFileSearcher... but I nood more flexibility, so I must use the TListFileSearcher. Function header come from the Lazarus source 1:1.

totya

  • Hero Member
  • *****
  • Posts: 720
Re: TListFileSearcher.OnFileFound doesn't work.
« Reply #4 on: May 24, 2018, 06:38:41 am »
ok now you have a problem at this point you know that the filefoundEvent event handler has no knowledge about the SL string list and it does not add items to it but you assume it does and try to feed them to listbox2 ofcourse the sl is unknown to the event handler and it will never get filled with the data you want.

Thanks for the answer, but I'm sorry, I don't know what is the problem.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: TListFileSearcher.OnFileFound doesn't work.
« Reply #5 on: May 24, 2018, 07:25:23 am »
ok now you have a problem at this point you know that the filefoundEvent event handler has no knowledge about the SL string list and it does not add items to it but you assume it does and try to feed them to listbox2 ofcourse the sl is unknown to the event handler and it will never get filled with the data you want.

Thanks for the answer, but I'm sorry, I don't know what is the problem.
one more time
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FileFoundEvent(FileIterator: TFileIterator);
  2. begin
  3.   Application.ProcessMessages;
  4.  
  5.   ListBox1.Items.Add(FileIterator.FileName);
  6. end;
where in the above code is the SL updated. only that procedure saves the files found.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

totya

  • Hero Member
  • *****
  • Posts: 720
Re: TListFileSearcher.OnFileFound doesn't work.
« Reply #6 on: May 24, 2018, 05:48:05 pm »
one more time where in the above code is the SL updated. only that procedure saves the files found.

Hi!

Sorry but I don't understand you again. My code is perfect, only doesn't work. But anyway, I found what is the problem (really). The problem is the bad implementation in the TListFileSearcher Lazarus code. See:

Code: Pascal  [Select][+][-]
  1. procedure TFileSearcher.DoFileFound;
  2. begin
  3.   if Assigned(FOnFileFound) then OnFileFound(Self);
  4. end;

Okay, now let me see the TListFileSearcher:

Code: Pascal  [Select][+][-]
  1. { TListFileSearcher }
  2.  
  3.   TListFileSearcher = class(TFileSearcher)
  4.   private
  5.     FList: TStrings;
  6.   protected
  7.     procedure DoFileFound; override;
  8.   public
  9.     constructor Create(AList: TStrings);
  10.   end;
  11.  

DoFile found overrided, but how:

Code: Pascal  [Select][+][-]
  1. procedure TListFileSearcher.DoFileFound;
  2. begin
  3.   FList.Add(FileName);
  4. end;

Well, Inherited is missing! So the event is lost. If I put inherited the code,  my code works correctly. Thank you, and wake up taazz :)

 

TinyPortal © 2005-2018