鉴于Windows Vista或更新的IShellItem ,我如何获得与该项目相关联的系统映像列表图标索引?
例如(伪代码) :
IShellItem networkFolder = SHGetKNownFolderItem(FOLDERID_NetworkFolder,IShellItem); Int32 iconIndex = GetSmallSysIconIndex(networkFolder); Int32 GetSmallSysIconIndex(IShellItem item) { //Todo: Ask Stackoverflow }
背景
在过去的时代(Windows 95和更新版本),我们可以让shell给我们一个项目的图标的系统图像列表索引。 我们使用SHGetFileInfo 。 SHGetFileInfo函数通过询问shell命名空间获取系统图像列表中的图标索引来获取图标 :
HICON GetIconIndex(PCTSTR pszFile) { SHFILEINFO sfi; HIMAGELIST himl = SHGetFileInfo(pszFile,&sfi,sizeof(sfi),SHGFI_SYSICONINDEX)); if (himl) { return sfi.iIcon; } else { return -1; } }
当在shell命名空间中使用与文件相对应的项目时,这将起作用。 但是shell支持除了文件系统中的文件和文件夹之外的东西。
Windows环境中的Envvariables(v3.0)
哪个Windows Shell命令会在标准输出上打印文件内容(如Linux中的cat)?
Cygwin错误:“child_info_fork :: abort:加载到不同的地址:”
删除shell脚本中的分支,以便在Cygwin中运行良好
如何在solaris下使用spawn和sftp捕获expect输出
来自IShellFolder的图标索引
获取shell命名空间中的对象信息的一般解决scheme来自于使用您在shell命名空间中表示项目的方式:
IShellFolder : 东西所在的文件夹,以及
子PIDL :该文件夹中的东西的ID
从这里可以得到系统映像列表索引 :
Int32 GetIconIndex(IShellFolder folder,PITEMID_CHILD childPidl) { //Note: I actually have no idea how to do this. }
但是IShellFolder出来了; 我们现在正在使用IShellItem
从Windows Vista开始, IShellItem成为用于导航shell 的首选AP我。 不得不保持一个IShellFolder + pidl对的Windows 95时代的API 是麻烦的,并且容易出错 。
问题就变成了:如何用它做东西? 特别是,我如何获得项目的系统图像列表中的图像索引? 看看它的方法,甚至没有办法得到它的绝对pidl:
BindToHandler :绑定到由处理程序ID值(BHID)指定的项目的处理程序。
比较 :比较两个IShellItem对象。
GetAttributes :获取一组请求的IShellItem对象的属性。
GetdisplayName :获取IShellItem对象的显示名称。
GetParent :获取一个IShellItem对象的父对象。
我希望可以通过IShellItem2访问的Windows属性系统将有一个与shell imagelist图标索引关联的属性。 不幸的是,我没有看到任何:
System.DescriptionID
system.infoTipText
system.internalName
System.Link.TargetSFGAOFlagsstrings
System.Link.TargetUrl
System.NamespaceCLSID
System.Shell.SFGAOFlagsstrings
在Windows Shell命名空间中有许多标准的获取图片的方法 :
IExtractIcon 。 返回一个HICON 。 需要IShellFolder + pidl。 如果失败,可以使用SHDefExtractIcon
SHDefExtractIcon 。 返回一个HICON 。 需要图标文件的完整path
IThumbnailCache 。 需要IShellItem 。 返回缩略图,而不是图标
IShellImageFactory 。 获取一个表示一个IShellItem的位图
IThumbnailProvider 。 Windows Vistareplace为IExtractimage
IExtractimage 。 需要IShellFolder + pidl 。
SHGetFileInfo 。 需要完整的文件path,或绝对pidl
他们都不是:
采取一个IShellItem
返回一个索引
使用PHP执行unix shell命令
Cgywin .sh文件作为Windows任务计划程序运行
如何在java中编写运行使用cygwin在Windows环境内使用rSync的unix shell脚本?
在Bash中划分一个数字
基本上,这似乎没有任何简单的方法。 它只是没有在API中提供。
在你的问题中,你会说“但是shell支持除文件系统中的文件和文件夹之外的东西。” ,这让我觉得你忽略了SHGetFileInfo实际上直接支持使用SHGFI_PIDL (带有SHGFI_PIDL标志) – 所以它可以在非文件系统对象上使用。 如果你仍然有完整的PIDL,这是得到一个图标索引的最简单的方法,否则像这样的事情应该有希望的工作:
int GetIShellItemSysIconIndex(IShellItem* psi) { PIDLIST_ABSOLUTE pidl; int iIndex = -1; if (SUCCEEDED(SHGetIDListFromObject(psi,&pidl))) { SHFILEINFO sfi{}; if (SHGetFileInfo(reinterpret_cast<LPCTSTR>(pidl),SHGFI_PIDL | SHGFI_SYSICONINDEX)) iIndex = sfi.iIcon; CoTaskMemFree(pidl); } return iIndex; }
或者使用雷蒙德的建议:
int GetIconIndex(IShellItem item) { Int32 imageIndex; PIDLIST_ABSOLUTE parent; IShellFolder folder; PITEMID_CHILD child; //Use IParentAndItem to have the ShellItem //cough up the IShellObject and child pidl it is wrapping. (item as IParentAndItem).GetParentAndItem(out parent,out folder,out child); try { //Now use IShellIcon to get the icon index from the folder and child (folder as IShellIcon).GetIconOf(child,GIL_FORSHELL,out imageIndex); } finally { CoTaskMemFree(parent); CoTaskMemFree(child); } return imageIndex; }
原来, IShellFolder有时不支持IShellIcon 。 例如试图浏览一个zip文件。 发生这种情况时, IShellIcon的IShellFolder的QueryInterface失败。
shellFolder.QueryInterface(IID_IShellIcon,out shellIcon); //<--fails with E_NOINTERFACE
然而SHGetFileInfo知道如何处理它。
所以最好不要尝试自己获得一个IShellIcon接口。 将重任留给SHGetFileInfo (至少直到微软的某个人文档如何使用IShellIcon )。
在你的伟大的调查中,你忘记了IShellIcon接口。 它甚至可以在Windows XP中使用。
function GetIconIndex(AFolder: IShellFolder; AChild: PItemIDList): Integer; overload; var ShellIcon: IShellIcon; R: HRESULT; begin OleCheck(AFolder.QueryInterface(IShellIcon,ShellIcon)); try R := ShellIcon.GetIconOf(AChild,Result); case R of S_OK:; S_FALSE: Result := -1; // icon can not be obtained for this object else OleCheck(R); end; finally ShellIcon := nil; end; end;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。