In the previous article, we saw how to recursively search through subfolders and assemble a list of files that mach a certain file mask. Functions FindFirst, FindNext and FindClose were used to scan disks directory structure for a given file mask.
This time we'll create a new Delphi component TFindFile that encapsulates all the code from the Searching for Files article.
TFindFile - back to the old drawing boardThe idea is to create a non-visual Delphi component that fills a TStringList object with files (precisely: full path + file name) that match a certain file mask.
Naturally, we have to derive our component from the TComponent. If you are not sure how to derive a new component from an existing one, read the following: How To Create the Basic Unit for a New Component.
TFindFile PropertiesHere are the TFindFile's properties:
- FileAttr - encapsulates the Attr parameter used in the FindFirst function. For example, to search for read-only and hidden files in addition to normal files, set both ffaReadOnly and ffaHidden to true.
- FileMask - is used to set the file name mask, including wildcard characters.
- InSubFolders - is True if we want to search for files recursively in all subfolders of a given Path, False otherwise.
- Path - specifies the directory in which we want to start searching for files.
- Name and Tag properties are derived from TComponent.
TFindFile MethodsSince TFindFile component's only job is to fill in some StringList object with files that match the criteria, it has only one public method: SearchForFiles. The implementation looks like:
Note: The s variable (private to the component) is of TStringList type. The SearchForFiles calls the FileSearch procedure (also private). The FileSearch procedure fills (recursively) the s variable with all the files found. The implementation of the FileSearch procedure is similar to the FileSearch procedure from the previous article.
function TFindFile.SearchForFiles: TStringList; begin s.Clear; try FileSearch(Path) ; finally Result := s; end; end;
TFindFile in ActionThe easiest way to see our component in action is to start up with a new Delphi project. Drop one TListBox, one TButton and, of course, one TFindFile component on a form. The button will fill ListBox's Items property with all the files that are found by the TFindFile component. Just one line of code is all we need:
Naturally, all the properties of the TFindFile are initially set at design time. When you drop TFindFile component on a form, the Path property is pointing to the current directory, the file mask is "*.*", and InSubFolders property is set to False, by default.
ListBox1.Items := FindFile1.SearchForFiles;
Note: Since SearchForFiles function fills a StringList object, in addition to ListBox we can use TMemo (Lines property) or TComboBox (Items property).
TFindFile - Create and Use at Run TimeAs like any other Delphi component, TFindFile component can be created, used and destroyed at run time. To create a TFindFile component at run, we can use the following code (suppose we have a TMemo named Memo1) :
This piece of code creates a TFindFile component at run time and fills the Memo component with all the *.pas files that are found in all subfolders of the application start up folder.
uses FindFile; ... procedure TfrMain.Button2Click(Sender: TObject) ; var FFile : TFindFile; begin FFile := TFindFile.Create(nil) ; try FFile.FileAttr := [ffaAnyFile]; FFile.InSubFolders := True; FFile.Path := ExtractFilePath(ParamStr(0)) ; FFIle.FileMask := '*.pas'; Memo1.Lines := FFile.SearchForFiles; finally FFile.Free; end; end;
Note 1: If you look at the TFindFile's code, you'll notice that every time you try to change the Path property (SetPath procedure): if the specified directory does not exist the Path property is restored.
Note 2: If you want to specify the current folder assign '.' to the Path property, also if you set '..' to the Path property, Path is pointing to the curent's parent folder.
If you don't know how to install this component check out How To Install Custom Component in Delphi (into existing package).