我正在尝试用于SHGetFileInfo
获取文件和文件夹的图标。我注意到它在一种情况下不起作用:我的用户配置文件文件夹中的 OneDrive 文件夹。在这种情况下,对 SHGetFileInfo 的调用成功,但我得到了可执行文件的默认图标:
这是我调用函数的方式:
HIMAGELIST imageList;
SHFILEINFO shfi;
// Get the path to the OneDrive folder
LPTSTR src = _T("%USERPROFILE%\\OneDrive");
TCHAR dest[MAX_PATH];
ExpandEnvironmentStrings(src, dest, MAX_PATH);
// Load the image from the OneDrive folder
ZeroMemory(&shfi, sizeof(shfi));
imageList = (HIMAGELIST)SHGetFileInfo(
dest,
FILE_ATTRIBUTE_NORMAL,
&shfi,
sizeof(shfi),
SHGFI_ICON | SHGFI_SYSICONINDEX);
这是我绘制图标的方式:
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
ImageList_Draw(imageList, shfi.iIcon, hdc, 0, 0, ILD_NORMAL);
EndPaint(hwnd, &ps);
}
break;
我为 pastebin 上的应用程序制作了一个简短的自包含示例:http : //pastebin.com/bdTvEQT5
在这个简短的自包含示例中,为简洁起见,我省略了任何错误检查代码。此外,为了示例的目的,我对文件夹的位置进行了硬编码。在我的真实应用程序中,我正在枚举文件系统中的文件夹,这就是我获取 OneDrive 文件夹位置的方式。图标提取代码需要与枚举的任何文件夹一起使用。
我究竟做错了什么?
您的代码在 Windows 10 (15031) 上对我来说很好用。你从不使用shfi.hIcon
所以你不需要,SHGFI_ICON
虽然它不会阻止它在我的情况下工作,但你正在泄漏一个图标。
%USERPROFILE%\OneDrive
可能不是 OneDrive 文件夹的位置。当有 shell 函数可以告诉你路径时,千万不要使用环境变量!
您不能假设首先存在 OneDrive 文件夹。如果尚未使用 OneDrive,则 Windows 8.1 上不存在该文件夹,因此您应该处理来自SHGetFileInfo
!
我建议您将代码更改为如下所示:
PIDLIST_ABSOLUTE pidl;
HRESULT hr = SHGetKnownFolderIDList(FOLDERID_SkyDrive, 0, NULL, &pidl); // Note: Change the flags if you want to create the folder if it does not exist
if (SUCCEEDED(hr))
{
imageList = (HIMAGELIST) SHGetFileInfo((LPTSTR) pidl, 0, &shfi, sizeof(shfi), SHGFI_PIDL | SHGFI_SYSICONINDEX);
ILFree(pidl);
}
if (!imageList)
{
// Fall back to a plain folder icon
imageList = (HIMAGELIST) SHGetFileInfo(TEXT("DoesNotMatter"), FILE_ATTRIBUTE_DIRECTORY, &shfi, sizeof(shfi), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
}
我无法解释您所看到的结果,缺少错误检查当然也无济于事。我猜这是其中之一:
CoInitialize
/ 。MSDN确实说您必须这样做,但它似乎不太可能返回正确的图像列表,但返回错误的图标索引。OleInitialize
SHGetFileInfo
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句