home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 April A / Pcwk4a98.iso / PROGRAM / DELPHI16 / Filefind / FILEFIND.PAS < prev    next >
Pascal/Delphi Source File  |  1995-12-12  |  8KB  |  237 lines

  1. { ************************************************************************* }
  2. { ***        FileFind Component                                         *** }
  3. { ***        by Gabriel Cherem, Dec 1995                                *** }
  4. { ***        E-mail egr7jmc@npd.ufsc.br                                 *** }
  5. { ***                                                                   *** }
  6. { ***  NOTICE: I DO NOT assume responsibility for any harm or rack      *** }
  7. { ***  due the use of this software program, although I belive it is    *** }
  8. { ***  quite harmless as you can see on its sourcecode.                 *** }
  9. { ***  You can remove bugs yourself since the sourcecode is available.  *** }
  10. { ***  If you find a bug, please let me know.                           *** }
  11. { ***                                                                   *** }
  12. { ***  Feel free to use this software. I don't want any payment.        *** }
  13. { ***  But if you think this software will be usefull for you, just     *** }
  14. { ***  send me a postal card from your town. I am wonder to know how    *** }
  15. { ***  far this package has got!                                        *** }
  16. { ***                                                                   *** }
  17. { ***  Postal cards can be addressed to                                 *** }
  18. { ***                                                                   *** }
  19. { ***     Gabriel Cherem                                                *** }
  20. { ***     Rua Manfredo Leite 136                                        *** }
  21. { ***     Stodieck                                                      *** }
  22. { ***     88025-110 Florianpolis, SC                                    *** }
  23. { ***     Brazil                                                        *** }
  24. { ***                                                                   *** }
  25. { ***  Cheers from Brazil!                                              *** }
  26. { **************************************************************************}
  27.  
  28. {$B-} {Complete Boolean Evaluation}
  29. {$G+} {286 Instructions}
  30. {$I-} {Use IOResult instead for Input/Output-Checking}
  31. {$N+} {Numeric Coprocessor}
  32. {$P+} {Open Parameters}
  33. {$T-} {Typed @ Operator}
  34. {$W-} {Windows Stack Frame}
  35. {$X+} {Extended Syntax}
  36.  
  37. {$C MOVEABLE,DEMANDLOAD,DISCARDABLE}
  38.  
  39. unit FileFind;
  40.  
  41. interface
  42.  
  43. uses
  44.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  45.   Forms, Dialogs;
  46.  
  47. type
  48.   TSearchScope = (ssEntireDisk, ssCurrentDir, ssCurrentDirAndBelow);
  49.  
  50. const
  51.   {default property values}
  52.   DefStopOnFirstMatch = true;
  53.   DefSearchScope      = ssEntireDisk;
  54.  
  55. type
  56.   { event to notify Drive changing }
  57.   TChangeDriveEvent =
  58.     procedure (Sender: TObject; NewDrive:Char)
  59.     of object;
  60.   { event to notify Directory changing }
  61.   TChangeDirectoryEvent =
  62.     procedure (Sender: TObject; NewDirectory:TFileName)
  63.     of object;
  64.   { event to notify stoping }
  65.   TStopEvent =
  66.     procedure (Sender: TOBject; var CanStop: Boolean)
  67.     of object;
  68.  
  69. type
  70.   TFileFind = class(TComponent)
  71.   private
  72.     { Private declarations }
  73.     FDriveList: String;
  74.     FSearchScope: TSearchScope;
  75.     FFileName: TFileName;
  76.     FLastMatch: TFileName;
  77.     FStopOnFirstMatch: Boolean;
  78.     Stopped: Boolean;
  79.  
  80.     { event handler variables }
  81.     FOnMatch: TNotifyEvent;
  82.     FOnChangeDrive: TChangeDriveEvent;
  83.     FOnChangeDirectory: TChangeDirectoryEvent;
  84.     FOnStop: TStopEvent;
  85.  
  86.   protected
  87.     { Protected declarations }
  88.     procedure SearchDirectory(FileMask:String; Path: TFileName);
  89.  
  90.   public
  91.     { Public declarations }
  92.     constructor Create(AOwner:Tcomponent);override;
  93.  
  94.     { methods}
  95.     procedure Start;
  96.     procedure Stop;
  97.  
  98.   published
  99.     { Published declarations }
  100.     property DriveList: String
  101.       read FDriveList
  102.       write FDriveList;
  103.     property SearchScope: TSearchScope
  104.       read FSearchScope
  105.       write FSearchScope
  106.       default DefSearchScope;
  107.     property FileName: TFileName
  108.       read FFileName
  109.       write FFileName;
  110.     property StopOnFirstMatch: Boolean
  111.       read FStopOnFirstMatch
  112.       write FStopOnFirstMatch
  113.       default DefStopOnFirstMatch;
  114.     property LastMatch: TFileName
  115.       read FLastMatch;
  116.  
  117.     { event handler declarations }
  118.     property OnMatch: TNotifyEvent
  119.       read FOnMatch
  120.       write FOnMatch;
  121.     property OnChangeDrive: TChangeDriveEvent
  122.       read FOnChangeDrive
  123.       write FOnChangeDrive;
  124.     property OnChangeDirectory: TChangeDirectoryEvent
  125.       read FOnChangeDirectory
  126.       write FOnChangeDirectory;
  127.     property OnStop: TStopEvent
  128.       read FOnStop
  129.       write FOnStop;
  130.   end;
  131.  
  132. procedure Register;
  133.  
  134. implementation
  135.  
  136. procedure Register;
  137. begin
  138.   RegisterComponents('Samples', [TFileFind]);
  139. end;
  140.  
  141. constructor TFileFind.Create(AOwner:Tcomponent);
  142. begin
  143.   inherited Create(AOwner);
  144.   FStopOnFirstMatch := DefStopOnFirstMatch;
  145.   FSearchScope := DefSearchScope;
  146. end;
  147.  
  148. procedure TFileFind.Start;
  149. function IsValidDrive(Drive: Char): Boolean;
  150. var
  151.   Str: String;
  152. begin
  153.   ChDir(Drive+':');
  154.   Result := IOResult = 0;
  155. end;
  156. var
  157.   I: Byte;
  158.   FileMask,InitialPath: TFileName;
  159. begin
  160.   FLastMatch := '';
  161.   Stopped := false;
  162.   FileMask := ExtractFilename(FileName);
  163.   InitialPath := ExtractFilePath(FileName);
  164.   if InitialPath <> '' then
  165.     SearchDirectory(FileMask,InitialPath)
  166.   else begin
  167.     if DriveList = '' then
  168.       DriveList := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  169.     for I := 1 to Length(DriveList) do
  170.       if IsValidDrive(DriveList[i]) then begin
  171.         if Assigned(FOnChangeDrive) then
  172.           FOnChangeDrive(Self,UpCase(DriveList[i]));
  173.         if SearchScope = ssEntireDisk then
  174.           SearchDirectory(FileMask,DriveList[i]+':\')
  175.         else
  176.           SearchDirectory(FileMask,DriveList[i]+':');
  177.         if Stopped then
  178.           Break;
  179.       end;
  180.   end;
  181. end;
  182.  
  183. procedure TFileFind.Stop;
  184. begin
  185.   Stopped := true;
  186.   if Assigned(FOnStop) then
  187.      FOnStop(Self,Stopped);
  188. end;
  189.  
  190. { the following method is the heart of the component }
  191. procedure TFileFind.SearchDirectory(FileMask:String; Path: TFileName);
  192. function MakePath(Path,FileName:TFileName):TFileName;
  193. begin
  194.   Result := Path;
  195.   if Result[Length(Result)] <> '\' then
  196.     Result := Result + '\';
  197.   Result := Result + FileName;
  198. end;
  199.  
  200. var
  201.   SearchRec: TSearchRec;
  202. begin
  203.   if Assigned(FOnChangeDirectory) then
  204.     FOnChangeDirectory(Self,Path);
  205.   { one pass for files... }
  206.   if FindFirst(MakePath(Path,FileMask), faAnyFile, SearchRec) = 0 then
  207.     repeat
  208.       with SearchRec do
  209.         if Attr <> faDirectory then begin
  210.           FLastMatch := MakePath(Path,Name);
  211.           if Assigned(FOnMatch) then
  212.             FOnMatch(Self);
  213.           if StopOnFirstMatch then
  214.             Stopped := true
  215.           else
  216.             Application.ProcessMessages;
  217.        end
  218.       until (FindNext(SearchRec) <> 0) or Stopped;
  219.   FindClose(SearchRec);
  220.   { ... and another for subdirectories }
  221.   if (SearchScope <> ssCurrentDir) or Stopped then begin
  222.     if FindFirst(MakePath(Path,'*.*'), faDirectory, SearchRec) = 0 then
  223.       repeat
  224.         with SearchRec do
  225.           if (Name <> '.') and (Name <> '..') and (Attr = faDirectory) then
  226.             SearchDirectory(FileMask,MakePath(Path,Name));
  227.         Application.ProcessMessages; { we have to be gentle to the others apps }
  228.       until (FindNext(SearchRec) <> 0) or Stopped;
  229.     FindClose(SearchRec);
  230.   end;
  231.   { these two loops above could become just one, but i'd  }
  232.   { have to write a parser to resolve wildcards...        }
  233.   { I will be gratefull if someone send me one! :)        }
  234. end;
  235.  
  236. end.
  237.