使用Win32 API找出图标资源中的图标数量 [英] Find out number of icons in an icon resource using Win32 API

查看:133
本文介绍了使用Win32 API找出图标资源中的图标数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 *.ico 文件,其中包含多个大小不同的图标,这些图标链接到我的可执行文件作为资源.我使用此资源将应用程序的图标设置为RegisterClassEx(),即:

I have an *.ico file that contains multiple icons in different sizes linked to my executable as a resource. I use this resource to set my application's icon with RegisterClassEx(), i.e.:

wcx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));

除此之外,我还想将此资源中的所有单个图标转换为ARGB像素阵列.通过在GetIconInfo()返回的位图上使用GetDIBits(),这应该是可能的.

In addition to that, I'd also like to convert all the single icons in this resource to ARGB pixel arrays. This should be possible by using GetDIBits() on the bitmap returned by GetIconInfo().

但是,存在一个问题:我需要找出LoadIcon()返回的HICON句柄中的图标数量以及它们的大小.我似乎没有找到带有HICON句柄并告诉我实际上有多少个图标以及它们的大小的API.

However, there is one problem: I need to find out the number of icons in the HICON handle returned by LoadIcon() as well as their sizes. I do not seem to find an API that takes a HICON handle and tells me how many icons there are actually in there and what their sizes are.

这是否可能以某种方式出现?还是我需要努力分析自己的 *.ico 资源?

Is this possible somehow or do I need to go the hard way and parse the *.ico resource myself?

推荐答案

原始图标处理功能很古老.它们是在16位Windows中引入的,并且是为仅定义一个图标大小的系统而设计的.因此,大多数这些功能都没有意识到超过一个图标大小的可能性.要获取资源中大小不同的图标,需要进行额外的工作.

The original icon handling functions are ancient. They were introduced in 16-bit Windows and designed for a system that defined only one icon size. Therefore, most of those functions are unaware of the possibility of more than one icon size. To get to the differently sized icons in a resource additional work is required.

根据ICO文件格式,包括图标目录和实际图标图像,图标资源也包括两部分:类型为RT_GROUP_ICON的图标目录和各个图标(RT_ICON).该目录由以下结构表示:

Following the ICO file format, consisting of an icon directory and the actual icon images, an icon resource consists of two parts as well: The icon directory of type RT_GROUP_ICON and the individual icons (RT_ICON). The directory is represented by the following structures:

#pragma pack( push )
#pragma pack( 2 )
typedef struct 
{
    WORD            idReserved;   // Reserved (must be 0)
    WORD            idType;       // Resource type (1 for icons)
    WORD            idCount;      // How many images?
    GRPICONDIRENTRY idEntries[1]; // The entries for each image
} GRPICONDIR, *LPGRPICONDIR;
#pragma pack( pop )

#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
    BYTE   bWidth;               // Width, in pixels, of the image
    BYTE   bHeight;              // Height, in pixels, of the image
    BYTE   bColorCount;          // Number of colors in image (0 if >=8bpp)
    BYTE   bReserved;            // Reserved
    WORD   wPlanes;              // Color Planes
    WORD   wBitCount;            // Bits per pixel
    DWORD  dwBytesInRes;         // how many bytes in this resource?
    WORD   nID;                  // the ID
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;
#pragma pack( pop )

可以使用以下代码来检索图标组ID的图标目录:

The icon directory for an icon group ID can be retrieved using the following code:

typedef std::list<GRPICONDIRENTRY> IconDirectory;

IconDirectory GetIconDirectory( HMODULE hMod, WORD Id ) {
    HRSRC hRsrc = FindResourceW( hMod, MAKEINTRESOURCE( Id ), RT_GROUP_ICON );
    HGLOBAL hGlobal = LoadResource( hMod, hRsrc );
    GRPICONDIR* lpGrpIconDir = (GRPICONDIR*)LockResource( hGlobal );

    IconDirectory dir;
    for ( size_t i = 0; i < lpGrpIconDir->idCount; ++i ) {
        dir.push_back( lpGrpIconDir->idEntries[ i ] );
    }
    return dir;
}

利用图标目录中的信息,可以使用以下代码构建各个图标:

With the information from the icon directory the individual icons can be constructed with this code:

HICON LoadSpecificIcon( HMODULE hMod, WORD Id ) {
    HRSRC hRsrc = FindResourceW( hMod, MAKEINTRESOURCE( Id ), RT_ICON );
    HGLOBAL hGlobal = LoadResource( hMod, hRsrc );
    BYTE* lpData = (BYTE*)LockResource( hGlobal );
    DWORD dwSize = SizeofResource( hMod, hRsrc );

    HICON hIcon = CreateIconFromResourceEx( lpData, dwSize, TRUE, 0x00030000,
                                            0, 0, LR_DEFAULTCOLOR );
    return hIcon;
}

将所有片段放在一起,以下内容将explorer.exe作为资源文件加载,检索ID为101的第一个图标组,并从图标目录中为每个条目打印信息.然后,它创建各个图标并输出xHotspotyHotspot数据.对于图标,热点位于中心:

Putting all the pieces together, the following loads explorer.exe as a resource file, retrieves the first icon group with ID 101 and prints the information from the icon directory for each entry. It then creates the individual icons and outputs the xHotspot and yHotspot data. For icons, the hotspot is located in the center:

void PrintIconDirEntry( const GRPICONDIRENTRY& DirEntry ) {
    _wprintf_p( L"ID: %04d; width=%02d; height=%02d; bpp=%02d\n",
                DirEntry.nID,
                DirEntry.bWidth, DirEntry.bHeight, DirEntry.wBitCount );
}

void PrintIconInfo( HICON hIcon ) {
    ICONINFO ii = { 0 };
    GetIconInfo( hIcon, &ii );
    _wprintf_p( L"xHotspot=%02d; yHotspot=%02d\n", ii.xHotspot, ii.yHotspot );
}

typedef std::list<GRPICONDIRENTRY>::const_iterator IconDirectoryCIt;

int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE hMod = LoadLibraryExW( L"C:\\Windows\\system32\\explorer.exe",
                                   NULL, LOAD_LIBRARY_AS_IMAGE_RESOURCE );
    IconDirectory dir = GetIconDirectory( hMod, 101 );
    for ( IconDirectoryCIt it = dir.begin(); it != dir.end(); ++it ) {
        PrintIconDirEntry( *it );
        HICON hIcon = LoadSpecificIcon( hMod, it->nID );
        PrintIconInfo( hIcon );
        DestroyIcon( hIcon );
    }
    return 0;
}

总结一下:检索图标资源的所有图标大小和颜色变化涉及两个步骤:

To sum this up: Retrieving all icon sizes and color variations for an icon resources involves two steps:

  1. 使用图标组中所有图标的信息检索图标目录.
  2. 遍历图标目录,并使用参考文献:

    • MSDN documentation for the icon format: Icons
    • The Old New Thing: The evolution of the ICO file format, part 1: Monochrome beginnings
    • The Old New Thing: The evolution of the ICO file format, part 2: Now in color!
    • The Old New Thing: The evolution of the ICO file format, part 3: Alpha-blended images
    • The Old New Thing: The evolution of the ICO file format, part 4: PNG images
    • The Old New Thing: The format of icon resources
    • The Old New Thing: How do I override the default icon selection algorithm?

    这篇关于使用Win32 API找出图标资源中的图标数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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