MS-Windows 是否使用未记录的 API 来查找 256x256 图标?

问题描述 投票:0回答:1

MS-Windows 使用什么 API 从

.exe
.dll
文件中的资源查找并加载 256x256px 图标?

我发现记录的 Windows API 无法找到并加载 256x256px 图标。

nSize==256
时见下面的函数:

#pragma pack(push, 1)
typedef struct  _GRPICONDIRENTRY
{
    BYTE  bWidth;
    BYTE  bHeight;
    BYTE  bColorCount;
    BYTE  bReserved;
    WORD  wPlanes;
    WORD  wBitCount;
    DWORD dwBytesInRes;
    WORD  nId;
} GRPICONDIRENTRY, *PGRPICONDIRENTRY;

typedef struct  _GRPICONDIR
{
    WORD idReserved;
    WORD idType;
    WORD idCount;
    GRPICONDIRENTRY idEntries[1];
} GRPICONDIR, * PGRPICONDIR;
#pragma pack(pop)


HICON Dll2Icon(LPCTSTR szFileName, int nSize)
{
    HICON   hIcon = 0;
    HMODULE hMod = LoadLibraryEx( szFileName, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE );       
    HRSRC hResIbIconDir = FindResource(hMod, MAKEINTRESOURCE(42), RT_GROUP_ICON);
    HGLOBAL hResDatIconDir = LoadResource(hMod, hResIbIconDir);
    PGRPICONDIR pIconDir = static_cast<PGRPICONDIR>(LockResource(hResDatIconDir));

    PGRPICONDIRENTRY pEntry;

    for (pEntry = pIconDir->idEntries; pEntry < &(pIconDir->idEntries[pIconDir->idCount]); pEntry++)
    {
        if ( (pEntry->bWidth == nSize) && (pEntry->bHeight == nSize) )
        {
            HRSRC hResIbIcon = FindResource(hMod, MAKEINTRESOURCE(pEntry->nId), RT_ICON);
            HGLOBAL hResDatIcon = LoadResource(hMod, hResIbIcon);
            PBYTE pIcon = static_cast<PBYTE>(LockResource(hResDatIcon));

            hIcon = CreateIconFromResourceEx(pIcon, pEntry->dwBytesInRes, TRUE, 0x00030000, 0, 0, LR_DEFAULTCOLOR);
            FreeResource(hResDatIcon);
            break;
        }
    }
    FreeResource(hResDatIconDir);
    FreeLibrary(hMod);
    return hIcon;
}

上面列出的函数对于 256x256px 图标图像失败但成功找到 255x255px 图标的原因是字段

GRPICONDIRENTRY.bWidth
GRPICONDIRENTRY.bHeight
的宽度,它们是字节大小的,因此无法容纳数字 256。

Windows 使用什么 API 来查找此类图标分辨率?

根据本文,MS-Windows从Windows Vista开始支持256x256像素图标,如果您选择

View->Extra large icons
中的菜单
Windows Explorer
,则
.dll
.exe
中的256x256图标将毫无问题地显示文件,但不适用于
.ico
文件(已在 Windows 7 上验证)。

enter image description here

在这里您可以找到所有图标分辨率从8x8px到256x256px的资源文件。

c winapi
1个回答
0
投票

Windows 使用什么 API 来查找此类图标分辨率?

我不知道。我相信无论调用哪个 API 都知道如何解释图标资源。

根据这篇文章,自 Windows Vista 起,MS-Windows 支持 256x256 像素图标。

我没有找到任何证据支持这一说法。 Windows 95 中引入了对任一维度 256 像素的支持。在他关于 ICO 文件格式演变的第一部分(单色开始)中,Raymond Chen 解释道:

bWidth
bHeight
是图像的尺寸。最初,支持的范围是 1 到 255,但从 Windows 95(和 Windows NT 4)开始,值 0 被接受为表示宽度或高度 256

我不知道这是否(或曾经)准确。更灵活的演化方案肯定是值 0 表示:“忽略该值”。由于无论如何都存在冗余(

RT_ICON
资源以
BITMAPINFOHEADER
开头,除非它是PNG图像),可以实现资源读取器,忽略值0并从
RT_ICON
资源中提取尺寸信息。

无论如何,不需要任何未记录的秘密 API 来支持 256x256px 图标。由于所有 API(无论是直接还是间接)都没有重复将宽度和高度编码为 8 位值的错误,因此所有 API 都不受 ICO 文件格式演变的影响,ICO 文件格式演变选择了未使用的值 (0) 来表示其他含义。

但是,由于正在使用未记录的文件/资源格式内部结构,因此您的代码现在必须了解这些内部结构。具体来说,您的

Dll2Icon
实现需要对图标目录条目提供特殊处理,其中
bWidth
和/或
bHeight
成员报告值为 0。

© www.soinside.com 2019 - 2024. All rights reserved.