我想获取shell命名空间中对象的系统映像列表中的索引。
如果此对象是文件,我可以使用SHGetFileInfo
:
function GetFileImageIndex(const Filename: string): Integer;
var
sfi: TSHFileInfo;
begin
SHGetFileInfo(PChar(Filename), FILE_ATTRIBUTE_NORMAL, sfi, SizeOf(sfi),
SHGFI_USEFILEATTRIBUTES or SHGFI_SYSICONINDEX);
Result := sfi.iIcon;
end;
除非我没有文件
我所拥有的东西并不作为文件夹或文件存在于硬盘上,例如:
Control Panel
Homegroup
Network
但是我仍然需要在与此事件相对应的图标的系统图像列表中获取索引。我从SHGetFileInfo
开始(因为它支持pidls)。但那分崩离析。然后我尝试使用IExtractIcon
,但那分崩离析:
function GetObjectImageIndex(ParentFolder: IShellFolder; const ChildPidl: PItemIDList): Integer;
//var
// sfi: TSHFileInfo;
// extractIcon: IExtractIcon;
// iconFile: WideString;
// iconIndexInFile: Integer;
// flags: Cardinal;
begin
{
This function is the shell namespace equivalent of GetFileImageIndex helper function.
}
(*
Won't work (MSDN: "The PIDL must be a fully qualified PIDL. Relative PIDLs are not allowed.")
SHGetFileInfo(PWideChar(ChildPidl), FILE_ATTRIBUTE_NORMAL,
sfi, SizeOf(sfi),
SHGFI_PIDL or SHGFI_SYSICONINDEX);
*)
(*
Won't work. Doesn't return an index into the system imagelist
ParentFolder.GetUIObjectOf(0, 1, ChildPidl, IExtractIcon, nil, {out}extractIcon);
SetLength(iconFile, MAX_PATH);
extractIcon.GetIconLocation(0, PWideChar(iconFile), Length(iconFile), iconIndexInFile, {out}flags);
*)
Result := -1; //TODO: Figure out how to do it.
end;
如果该文件夹中有IShellFolder
和pidl
,我该如何获取该系统的系统图像列表中的图标?
答案 0 :(得分:0)
简单的答案是您将标识对象的绝对PIDL传递给SHGetFileInfo
。你说你试过没有成功,但这是解决问题的方法。
你应该回到SHGetFileInfo
并让它发挥作用。看起来你已经拥有相对PIDL并停止了。使用ILCombine
创建一个绝对PIDL,你应该回家。
如果您没有包含IShellFolder
的PIDL,那么您需要阅读此主题:How to obtain the PIDL of an IShellFolder
答案 1 :(得分:0)
function CreateGlobalChildIDList(AParentFolder: IShellFolder; const AChildIDList: PItemIDList): PItemIDList; forward;
function GetObjectImageIndex(AParentFolder: IShellFolder; const AChildIDList: PItemIDList): Integer;
var
ShellIcon: IShellIcon;
ChildIDList: PItemIDList;
FileInfo: TSHFileInfo;
begin
try
Result := -1;
try
OleCheck(AParentFolder.QueryInterface(IShellIcon, ShellIcon));
try
OleCheck(ShellIcon.GetIconOf(AChildIDList, GIL_FORSHELL, Result));
finally
ShellIcon := nil;
end;
except
Result := -1;
end;
if Result = -1 then
begin
ChildIDList := CreateGlobalChildIDList(AParentFolder, AChildIDList);
try
ZeroMemory(@FileInfo, SizeOf(FileInfo));
SHGetFileInfo(PWideChar(ChildIDList), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo), SHGFI_PIDL or SHGFI_SYSICONINDEX);
Result := FileInfo.iIcon;
finally
CoTaskMemFree(ChildIDList);
end;
end;
except
Result := -1;
end;
end;
function CretaeGlobalChildIDList(AParentFolder: IShellFolder; const AChildIDList: PItemIDList): PItemIDList;
var
PersistFolder2: IPersistFolder2;
PersistIDList: IPersistIDList;
ParentIDList: PItemIDList;
begin
if Succeeded(AParentFolder.QueryInterface(IPersistFolder2, PersistFolder2)) then
try
OleCheck(PersistFolder2.GetCurFolder(ParentIDList));
try
Result := ILCombine(ParentIDList, AChildIDList);
finally
CoTaskMemFree(ParentIDList);
end;
finally
PersistFolder2 := nil;
end
else
if Succeeded(AParentFolder.QueryInterface(IPersistIDList, PersistIDList)) then
try
OleCheck(PersistIDList.GetIDList(ParentIDList));
try
Result := ILCombine(ParentIDList, AChildIDList);
finally
CoTaskMemFree(ParentIDList);
end;
finally
PersistIDList := nil;
end
else
raise Exception.Create('Cannot create PIDL');
end;