ExtractIcon和ExtractAssociatedIcon之间的区别?需要提取特定大小的图标 [英] Difference between ExtractIcon and ExtractAssociatedIcon? Need to extract icon of specific size

查看:3574
本文介绍了ExtractIcon和ExtractAssociatedIcon之间的区别?需要提取特定大小的图标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说,如果我想从一个股票Windows可执行文件中提取一个图标。我可以通过在Visual Studio中打开它来获取该图标ID:

Say, if I want to extract an icon out of a stock Windows executable. I can get that icon ID by opening it in Visual Studio:

然后,我会对48x48尺寸的图标感兴趣:

Then I'll be interested in a 48x48 size icon:

所以我的假设是:

HICON hIcons[4];
::ExtractIconEx(L"mstsc.exe", -13011, hIcons, NULL, 4);
hIconLogo = hIcons[3];

但是当我运行它时,该方法只返回3个图标:

but when I run it, the method returns only 3 icons:

,其中只有一个是我需要的32x32版本。

and only one of them is a 32x32 version of what I need.

然后我找到 ExtractAssociatedIconEx API,我这样调用:

I then found ExtractAssociatedIconEx API that I called as such:

WORD wIcnId = -13011;
WORD wIcnInd = 3;
hIconLogo = ::ExtractAssociatedIconEx(hInst, L"mstsc.exe", &wIcnInd, &wIcnId);

但是这也给我一些我没想到的其他图标。

but that too gives me some other icon that I did not expect.

那么这两个API有什么区别呢?

So what is the difference between those two APIs? And what am I doing wrong?

推荐答案

ExtractIconEx 函数只能返回两种尺寸图标:大和小。这些是相对大小,由环境定义。 大图标通常为32x32像素,但在某些系统配置上可能较大。 小图标通常为16x16像素,但适用相同的警告。唯一的保证是,一个小图标,好,小于一个大图标。如果您想了解系统上的实际大小,请调用 GetSystemMetrics 函数 SM_CXICON SM_CYICON 大图标,或者小图标的 SM_CXSMICON SM_CYSMICON

The ExtractIconEx function can return only two sizes of icons: large and small. Those are relative sizes, defined by the environment. A "large" icon is classically 32x32 pixels, but may be larger on certain system configurations. A "small" icon is classically 16x16 pixels, but the same caveat applies. The only guarantee is that a "small" icon is, well, smaller than a "large" icon. If you want to know the actual size on your system, you call the GetSystemMetrics function with SM_CXICON and SM_CYICON for "large" icons, or SM_CXSMICON and SM_CYSMICON for "small" icons.

操作系统在内部使用小和大图标;大多数API仅处理小和大(也偶尔被称为大图标)。当您为窗口设置图标时,例如,您可以设置小图标或大图标。

The operating system uses "small" and "large" icons everywhere internally; most of the APIs deal only with "small" and "large" (also occasionally known as "big" icons). When you set an icon for a window, for example, you set either a "small" icon or a "big" icon. Those are your only two choices.

ExtractIconEx 函数设置 phIconLarge 参数指向大图标句柄数组的指针。 phIconSmall 参数设置为指向小图标的句柄数组的指针。由于您为 phIconSmall 参数传递 NULL ,因此您没有获得任何小图标。 hIcons 填充文件中大图标的句柄,在系统上,它们是32x32图标的不同位深度。

The ExtractIconEx function sets the phIconLarge parameter to a pointer to an array of handles to large icons. The phIconSmall parameter is set to a pointer to an array of handles to small icons. Since you passed NULL for the phIconSmall parameter, you didn't get any small icons. hIcons filled with handles to the "large" icons in the file, which, on your system, are different bit-depths of 32x32 icons.

ExtractAssociatedIcon 函数(及其Ex兄)仅返回大图标。所以你应该得到相同的结果,当你调用它的方式,你调用 ExtractIconEx 。我不知道你是不是说它给你个不同的结果。它可能与索引有关。负指数对于 ExtractIconEx 意味着特殊的东西,但我不确定它们是否对 ExtractAssociatedIcon 有效。

The ExtractAssociatedIcon function (and its Ex brother) returns only "large" icons. So you should be getting the same results when you call it as you do for the way that you call ExtractIconEx. I'm not really sure if you're saying that it is giving you different results or not. It might have something to do with the index. Negative indices mean something special to ExtractIconEx, but I'm not sure if they are valid for ExtractAssociatedIcon. The documentation doesn't give much of a hint.

SHGetFileInfo 功能,虽然功能更强大,从任何文件系统对象提取图标的能力具有相同的基本限制:它可以选择 SHGFI_LARGEICON SHGFI_SMALLICON

The SHGetFileInfo function, although more powerful in a number of senses, including the ability to extract icons from any file-system object, has the same fundamental limitation: it gives you choices of SHGFI_LARGEICON and SHGFI_SMALLICON.

如果您需要提取自定义大小的图标(即系统的小 基本上有两个选项:


  1. SHGetImageList 函数,这是另一个shell帮助函数,但检索包含图标的shell图像列表。它为图标大小提供了更多选项: SHIL_SMALL (通常为16x16), SHIL_LARGE (通常为32x32) c $ c> SHIL_EXTRALARGE (通常为48x48)和 SHIL_JUMBO (通常为256x256 - 仅适用于Vista及更高版本)。所以,如果你要求 SHIL_EXTRALARGE ,你会得到你想要的48x48图标。

  1. Call the SHGetImageList function, which is another shell helper function, but one that retrieves a shell image list containing icons. It gives you far more options for icon sizes: SHIL_SMALL (generally 16x16), SHIL_LARGE (generally 32x32), SHIL_EXTRALARGE (generally 48x48), and SHIL_JUMBO (generally 256x256—only on Vista and later). So if you ask for SHIL_EXTRALARGE, you'll get the 48x48 icons that you're looking for.

你仍需要 SHGetFileInfo 这里,但这次它将是检索所需图标的索引在shell镜像列表中。使用 SHGFI_SYSICONINDEX 选项检索

完全未经测试的示例代码,

Completely untested sample code, never touched by a compiler:

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 48x48 icons, we use `SHIL_EXTRALARGE`.)
    IImageList* piml;
    if (SHGetImageList(SHIL_EXTRALARGE, 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;
}


  • 您的其他选项是从文件中提取所需的大小图标自己。虽然图标资源格式是有记录的,并且各种人已经使用这个知识写了一堆丑陋的提取代码并将其发布在互联网上,有一个更简单的方法: SHDefExtractIcon

    作为 Raymond Chen博客一段时间之前, SHDefExtractIcon 是更强大的后备,如果 IExtractIcon :: Extract 是上面的代码示例尝试使用)失败。此函数的功能是它的 nIconSize 参数,它指定要提取的图标的实际大小。

    As Raymond Chen blogged about some time ago, SHDefExtractIcon is your more powerful fallback if IExtractIcon::Extract (which is what the code sample above attempts to use) fails. The power of this function is its nIconSize parameter, which specifies the actual size of the icon that you want to extract.

    修改Raymond的示例:

    Adapting Raymond's example:

    HICON ExtractArbitrarySizeIcon(LPCTSTR pszPath, int size)
    {    
        HICON hIcon;
        if (SHDefExtractIcon(pszPath, 1, 0, &hIcon, NULL, size) == S_OK)
        {
            return hIcon;
        }
        return NULL;  // failure
    }
    


  • 你应该记住,每当一个API函数返回一个HICON,它都会将该资源的所有权转移给你。这意味着,当你完成了图标,你必须通过调用 DestroyIcon 函数,以避免泄漏。

    Whatever you do, remember that whenever an API function returns an HICON, it is transferring ownership of that resource to you. This means that, when you are finished with the icon, you must destroy it by calling the DestroyIcon function to avoid a leak.

    这篇关于ExtractIcon和ExtractAssociatedIcon之间的区别?需要提取特定大小的图标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆