I just discovered that some programs are very quick when getting/listing the directory of network drives, almost instantly. I am talking about programs like FreeComanderXE and DirectoryOpus here.
In my program it takes several seconds to do the same task. What can I do to improve the speed here.
This is my code for loading the directory in a thread:
procedure LoadDirThread.Execute;
var
PIdx: Integer;
b: Boolean;
n: Integer;
FName: string;
Item: TXplorerItem;
i: Integer;
Path: String;
SR: TSearchRec;
SFI: TSHFileInfo;
FData: TXplorerItem;
begin
inherited;
if not XPlorerLink.Loaded then
begin
Path := XPlorerLink.Path;
PIdx := XPlorerLink.PathList.IndexOf(Path);
if PIdx = -1 then
PIdx := XPlorerLink.PathList.Add(Path);
if FindFirst(Path + '*.*', faAnyFile - faHidden, SR) = 0 then
begin
repeat
if (SR.Name <> '.') and (SR.Name <> '..') then
begin
if (SR.Attr and faDirectory <> 0) then
begin
FData := TXplorerItem.Create;
FName := Path + SR.Name;
SHGetFileInfo(PChar(FName), 0, SFI, SizeOf(SFI), SHGFI_DISPLAYNAME or
SHGFI_TYPENAME);
FData.FAttr:= SR.Attr;
FData.Kind := xiDir;
FData.Size := 0;
FData.Caption := Strpas(SFI.szDisplayName);
if FData.Caption = '' then
FData.Caption := ChangeFileExt(SR.Name, '');
FData.Name := SR.Name;
FData.Modified := FileDateToDateTime(SR.Time);
FData.ImgIdx := -1;
n := XPlorerLink.InfoList.IndexOf(SFI.szTypeName);
if n = -1 then
n := XPlorerLink.InfoList.Add(SFI.szTypeName);
FData.InfoIdx := n;
FData.PathIdx := PIdx;
XPlorerLink.Items.Add(FData);
end
else
if (SR.Attr and faDirectory = 0) then
begin
FData := TXplorerItem.Create;
FName := Path + SR.Name;
SHGetFileInfo(PChar(FName), 0, SFI, SizeOf(SFI), SHGFI_DISPLAYNAME or
SHGFI_TYPENAME);
FData.FAttr:= SR.Attr;
FData.Kind := xiFile;
FData.Size := SR.Size;
FData.Caption := Strpas(SFI.szDisplayName);
if FData.Caption = '' then
FData.Caption := ChangeFileExt(SR.Name, '');
FData.Name := SR.Name;
FData.Modified := FileDateToDateTime(SR.Time);
FData.ImgIdx := -1;
n := XPlorerLink.InfoList.IndexOf(SFI.szTypeName);
if n = -1 then
n := XPlorerLink.InfoList.Add(SFI.szTypeName);
FData.InfoIdx := n;
FData.PathIdx := PIdx;
XPlorerLink.Items.Add(FData);
end;
end;
until (FindNext(SR) <> 0) or Terminated;
FindClose(SR);
end;
end;
if not Terminated then
PostMessage(frmMain.Handle, CM_UPDATEVIEW, -2, Integer(XPlorerLink));
end;
Change your code to use the
IShellFolderinterface instead of theFind...()functions. Everything in the Windows Shell is internally represented byIShellFolder,ITEMIDLISTs, etc, even file system and network paths. When performance matters, use Windows’ own native data. Windows Explorer usesIShellFolderand related interfaces for all of its main work.