And*_*eas 5 windows winapi gdi
我有一个*.ico文件,其中包含多个不同大小的图标,这些图标链接到我的可执行文件作为资源.我用这个资源设置我的应用程序的图标RegisterClassEx(),即:
wcx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
Run Code Online (Sandbox Code Playgroud)
除此之外,我还想将此资源中的所有单个图标转换为ARGB像素数组.这应该可以通过使用GetDIBits()返回的位图来实现GetIconInfo().
但是,有一个问题:我需要找出HICON返回的句柄中的图标数量LoadIcon()以及它们的大小.我似乎没有找到一个可以HICON处理的API,并告诉我实际上有多少个图标以及它们的大小.
这可能是某种方式,还是我需要努力工作并自己解析*.ico资源?
IIn*_*ble 19
原始图标处理功能很古老.它们是在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 )
Run Code Online (Sandbox Code Playgroud)
和
#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 )
Run Code Online (Sandbox Code Playgroud)
可以使用以下代码检索图标组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;
}
Run Code Online (Sandbox Code Playgroud)
使用图标目录中的信息,可以使用以下代码构建各个图标:
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;
}
Run Code Online (Sandbox Code Playgroud)
将所有部分放在一起,以下加载explorer.exe为资源文件,检索带有ID的第一个图标组,101并从每个条目的图标目录中打印信息.然后它创建单个图标并输出xHotspot和yHotspot数据.对于图标,热点位于中心:
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;
}
Run Code Online (Sandbox Code Playgroud)
总结一下:检索图标资源的所有图标大小和颜色变化包括两个步骤:
CreateIconFromResourceEx.参考文献:
| 归档时间: |
|
| 查看次数: |
1957 次 |
| 最近记录: |