ExtractIcon和ExtractAssociatedIcon之间的区别?需要提取特定大小的图标 [英] Difference between ExtractIcon and ExtractAssociatedIcon? Need to extract icon of specific size
问题描述
说,如果我想从一个股票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
.
如果您需要提取自定义大小的图标(即系统的小 基本上有两个选项:
-
SHGetImageList
函数,这是另一个shell帮助函数,但检索包含图标的shell图像列表。它为图标大小提供了更多选项:SHIL_SMALL
(通常为16x16),SHIL_LARGE
(通常为32x32) c $ c> SHIL_EXTRALARGE (通常为48x48)和SHIL_JUMBO
(通常为256x256 - 仅适用于Vista及更高版本)。所以,如果你要求SHIL_EXTRALARGE
,你会得到你想要的48x48图标。
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), andSHIL_JUMBO
(generally 256x256—only on Vista and later). So if you ask forSHIL_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屋!