|
@@ -225,7 +225,9 @@ type
|
|
|
procedure WMDestroy(var Msg: TWMDestroy); message WM_DESTROY;
|
|
|
procedure CMRecreateWnd(var Message: TMessage); message CM_RECREATEWND;
|
|
|
procedure Load(DoFocusSomething: Boolean); override;
|
|
|
- function GetFileInfo(pszPath: LPCWSTR; dwFileAttributes: DWORD; var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD_PTR;
|
|
|
+ function GetFileInfo(
|
|
|
+ CanUsePIDL: Boolean; PIDL: PItemIDList; Path: string; CanTimeout: Boolean;
|
|
|
+ dwFileAttributes: DWORD; var psfi: TSHFileInfoW; uFlags: UINT): DWORD_PTR;
|
|
|
function DoCopyToClipboard(Focused: Boolean; Cut: Boolean; Operation: TClipBoardOperation): Boolean;
|
|
|
|
|
|
function HiddenCount: Integer; override;
|
|
@@ -707,16 +709,9 @@ begin
|
|
|
PChar(CurrentFilePath), Eaten, CurrentItemData.PIDL, ShAttr);
|
|
|
end;
|
|
|
|
|
|
- if (not ForceByName) and Assigned(CurrentItemData.PIDL) then
|
|
|
- begin
|
|
|
- SHGetFileInfo(PChar(CurrentItemData.PIDL), 0, FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_PIDL)
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- SHGetFileInfo(PChar(FileIconForName), 0, FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX);
|
|
|
- end;
|
|
|
+ FOwner.GetFileInfo(
|
|
|
+ (not ForceByName), CurrentItemData.PIDL, FileIconForName, False,
|
|
|
+ 0, FileInfo, SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX);
|
|
|
except
|
|
|
{Capture exceptions generated by the shell}
|
|
|
FSyncIcon := UnKnownFileIcon;
|
|
@@ -1159,8 +1154,7 @@ begin
|
|
|
FileMatches(DisplayName, SRec)) then
|
|
|
begin
|
|
|
{Filetype and icon:}
|
|
|
- SHGetFileInfo(PChar(FQPIDL), 0, FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_PIDL or SHGFI_TYPENAME or SHGFI_SYSICONINDEX);
|
|
|
+ GetFileInfo(True, FQPIDL, '', False, 0, FileInfo, SHGFI_TYPENAME or SHGFI_SYSICONINDEX);
|
|
|
|
|
|
NewItem := AddItem(Srec);
|
|
|
NewItem.Caption := DisplayName;
|
|
@@ -1759,16 +1753,37 @@ begin
|
|
|
end; {GetAttrString}
|
|
|
|
|
|
function TDirView.GetFileInfo(
|
|
|
- pszPath: LPCWSTR; dwFileAttributes: DWORD; var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD_PTR;
|
|
|
+ CanUsePIDL: Boolean; PIDL: PItemIDList; Path: string; CanTimeout: Boolean;
|
|
|
+ dwFileAttributes: DWORD; var psfi: TSHFileInfoW; uFlags: UINT): DWORD_PTR;
|
|
|
+var
|
|
|
+ pszPath: LPCWSTR;
|
|
|
+ cbFileInfo: UINT;
|
|
|
begin
|
|
|
- if TimeoutShellIconRetrieval then
|
|
|
+ cbFileInfo := SizeOf(psfi);
|
|
|
+ FillChar(psfi, cbFileInfo, #0);
|
|
|
+
|
|
|
+ if CanUsePIDL and Assigned(PIDL) then
|
|
|
begin
|
|
|
- Result := SHGetFileInfoWithTimeout(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags, MSecsPerSec div 4);
|
|
|
+ pszPath := PChar(PIDL);
|
|
|
+ uFlags := uFlags or SHGFI_PIDL;
|
|
|
+ end
|
|
|
+ else pszPath := PChar(Path);
|
|
|
+
|
|
|
+ // CanTimeout is False in scenarios, where we did not have any reports of hangs, to avoid thread overhead.
|
|
|
+ if TimeoutShellIconRetrieval and CanTimeout then
|
|
|
+ begin
|
|
|
+ Result := SHGetFileInfoWithTimeout(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags, MSecsPerSec div 4);
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
|
Result := SHGetFileInfo(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags);
|
|
|
end;
|
|
|
+
|
|
|
+ if Result = 0 then
|
|
|
+ begin
|
|
|
+ psfi.szTypeName[0] := #0;
|
|
|
+ psfi.iIcon := 0;
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
procedure TDirView.GetDisplayData(Item: TListItem; FetchIcon: Boolean);
|
|
@@ -1779,6 +1794,7 @@ var
|
|
|
Eaten: ULONG;
|
|
|
shAttr: ULONG;
|
|
|
FileIconForName, FullName: string;
|
|
|
+ FileAttributes: UINT;
|
|
|
begin
|
|
|
Assert(Assigned(Item) and Assigned(Item.Data));
|
|
|
with PFileRec(Item.Data)^ do
|
|
@@ -1808,23 +1824,13 @@ begin
|
|
|
begin
|
|
|
try
|
|
|
{Retrieve icon and typename for the directory}
|
|
|
- if Assigned(PIDL) then
|
|
|
- begin
|
|
|
- SHGetFileInfo(PChar(PIDL), 0, FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_TYPENAME or SHGFI_SYSICONINDEX or SHGFI_PIDL)
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- SHGetFileInfo(PChar(FPath + '\' + FileName), 0, FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_TYPENAME or SHGFI_SYSICONINDEX);
|
|
|
- end;
|
|
|
+ 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:}
|
|
|
- SHGetFileInfo(PChar(FPath + '\' + FileName), FILE_ATTRIBUTE_DIRECTORY,
|
|
|
- FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_TYPENAME or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES);
|
|
|
+ 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;
|
|
@@ -1854,25 +1860,18 @@ begin
|
|
|
OnFileIconForName(Self, Item, FileIconForName);
|
|
|
ForceByName := (FileIconForName <> FullName);
|
|
|
end;
|
|
|
- if (not ForceByName) and Assigned(PIDL) then
|
|
|
+ // 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
|
|
|
- // 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(
|
|
|
- PChar(PIDL), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX or SHGFI_PIDL) = 0 then
|
|
|
+ if Assigned(PIDL) then
|
|
|
begin
|
|
|
- FileInfo.szTypeName[0] := #0;
|
|
|
FileInfo.iIcon := DefaultExeIcon;
|
|
|
end;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- GetFileInfo(PChar(FileIconForName), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX);
|
|
|
end;
|
|
|
-
|
|
|
TypeName := FileInfo.szTypeName;
|
|
|
ImageIndex := FileInfo.iIcon;
|
|
|
IconEmpty := False;
|
|
@@ -1890,12 +1889,12 @@ begin
|
|
|
else
|
|
|
begin
|
|
|
try
|
|
|
- if IsDirectory then
|
|
|
- SHGetFileInfo(PChar(FPath + '\' + FileName), FILE_ATTRIBUTE_DIRECTORY, FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES)
|
|
|
- else
|
|
|
- SHGetFileInfo(PChar(FPath + '\' + FileName), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo),
|
|
|
- SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES);
|
|
|
+ if IsDirectory then FileAttributes := FILE_ATTRIBUTE_DIRECTORY
|
|
|
+ else FileAttributes := FILE_ATTRIBUTE_NORMAL;
|
|
|
+
|
|
|
+ GetFileInfo(
|
|
|
+ False, nil, FPath + '\' + FileName, False, FileAttributes, FileInfo,
|
|
|
+ SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES);
|
|
|
TypeName := FileInfo.szTypeName;
|
|
|
except
|
|
|
{Capture exceptions generated by the shell}
|