Winapi 加载图标处理程序外壳扩展时,文件图标模糊
我有一个带有图标处理程序的shell扩展,它根据文件内容将文件类型的图标设置为绿色或红色图标。图标似乎工作正常,只是当使用大图标时,它们非常模糊,好像它们是从非常小的尺寸放大的。图标Winapi 加载图标处理程序外壳扩展时,文件图标模糊,winapi,shell-extensions,Winapi,Shell Extensions,我有一个带有图标处理程序的shell扩展,它根据文件内容将文件类型的图标设置为绿色或红色图标。图标似乎工作正常,只是当使用大图标时,它们非常模糊,好像它们是从非常小的尺寸放大的。图标.ico文件包含从256x256到16x16的所有图像大小 我使用的是一个非常基本的图标处理程序,但可能缓存还是有问题。如何确保图标已正确加载 HRESULT icon_handler::GetIconLocation(UINT u_flags, PWSTR psz_icon_file, UINT cch_max,
.ico
文件包含从256x256到16x16的所有图像大小
我使用的是一个非常基本的图标处理程序,但可能缓存还是有问题。如何确保图标已正确加载
HRESULT icon_handler::GetIconLocation(UINT u_flags, PWSTR psz_icon_file, UINT cch_max, int* pi_index, UINT* pw_flags)
{
*pw_flags = GIL_NOTFILENAME | GIL_DONTCACHE;
return S_OK;
}
HRESULT icon_handler::Extract(PCWSTR psz_file, UINT n_icon_index, HICON* phicon_large, HICON* phicon_small, UINT n_icon_size)
{
int icon = ICON_GREEN;
if (m_icon_color_ == 1) {
icon = ICON_RED;
}
if (phicon_large != nullptr)
{
const int large_size = LOWORD(n_icon_size);
*phicon_large = HICON(LoadImageW(global_h_instance, MAKEINTRESOURCE(icon), IMAGE_ICON, large_size, large_size,
LR_DEFAULTCOLOR));
}
if (phicon_small != nullptr)
{
const int small_size = HIWORD(n_icon_size);
*phicon_small = HICON(LoadImageW(global_h_instance, MAKEINTRESOURCE(icon), IMAGE_ICON, small_size, small_size,
LR_DEFAULTCOLOR));
}
return S_OK;
}
使用DebugView登录时,图标处理程序会显示为请求适当的大小:
[30100] phicon_large size:
[30100] 256
[30100] phicon_small size:
[30100] 16
编辑:
根据@Anders的说法,如果我检查加载了LoadImage
的图像的大小,它似乎也是正确的:
*phicon_large = HICON(LoadImageW(global_h_instance, MAKEINTRESOURCE(icon), IMAGE_ICON, large_size, large_size,
LR_DEFAULTCOLOR));
ICONINFOEXW info = {sizeof(ICONINFOEXW)};
GetIconInfoEx(*phicon_large, &info)
BITMAP bmp;
GetObjectW(info.hbmMask, sizeof(BITMAP), &bmp);
OutputDebugStringW(L"Icon size:");
OutputDebugStringW(std::to_wstring(bmp.bmWidth).c_str());
我以前见过这种信息。我现在不能保证这些信息是准确的 尼科西 指示图标的所需大小。高调的词是 尺寸(高度和宽度,因为它们始终相同) 小图标的尺寸,低字表示小图标的尺寸 大图标。在正常情况下,小图标的大小将是 16大图标通常为32或48,这取决于浏览器的视图模式,对于大图标模式为-32,对于平铺模式为48 似乎
IExtract IconA::Extract
只能提取标准尺寸的图标
另一方面,参考Raymond Chen的
如果您要求IExtract-Icon::Extract在特定位置提取图标
大小,函数可以返回S_FALSE。提取图标和
Extract-Icon-Ex函数不允许
指定自定义大小,
加载图像与图标索引不兼容
(仅限资源ID)
因此,如果您需要提取自定义大小的图标(即系统的“小”和“大”尺寸以外的图标),则需要做更多的工作
调用该函数,该函数是另一个shell助手函数,但用于检索包含图标的shell图像列表。它为图标大小提供了更多选项:SHIL_SMALL
(通常为16x16)、SHIL_LARGE
(通常为32x32)、SHIL_超大
(通常为48x48)和SHIL_JUMBO
(通常为256x256,仅在Vista和更高版本上使用)。因此,如果您要求使用超大型的SHIL_,您将获得所需的48x48图标
这里仍然需要该函数,但这次将检索shell图像列表中所需图标的索引。使用SHGFI\u SYSICONINDEX
选项检索
完全未经测试的示例代码,编译器从未接触过:
HICON ExtractExtraLargeIcon(LPCTSTR pszPath)
{
// Determine the index of the desired icon
// in the system image list.
SHGETFILEINFO sfi;
SHGetFileInfo(pszPath, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX);
// Retrieve the system image list.
// (To get 256x256 icons, we use `SHIL_JUMBO`.)
IImageList* piml;
if (SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&piml) == S_OK)
{
HICON hIcon;
if (piml->GetIcon(sfi.iIcon, ILD_TRANSPARENT, &hIcon) == S_OK)
{
return hIcon;
}
}
// Oops! We failed.
return NULL;
}
有关详情,请参阅:
更新:
我意外地发现了这样一个,可能是通过指定宽度/高度,删除了
LR\u DEFAULTSIZE
。另外,您必须在DrawIconEx
之后调用destroycon
,否则会导致资源泄漏。或者在堆上创建HICON
,以便只创建一次。使用geticonnifoex
检查从LoadImage
获得的图标,看看它的大小是否正确。谢谢,我检查了这个,加载的图像的大小似乎也正确。不确定这是否适用于这里,但值得一看:下一步尝试:在16x16图标中添加一些内容,以确保它不是用作大图标的图标。如果这没有帮助,请尝试使用每个资源的单个图标图像大小(HICONs可以包含链接回加载它的文件的机密信息)。最初传递到GetIconLocation的标志是什么(u_标志)?我认为SHGetFileInfo只调用IExtractCon和相关接口。
HICON ExtractExtraLargeIcon(LPCTSTR pszPath)
{
// Determine the index of the desired icon
// in the system image list.
SHGETFILEINFO sfi;
SHGetFileInfo(pszPath, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX);
// Retrieve the system image list.
// (To get 256x256 icons, we use `SHIL_JUMBO`.)
IImageList* piml;
if (SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&piml) == S_OK)
{
HICON hIcon;
if (piml->GetIcon(sfi.iIcon, ILD_TRANSPARENT, &hIcon) == S_OK)
{
return hIcon;
}
}
// Oops! We failed.
return NULL;
}