【问题标题】:File icons blurry when loaded with an icon handler shell extension加载图标处理程序外壳扩展时文件图标模糊
【发布时间】:2019-07-10 09:24:09
【问题描述】:

我有一个带有图标处理程序的外壳扩展程序,它根据文件内容将文件类型的图标设置为绿色或红色图标。这些图标似乎可以正常工作,只是在使用大图标时它们真的很模糊,就好像它们是从一个非常小的尺寸放大的一样。图标.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());
[12376] phicon_large size:
[12376] 256
[12376] Icon size:
[12376] 256
[12376] phicon_small size:
[12376] 16
[12376] Icon size:
[12376] 16

【问题讨论】:

  • GetIconInfoEx检查你从LoadImage得到的图标,看看它的大小是否正确。
  • 谢谢,我检查了这个,加载图像的大小似乎也正确。
  • 不确定这是否适用于此,但值得一看:How do I override the default icon selection algorithm?
  • 接下来要尝试的事情:向 16x16 图标添加一些内容,以确保它不是用作大图标的那个图标。如果这没有帮助,请尝试对每个资源使用单个图标图像大小(HICON 可以包含链接回加载它的文件的秘密信息)。
  • 最初传递给 GetIconLocation (u_flags) 的标志是什么?

标签: winapi shell-extensions


【解决方案1】:

我从过去的documents看到过这种信息。我现在不能保证这些信息是准确的。

n图标大小

表示所需的图标大小。最高的词是 尺寸(高度和宽度,因为它们总是相同的) 的小图标,低字保存的尺寸 大图标。一般情况下,小图标大小会 16. 大图标通常为 32 或 48,具体取决于 Explorer 所处的视图模式 - 大图标模式为 32,平铺模式为 48。

看来IExtract IconA:: Extract只能提取标准尺寸的图标。

另一方面,请参考Raymond Chen的old thing

如果您要求 IExtractIcon::Extract 在特定位置提取图标 大小,函数可以返回 S_FALSE。ExtractIcon 和 ExtractIconEx 函数不允许你 指定自定义尺寸, 并且 LoadImage 不适用于图标索引 (仅限资源 ID)。

因此,如果您需要提取自定义尺寸的图标(即系统“小”和“大”尺寸以外的图标),则需要做更多的工作。

调用SHGetImageList 函数,这是另一个shell 辅助函数,但它检索包含图标的shell 图像列表。它为您提供了更多图标大小选项:SHIL_SMALL(通常为 16x16)、SHIL_LARGE(通常为 32x32)、SHIL_EXTRALARGE(通常为 48x48)和SHIL_JUMBO(通常为 256x256,仅适用于 Vista 及更高版本)。因此,如果您请求 SHIL_EXTRALARGE,您将获得所需的 48x48 图标。

这里你仍然需要SHGetFileInfo 函数,但是这一次它将在shell 图像列表中检索所需图标的索引。使用 SHGFI_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;
}

更多详情,请参考:

Difference between ExtractIcon and ExtractAssociatedIcon? Need to extract icon of specific size

Extract high resolution icon or thumbnail for file

更新:

无意中发现了这样一个post,可能是通过指定宽/高,去掉LR_DEFAULTSIZE。此外,您必须在DrawIconEx 之后调用DestroyIcon,否则会导致资源泄漏。要么在堆上创建HICON,以便它只创建一次。

【讨论】:

  • 我认为 SHGetFileInfo 只是调用了 IExtractIcon 和相关接口。
猜你喜欢
  • 1970-01-01
  • 2017-01-05
  • 1970-01-01
  • 2019-10-06
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
  • 2014-01-25
  • 2016-09-22
相关资源
最近更新 更多