【问题标题】:I can't get SHGetFileInfo to return an icon location我无法让 SHGetFileInfo 返回图标位置
【发布时间】:2017-03-08 16:07:27
【问题描述】:

我使用的是 Windows 10 Pro 和 Visual Studio 2013,我正在使用 SHGetFileInfoW 获取文件类型的图标位置(路径 + 索引):

std::wstring wFile { L"a.bas" };
SHFILEINFOW fi {};    
DWORD success = ::SHGetFileInfoW(wFile.c_str(), 
                                 FILE_ATTRIBUTE_NORMAL, 
                                 &fi, 
                                 sizeof(fi),
                                 SHGFI_USEFILEATTRIBUTES | SHGFI_ICONLOCATION);

无论wFile 是指现有文件还是只是任何文件名,调用都会返回1 表示成功。 fiiIcon 成员设置为一个数字,但 szDisplayString 为空。不仅驱动器号被\0 覆盖(就像here 发生的那样),而且它完全被\0 填充。

Microsoft 建议使用 IExtractIcon::GetIconLocation 作为替代方案,但我需要获取不在本地文件系统上的文件的图标,因此我无法获取将获取的 IShellInfo 对象我这个接口指针。

另一方面,获取图标句柄是可行的。这个功能是错误的还是我做错了什么?有解决办法吗?

【问题讨论】:

  • @Ðаn bas 甚至不返回索引,.bas 就像 a.bas 一样工作并返回索引,但不返回路径。那里的文档似乎很草率。
  • @Ðаn 图标不是通常存储在相关的可执行文件中吗(.pdf = Acrobat Reader、.7z = 7zip 等)?我认为这种方法至少应该适用于某些扩展(我已经尝试了很多)。我认为 Windows 10 中可能发生了一些变化,但后来我发现 this question 从 2013 年开始......没有任何答案。
  • 为什么需要图标位置?只需使用 SHGFI_ICON 标志,让系统为您提供图标句柄和系统图标列表的索引。如果您想自己在系统映像列表中查找图标,请使用 SHGFI_SYSICONINDEX。
  • 图标通常不存储在其关联的可执行文件中” - 有时,但并非总是如此。

标签: c++ winapi windows-10


【解决方案1】:

图标可以动态生成,并且可能不会暴露其图像的路径。图标处理程序通过在其IExtractIcon::GetIconLocation 实现中设置GIL_NOTFILENAME 标志将其传达给shell。如果设置了GIL_SIMULATEDOC,shell 通常还必须动态生成一个图标。

如果您调用 SHGetFileInfo 并设置了 SHGFI_SELECTED 标志,那么无论您要求哪种文件类型,函数都可能必须生成一个新图标。

如果您在 ListView/TreeView 中显示文件列表,则通常使用 SHGFI_SYSICONINDEX|SHGFI_SHELLICONSIZE|SHGFI_SMALLICON 并使用系统图像列表。

如果您需要 HICON,请使用 SHGFI_ICON

如果指定了SHGFI_ICONLOCATION,则SHGetFileInfo 使用IExtractIcon:

检索包含表示由 pszPath 指定的文件的图标的文件的名称,由文件的图标处理程序的 IExtractIcon::GetIconLocation 方法返回。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-26
    相关资源
    最近更新 更多