加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows – 使用Win32 API查找图标资源中的图标数量

发布时间:2020-12-14 02:19:40 所属栏目:Windows 来源:网络整理
导读:我有一个* .ico文件,其中包含多个不同大小的图标,这些图标链接到我的可执行文件作为资源.我使用这个资源用RegisterClassEx()设置我的应用程序的图标,即: wcx.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1)); 除此之外,我还想将此资源中的所有单个
我有一个* .ico文件,其中包含多个不同大小的图标,这些图标链接到我的可执行文件作为资源.我使用这个资源用RegisterClassEx()设置我的应用程序的图标,即:

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

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

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

这可能是某种方式,还是我需要努力工作并自己解析* .ico资源?

解决方法

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

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

#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,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的图标目录:

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;
}

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

HICON LoadSpecificIcon( HMODULE hMod,RT_ICON );
    HGLOBAL hGlobal = LoadResource( hMod,hRsrc );
    BYTE* lpData = (BYTE*)LockResource( hGlobal );
    DWORD dwSize = SizeofResource( hMod,hRsrc );

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

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

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

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

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

int _tmain(int argc,_TCHAR* argv[])
{
    HMODULE hMod = LoadLibraryExW( L"C:Windowssystem32explorer.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;
}

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

>检索图标目录,其中包含图标组中所有图标的信息.
>迭代图标目录并使用CreateIconFromResourceEx构建单个图标.

参考文献:

>图标格式的MSDN文档:Icons
>旧的新事物:The evolution of the ICO file format,part 1: Monochrome beginnings
>旧的新事物:The evolution of the ICO file format,part 2: Now in color!
>旧的新事物:The evolution of the ICO file format,part 3: Alpha-blended images
>旧的新事物:The evolution of the ICO file format,part 4: PNG images
>旧的新事物:The format of icon resources
>旧的新事物:How do I override the default icon selection algorithm?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读