I have implemented this code in Delphi, it will search for the File or the name given but it omits searching all the subdirectories. How can this be done?
Code:
if FindFirst(filePath,faAnyFile,searchResult)=0 then
try
repeat
lbSearchResult.Items.Append(searchResult.Name);
until FindNext(searchResult)<>0
except
on e:Exception do
ShowMessage(e.Message);
end; //try ends
FindClose(searchResult);
If you don't need threading, the simplest way is this:
procedure TForm1.AddAllFilesInDir(const Dir: string);
var
SR: TSearchRec;
begin
if FindFirst(IncludeTrailingBackslash(Dir) + '*.*', faAnyFile or faDirectory, SR) = 0 then
try
repeat
if (SR.Attr and faDirectory) = 0 then
ListBox1.Items.Add(SR.Name)
else if (SR.Name <> '.') and (SR.Name <> '..') then
AddAllFilesInDir(IncludeTrailingBackslash(Dir) + SR.Name); // recursive call!
until FindNext(Sr) <> 0;
finally
FindClose(SR);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Items.BeginUpdate;
AddAllFilesInDir('C:\Users\Andreas Rejbrand\Documents\Aweb');
ListBox1.Items.EndUpdate;
end;
With Delphi XE and up, you can have a look at IOUtils.pas:
TDirectory.GetFiles('C:\', '*.dll', TSearchOption.soAllDirectories);
The simplest way is:
uses
DSiWin32;
DSiEnumFilesToStringList('c:\somefolder\file.name', 0, ListBox1.Items, true, true);
DSiWin32 is a free Delphi library.
When i need to do tricks
like override protected methods i tend to use a generic solution to the problem... i do a hack to the class.
Here is how to do it with TDirectoryListbox
.
On every Form you need to use this hacked
TDirectoryListbox
just add unitTDirectoryListbox_WithHiddenAndSystemFolders
to interface uses
, that way the form will use the hacked
TDirectoryListbox
.
Create a file called unitTDirectoryListbox_WithHiddenAndSystemFolders.pas
on your proyect folder.
Put this text inside that file (i will explain later what i have done):
unit unitTDirectoryListbox_WithHiddenAndSystemFolders;
interface
uses
Windows
,SysUtils
,Classes
,FileCtrl
;
type TDirectoryListbox=class(FileCtrl.TDirectoryListbox)
private
FPreserveCase:Boolean;
FCaseSensitive:Boolean;
protected
function ReadDirectoryNames(const ParentDirectory:String;DirectoryList:TStringList):Integer;
procedure BuildList;override;
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
property PreserveCase:Boolean read FPreserveCase;
property CaseSensitive:Boolean read FCaseSensitive;
end;
implementation
constructor TDirectoryListbox.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
end;
destructor TDirectoryListbox.Destroy;
begin
inherited Destroy;
end;
function TDirectoryListbox.ReadDirectoryNames(const ParentDirectory:String;DirectoryList:TStringList):Integer;
var
TheCount,Status:Integer;
SearchRec:TSearchRec;
begin
TheCount:=0;
Status:=FindFirst(IncludeTrailingPathDelimiter(ParentDirectory)+'*.*',faDirectory or faHidden or faSysFile,SearchRec);
try
while 0=Status
do begin
if faDirectory=(faDirectory and SearchRec.Attr)
then begin
if ('.'<>SearchRec.Name)
and
('..'<>SearchRec.Name)
then begin
DirectoryList.Add(SearchRec.Name);
Inc(TheCount);
end;
end;
Status:=FindNext(SearchRec);
end;
finally
FindClose(SearchRec);
end;
ReadDirectoryNames:=TheCount;
end;
procedure TDirectoryListBox.BuildList;
var
TempPath: string;
DirName: string;
IndentLevel, BackSlashPos: Integer;
VolFlags: DWORD;
I: Integer;
Siblings: TStringList;
NewSelect: Integer;
Root: string;
begin
try
Items.BeginUpdate;
Items.Clear;
IndentLevel := 0;
Root := ExtractFileDrive(Directory)+'\';
GetVolumeInformation(PChar(Root), nil, 0, nil, DWORD(i), VolFlags, nil, 0);
FPreserveCase := VolFlags and (FS_CASE_IS_PRESERVED or FS_CASE_SENSITIVE) <> 0;
FCaseSensitive := (VolFlags and FS_CASE_SENSITIVE) <> 0;
if (Length(Root) >= 2) and (Root[2] = '\') then
begin
Items.AddObject(Root, OpenedBMP);
Inc(IndentLevel);
TempPath := Copy(Directory, Length(Root)+1, Length(Directory));
end
else
TempPath := Directory;
if (Length(TempPath) > 0) then
begin
if AnsiLastChar(TempPath)^ <> '\' then
begin
BackSlashPos := AnsiPos('\', TempPath);
while BackSlashPos <> 0 do
begin
DirName := Copy(TempPath, 1, BackSlashPos - 1);
if IndentLevel = 0 then DirName := DirName + '\';
Delete(TempPath, 1, BackSlashPos);
Items.AddObject(DirName, OpenedBMP);
Inc(IndentLevel);
BackSlashPos := AnsiPos('\', TempPath);
end;
end;
Items.AddObject(TempPath, CurrentBMP);
end;
NewSelect := Items.Count - 1;
Siblings := TStringList.Create;
try
Siblings.Sorted := True;
{ read all the dir names into Siblings }
ReadDirectoryNames(Directory, Siblings);
for i := 0 to Siblings.Count - 1 do
Items.AddObject(Siblings[i], ClosedBMP);
finally
Siblings.Free;
end;
finally
Items.EndUpdate;
end;
if HandleAllocated then
ItemIndex := NewSelect;
end;
end.
Now i explain what i have done:
unitTDirectoryListbox_WithHiddenAndSystemFolders
to interface uses
i make the form to use the modified (aka, hacked
) component.ReadDirectoryNames
(the one that needs a modification), i copy it from unit FileCtrl
and then i edit that copy on my own unit to fix
the problem (not showing Hidden folders, neither System folders); the trick
is to edit the call to FindFirst
by adding after faDirectory
the part or faHidden or faSysFile
, i also change SlashSep
to IncludeTrailingPathDelimiter
(avoid some extra references, etc) and also do a reformat (indexing, etc) so i can see that method is the one i had modified.BuildList
, that one i just simply copy it from unit FileCtrl
without any modification (if not copied the hack
does not work, since the call to ReadDirectoryNames
is inside BuildList
).FPreserveCase
and FCaseSensitive
and their property declarations (they are used inside BuildList
method).TDirectoryListBox
will see hidden and system foldersHope this helps others, this way you can have both TDirectoryListBox
(original one and modified one) at same time (but not on same form, sorry) on your project, without modifing VCL at all.
P.D.: Someone with extra knowledge maybe is able to add properties to configure if it must show or not hidden and/or system folders as an improvement, it must not be very difficoult, two private boolean variables and their corresponding property
declaration with read and write methods... i did not do it since i would like to add not only such two, also SymLinks, etc (search for faSymLink
on unit SysUtils
and see how many there are, a lot of work to add them all), sorry for any inconvenience for that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With