|
@@ -87,7 +87,7 @@ type
|
|
{Additional events:}
|
|
{Additional events:}
|
|
type
|
|
type
|
|
TDirViewFileSizeChanged = procedure(Sender: TObject; Item: TListItem) of object;
|
|
TDirViewFileSizeChanged = procedure(Sender: TObject; Item: TListItem) of object;
|
|
- TDirViewFileIconForName = procedure(Sender: TObject; Item: TListItem; var FileName: string) of object;
|
|
|
|
|
|
+ TDirViewFileIconForName = procedure(Sender: TObject; var FileName: string) of object;
|
|
|
|
|
|
type
|
|
type
|
|
TDirView = class;
|
|
TDirView = class;
|
|
@@ -225,6 +225,8 @@ type
|
|
procedure WMDestroy(var Msg: TWMDestroy); message WM_DESTROY;
|
|
procedure WMDestroy(var Msg: TWMDestroy); message WM_DESTROY;
|
|
procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND;
|
|
procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND;
|
|
procedure Load(DoFocusSomething: Boolean); override;
|
|
procedure Load(DoFocusSomething: Boolean); override;
|
|
|
|
+ procedure DoFetchIcon(
|
|
|
|
+ FilePath: string; IsSpecialExt: Boolean; CanTimeout: Boolean; FileRec: PFileRec; var ImageIndex: Integer; var TypeName: string);
|
|
function GetFileInfo(
|
|
function GetFileInfo(
|
|
CanUsePIDL: Boolean; PIDL: PItemIDList; Path: string; CanTimeout: Boolean;
|
|
CanUsePIDL: Boolean; PIDL: PItemIDList; Path: string; CanTimeout: Boolean;
|
|
dwFileAttributes: DWORD; var psfi: TSHFileInfoW; uFlags: UINT): DWORD_PTR;
|
|
dwFileAttributes: DWORD; var psfi: TSHFileInfoW; uFlags: UINT): DWORD_PTR;
|
|
@@ -669,12 +671,9 @@ end; {SetIndex}
|
|
|
|
|
|
procedure TIconUpdateThread.Execute;
|
|
procedure TIconUpdateThread.Execute;
|
|
var
|
|
var
|
|
- FileInfo: TShFileInfo;
|
|
|
|
Count: Integer;
|
|
Count: Integer;
|
|
- Eaten: ULONG;
|
|
|
|
- ShAttr: ULONG;
|
|
|
|
- FileIconForName: string;
|
|
|
|
- ForceByName: Boolean;
|
|
|
|
|
|
+ IsSpecialExt: Boolean;
|
|
|
|
+ TypeName: string;
|
|
begin
|
|
begin
|
|
if Assigned(FOwner.TopItem) then FIndex := FOwner.TopItem.Index
|
|
if Assigned(FOwner.TopItem) then FIndex := FOwner.TopItem.Index
|
|
else FIndex := 0;
|
|
else FIndex := 0;
|
|
@@ -694,24 +693,8 @@ begin
|
|
CurrentItemData.IconEmpty then
|
|
CurrentItemData.IconEmpty then
|
|
begin
|
|
begin
|
|
try
|
|
try
|
|
- ForceByName := False;
|
|
|
|
- FileIconForName := CurrentFilePath;
|
|
|
|
- if Assigned(FOwner.FOnFileIconForName) then
|
|
|
|
- begin
|
|
|
|
- FOwner.FOnFileIconForName(FOwner, nil, FileIconForName);
|
|
|
|
- ForceByName := (FileIconForName <> CurrentFilePath);
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
- if not Assigned(CurrentItemData.PIDL) then
|
|
|
|
- begin
|
|
|
|
- ShAttr := 0;
|
|
|
|
- FOwner.FDesktopFolder.ParseDisplayName(FOwner.ParentForm.Handle, nil,
|
|
|
|
- PChar(CurrentFilePath), Eaten, CurrentItemData.PIDL, ShAttr);
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
- FOwner.GetFileInfo(
|
|
|
|
- (not ForceByName), CurrentItemData.PIDL, FileIconForName, False,
|
|
|
|
- 0, FileInfo, SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX);
|
|
|
|
|
|
+ IsSpecialExt := MatchesFileExt(CurrentItemData.FileExt, SpecialExtensions);
|
|
|
|
+ FOwner.DoFetchIcon(CurrentFilePath, IsSpecialExt, False, @CurrentItemData, FSyncIcon, TypeName);
|
|
except
|
|
except
|
|
{Capture exceptions generated by the shell}
|
|
{Capture exceptions generated by the shell}
|
|
FSyncIcon := UnKnownFileIcon;
|
|
FSyncIcon := UnKnownFileIcon;
|
|
@@ -721,7 +704,6 @@ begin
|
|
FreePIDL(CurrentItemData.PIDL);
|
|
FreePIDL(CurrentItemData.PIDL);
|
|
Break;
|
|
Break;
|
|
end;
|
|
end;
|
|
- FSyncIcon := FileInfo.iIcon;
|
|
|
|
if FSyncIcon <> CurrentItemData.ImageIndex then
|
|
if FSyncIcon <> CurrentItemData.ImageIndex then
|
|
FNewIcons := True;
|
|
FNewIcons := True;
|
|
if not Terminated then
|
|
if not Terminated then
|
|
@@ -1786,18 +1768,99 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TDirView.DoFetchIcon(
|
|
|
|
+ FilePath: string; IsSpecialExt: Boolean; CanTimeout: Boolean; FileRec: PFileRec; var ImageIndex: Integer; var TypeName: string);
|
|
|
|
+var
|
|
|
|
+ Eaten: ULONG;
|
|
|
|
+ shAttr: ULONG;
|
|
|
|
+ FileInfo: TShFileInfo;
|
|
|
|
+ ForceByName: Boolean;
|
|
|
|
+ FileIconForName: string;
|
|
|
|
+begin
|
|
|
|
+ {Fetch the Item FQ-PIDL:}
|
|
|
|
+ if not Assigned(FileRec^.PIDL) and IsSpecialExt then
|
|
|
|
+ begin
|
|
|
|
+ try
|
|
|
|
+ ShAttr := 0;
|
|
|
|
+ FDesktopFolder.ParseDisplayName(
|
|
|
|
+ ParentForm.Handle, nil, PChar(FilePath), Eaten, FileRec^.PIDL, ShAttr);
|
|
|
|
+ except
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if FileRec^.IsDirectory then
|
|
|
|
+ begin
|
|
|
|
+ if FDriveType = DRIVE_FIXED then
|
|
|
|
+ begin
|
|
|
|
+ try
|
|
|
|
+ {Retrieve icon and typename for the directory}
|
|
|
|
+ GetFileInfo(True, FileRec^.PIDL, FilePath, False, 0, FileInfo, SHGFI_TYPENAME or SHGFI_SYSICONINDEX);
|
|
|
|
+
|
|
|
|
+ if (FileInfo.iIcon <= 0) or (FileInfo.iIcon > SmallImages.Count) then
|
|
|
|
+ begin
|
|
|
|
+ {Invalid icon returned: retry with access file attribute flag:}
|
|
|
|
+ GetFileInfo(
|
|
|
|
+ False, nil, FilePath, False,
|
|
|
|
+ FILE_ATTRIBUTE_DIRECTORY, FileInfo, SHGFI_TYPENAME or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES);
|
|
|
|
+ end;
|
|
|
|
+ TypeName := FileInfo.szTypeName;
|
|
|
|
+ ImageIndex := FileInfo.iIcon;
|
|
|
|
+ except
|
|
|
|
+ {Capture exceptions generated by the shell}
|
|
|
|
+ TypeName := StdDirTypeName;
|
|
|
|
+ ImageIndex := StdDirIcon;
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ TypeName := StdDirTypeName;
|
|
|
|
+ ImageIndex := StdDirIcon;
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ {Retrieve icon and typename for the file}
|
|
|
|
+ try
|
|
|
|
+ ForceByName := False;
|
|
|
|
+ FileIconForName := FilePath;
|
|
|
|
+ if Assigned(OnFileIconForName) then
|
|
|
|
+ begin
|
|
|
|
+ OnFileIconForName(Self, FileIconForName);
|
|
|
|
+ ForceByName := (FileIconForName <> FilePath);
|
|
|
|
+ end;
|
|
|
|
+ // Files with PIDL are typically .exe files.
|
|
|
|
+ // It may take long to retrieve an icon from exe file.
|
|
|
|
+ // We typically do not get here, now that we have UseIconUpdateThread enabled.
|
|
|
|
+ if GetFileInfo(
|
|
|
|
+ (not ForceByName), FileRec^.PIDL, FileIconForName, CanTimeout, FILE_ATTRIBUTE_NORMAL, FileInfo,
|
|
|
|
+ SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX) = 0 then
|
|
|
|
+ begin
|
|
|
|
+ if Assigned(FileRec^.PIDL) then
|
|
|
|
+ begin
|
|
|
|
+ FileInfo.iIcon := DefaultExeIcon;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ TypeName := FileInfo.szTypeName;
|
|
|
|
+ ImageIndex := FileInfo.iIcon;
|
|
|
|
+
|
|
|
|
+ except
|
|
|
|
+ {Capture exceptions generated by the shell}
|
|
|
|
+ ImageIndex := UnKnownFileIcon;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TDirView.GetDisplayData(Item: TListItem; FetchIcon: Boolean);
|
|
procedure TDirView.GetDisplayData(Item: TListItem; FetchIcon: Boolean);
|
|
var
|
|
var
|
|
FileInfo: TShFileInfo;
|
|
FileInfo: TShFileInfo;
|
|
IsSpecialExt: Boolean;
|
|
IsSpecialExt: Boolean;
|
|
- ForceByName: Boolean;
|
|
|
|
- Eaten: ULONG;
|
|
|
|
- shAttr: ULONG;
|
|
|
|
- FileIconForName, FullName: string;
|
|
|
|
|
|
+ FileRec: PFileRec;
|
|
|
|
+ FilePath: string;
|
|
FileAttributes: UINT;
|
|
FileAttributes: UINT;
|
|
begin
|
|
begin
|
|
Assert(Assigned(Item) and Assigned(Item.Data));
|
|
Assert(Assigned(Item) and Assigned(Item.Data));
|
|
- with PFileRec(Item.Data)^ do
|
|
|
|
|
|
+ FileRec := PFileRec(Item.Data);
|
|
|
|
+ with FileRec^ do
|
|
begin
|
|
begin
|
|
IsSpecialExt := MatchesFileExt(FileExt, SpecialExtensions);
|
|
IsSpecialExt := MatchesFileExt(FileExt, SpecialExtensions);
|
|
|
|
|
|
@@ -1805,87 +1868,15 @@ begin
|
|
|
|
|
|
if Empty or FetchIcon then
|
|
if Empty or FetchIcon then
|
|
begin
|
|
begin
|
|
|
|
+ FilePath := FPath + '\' + FileName;
|
|
if FetchIcon then
|
|
if FetchIcon then
|
|
begin
|
|
begin
|
|
- {Fetch the Item FQ-PIDL:}
|
|
|
|
- if not Assigned(PIDL) and IsSpecialExt then
|
|
|
|
- begin
|
|
|
|
- try
|
|
|
|
- ShAttr := 0;
|
|
|
|
- FDesktopFolder.ParseDisplayName(ParentForm.Handle, nil,
|
|
|
|
- PChar(FPath + '\' + FileName), Eaten, PIDL, ShAttr);
|
|
|
|
- except
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
- if IsDirectory then
|
|
|
|
- begin
|
|
|
|
- if FDriveType = DRIVE_FIXED then
|
|
|
|
- begin
|
|
|
|
- try
|
|
|
|
- {Retrieve icon and typename for the directory}
|
|
|
|
- GetFileInfo(True, PIDL, FPath + '\' + FileName, False, 0, FileInfo, SHGFI_TYPENAME or SHGFI_SYSICONINDEX);
|
|
|
|
-
|
|
|
|
- if (FileInfo.iIcon <= 0) or (FileInfo.iIcon > SmallImages.Count) then
|
|
|
|
- begin
|
|
|
|
- {Invalid icon returned: retry with access file attribute flag:}
|
|
|
|
- GetFileInfo(False, nil, FPath + '\' + FileName, False,
|
|
|
|
- FILE_ATTRIBUTE_DIRECTORY, FileInfo, SHGFI_TYPENAME or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES);
|
|
|
|
- end;
|
|
|
|
- TypeName := FileInfo.szTypeName;
|
|
|
|
- ImageIndex := FileInfo.iIcon;
|
|
|
|
- IconEmpty := False;
|
|
|
|
- {Capture exceptions generated by the shell}
|
|
|
|
- except
|
|
|
|
- ImageIndex := StdDirIcon;
|
|
|
|
- IconEmpty := False;
|
|
|
|
- end; {Except}
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- begin
|
|
|
|
- TypeName := StdDirTypeName;
|
|
|
|
- ImageIndex := StdDirIcon;
|
|
|
|
- IconEmpty := False;
|
|
|
|
- end;
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- begin
|
|
|
|
- {Retrieve icon and typename for the file}
|
|
|
|
- try
|
|
|
|
- ForceByName := False;
|
|
|
|
- FullName := FPath + '\' + FileName;
|
|
|
|
- FileIconForName := FullName;
|
|
|
|
- if Assigned(OnFileIconForName) then
|
|
|
|
- begin
|
|
|
|
- OnFileIconForName(Self, Item, FileIconForName);
|
|
|
|
- ForceByName := (FileIconForName <> FullName);
|
|
|
|
- end;
|
|
|
|
- // Files with PIDL are typically .exe files.
|
|
|
|
- // It may take long to retrieve an icon from exe file.
|
|
|
|
- // We typically do not get here, now that we have UseIconUpdateThread enabled.
|
|
|
|
- if GetFileInfo(
|
|
|
|
- (not ForceByName), PIDL, FileIconForName, True, FILE_ATTRIBUTE_NORMAL, FileInfo,
|
|
|
|
- SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX) = 0 then
|
|
|
|
- begin
|
|
|
|
- if Assigned(PIDL) then
|
|
|
|
- begin
|
|
|
|
- FileInfo.iIcon := DefaultExeIcon;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- TypeName := FileInfo.szTypeName;
|
|
|
|
- ImageIndex := FileInfo.iIcon;
|
|
|
|
- IconEmpty := False;
|
|
|
|
-
|
|
|
|
- {Capture exceptions generated by the shell}
|
|
|
|
- except
|
|
|
|
- ImageIndex := UnKnownFileIcon;
|
|
|
|
- IconEmpty := False;
|
|
|
|
- end; {Except}
|
|
|
|
- end;
|
|
|
|
|
|
+ DoFetchIcon(FilePath, IsSpecialExt, True, FileRec, ImageIndex, TypeName);
|
|
|
|
+ IconEmpty := False;
|
|
|
|
|
|
if Length(TypeName) = 0 then
|
|
if Length(TypeName) = 0 then
|
|
TypeName := Format(STextFileExt, [FileExt]);
|
|
TypeName := Format(STextFileExt, [FileExt]);
|
|
- end {If FetchIcon}
|
|
|
|
|
|
+ end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
try
|
|
try
|
|
@@ -1893,7 +1884,7 @@ begin
|
|
else FileAttributes := FILE_ATTRIBUTE_NORMAL;
|
|
else FileAttributes := FILE_ATTRIBUTE_NORMAL;
|
|
|
|
|
|
GetFileInfo(
|
|
GetFileInfo(
|
|
- False, nil, FPath + '\' + FileName, False, FileAttributes, FileInfo,
|
|
|
|
|
|
+ False, nil, FilePath, False, FileAttributes, FileInfo,
|
|
SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES);
|
|
SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES);
|
|
TypeName := FileInfo.szTypeName;
|
|
TypeName := FileInfo.szTypeName;
|
|
except
|
|
except
|