我试图为任何文件获取一个图标(如H图标),以与Explorer完全相同的方式绘制它。这意味着,如果我有一个路径到一个exe文件,我应该绘制它的默认图标。如果我有一个链接(.lnk)文件,我必须绘制一个图标,分配给链接(如果有的话),否则它的目标文件图标。
不幸的是,本应返回图标的SHGetFileInfo()不能用于几个链接文件。以下是代码:
SHFILEINFO fi = {0};
::SHGetFileInfo(L"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Windows Mobile Device Center.lnk",
//::SHGetFileInfo(L"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\TortoiseGit\\TortoiseGitMerge.lnk",
0, &fi, sizeof(fi), SHGFI_ICON /*| SHGFI_SMALLICON*/);
CPaintDC dc(this);
dc.DrawIcon(0, 0, fi.hIcon);第一个文件呈现如下(正确):

第二次呈现如下(不正确):

但资源管理器将其呈现如下:

我试过SHGFI_SMALLICON修饰符,但没有用。如何获得这两种情况的图标?或者也许还有其他功能来完成这一任务?
更新
问题是应用程序是x86,操作系统是x64。有什么方法可以不把它分成两个版本呢?
发布于 2014-11-11 05:29:49
您所遇到的问题是32位应用程序在64位Windows上工作的已知问题。System解析器对指向Program目录中的文件的lnk文件不正确地工作。而不是程序文件解析器提取程序文件的x86路径。这就是为什么您尝试提取图标或提取目标名称失败的原因。唯一正确的解决方案是为64位操作系统创建64位版本的应用程序,为32位操作系统创建32位版本。此外,您也可以使用黑客阅读和解析lnk文件与您自己的代码。一些细节:JclShell.ShellLinkResolve gets wrong data另一个“黑客”-使用额外的64位进程来读取lnk文件的图标,但是IMHO是一种不好的方式。
发布于 2014-11-11 01:59:39
如果您确实希望获得与资源管理器相同的行为,则需要使用资源管理器使用的相同的Shell接口,例如IExtractIcon和IExtractImage
检索对象的图标有两种方法。最简单的方法是调用SHGetFileInfo。然而,这一做法是不灵活的,可能是缓慢的。检索项目图标的一个更灵活、更有效的方法是使用IExtractIcon。当显示文件夹的内容时,Shell使用IExtractIcon检索图标。若要使用IExtractIcon检索对象的图标,请执行以下操作:
如果要实现命名空间对象的视图并希望显示缩略图,请使用IExtractImage。您可以使用Shell文件夹的IShellFolder::GetUIObjectOf方法绑定到它的IExtractImage接口。
请记住,Shell中的所有内容都是用PIDL表示的,因此可以通过IShellFolder和相关接口访问。
您可以使用SHParseDisplayName()将路径和文件名转换为绝对PIDL,然后使用SHBindToParent()获取其父文件夹的IShellFolder。
https://stackoverflow.com/questions/26843464
复制相似问题