给定 Windows Vista 或更高版本IShellItem
,如何获取与该项目关联的系统图像列表图标索引?
例如(伪代码):
IShellItem networkFolder = SHGetKnownFolderItem(FOLDERID_NetworkFolder, 0, 0, IShellItem);
Int32 iconIndex = GetSmallSysIconIndex(networkFolder);
Int32 GetSmallSysIconIndex(IShellItem item)
{
//TODO: Ask Stackoverflow
}
背景
在过去(Windows 95 及更新版本),我们可以要求 shell 为我们提供项目图标的系统图像列表索引。我们这样做是使用。 SHGetFileInfo 函数通过向 shell 命名空间询问系统图像列表中的图标索引来获取图标 https://blogs.msdn.microsoft.com/oldnewthing/20110127-00/?p=11653:
HICON GetIconIndex(PCTSTR pszFile)
{
SHFILEINFO sfi;
HIMAGELIST himl = SHGetFileInfo(pszFile, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX));
if (himl) {
return sfi.iIcon;
} else {
return -1;
}
}
当您使用 shell 命名空间中与文件相对应的项目时,这会起作用。但是 shell 支持文件系统中除文件和文件夹之外的其他内容。
IShellFolder 中的图标索引
获取有关 shell 命名空间中对象的信息的一般解决方案来自于使用表示对象的方式item在 shell 命名空间中:
-
IShellFolder
: 的文件夹thing坐在里面,与
-
child
PIDL
: 的 IDthing在那个文件夹中
从此有获取系统镜像列表索引的方法 https://stackoverflow.com/questions/25353059/how-to-get-the-shell-image-index-of-an-object-in-the-shell-namespace:
Int32 GetIconIndex(IShellFolder folder, PITEMID_CHILD childPidl)
{
//Note: I actually have no idea how to do this.
}
但是 IShellFolder 已经退出了;我们现在使用 IShellItem
从 Windows Vista 开始,IShellItem
became 首选接入点 https://msdn.microsoft.com/en-us/library/windows/desktop/bb761144(v=vs.85).aspxI 用于在 shell 中导航。 Windows 95 时代的 API 必须保留一个IShellFolder
+pidl
配对很麻烦,而且容易出错 https://blogs.msdn.microsoft.com/oldnewthing/20110831-00/?p=9763/.
问题是:如何用它来做事?特别是,如何获取该项目的系统图像列表中的图像索引?看看它的方法,甚至没有办法获得它的绝对pidl:
-
绑定到处理程序:绑定到由处理程序 ID 值 (BHID) 指定的项目的处理程序。
-
Compare:比较两个 IShellItem 对象。
-
获取属性:获取 IShellItem 对象的请求属性集。
-
获取显示名称:获取IShellItem对象的显示名称。
-
获取父级:获取 IShellItem 对象的父对象。
我希望Windows 属性系统 https://msdn.microsoft.com/en-us/library/windows/desktop/dd561977(v=vs.85).aspx,可通过IShellItem2 https://msdn.microsoft.com/en-us/library/windows/desktop/bb761130(v=vs.85).aspx,将具有与 shell imagelist 图标索引关联的属性。不幸的是,我没有看到任何:
- 系统.描述ID https://msdn.microsoft.com/en-us/library/windows/desktop/bb760159(v=vs.85).aspx
- 系统信息提示文本 https://msdn.microsoft.com/en-us/library/windows/desktop/dd391574(v=vs.85).aspx
- 系统内部名称 https://msdn.microsoft.com/en-us/library/windows/desktop/bb892886(v=vs.85).aspx
- System.Link.TargetSFGAOFlagsStrings https://msdn.microsoft.com/en-us/library/windows/desktop/bb760160(v=vs.85).aspx
- 系统.链接.TargetUrl https://msdn.microsoft.com/en-us/library/windows/desktop/bb760161(v=vs.85).aspx
- 系统命名空间CLSID https://msdn.microsoft.com/en-us/library/windows/desktop/dd391575(v=vs.85).aspx
- System.Shell.SFGAOFlagsStrings https://msdn.microsoft.com/en-us/library/windows/desktop/bb760162(v=vs.85).aspx
提取图标的方法
There 有很多标准方法 https://xkcd.com/927/获得与 a 相匹配的图片thing在 Windows Shell 命名空间中:
-
IExtractIcon https://msdn.microsoft.com/en-us/library/bb761854(v=vs.85).aspx。返回一个
HICON
。需要IShellFolder
+pidl。如果失败您可以使用 SHDefExtractIcon https://blogs.msdn.microsoft.com/oldnewthing/20140501-00/?p=1103
-
SHDefExtractIcon https://msdn.microsoft.com/en-us/library/windows/desktop/bb762149(v=vs.85).aspx。返回一个
HICON
。需要图标文件的完整路径
-
IThumbnailCache https://msdn.microsoft.com/en-us/library/windows/desktop/bb774628(v=vs.85).aspx。需要
IShellItem
。返回缩略图,而不是图标
-
IShellImageFactory https://msdn.microsoft.com/en-us/library/windows/desktop/bb761084(v=vs.85).aspx。获取代表一个位图
IShellItem
-
。 Windows Vista 的替代品
IExtractImage
-
IExtractImage https://msdn.microsoft.com/en-us/library/windows/desktop/bb761848(v=vs.85).aspx。需要
IShellFolder
+pidl
.
-
SHGetFileInfo https://msdn.microsoft.com/en-us/library/windows/desktop/bb762179(v=vs.85).aspx。需要完整文件路径或绝对pidl
他们都没有: