使用图标
以下主题介绍如何执行与图标相关的某些任务:
创建图标
若要使用图标,应用程序必须获取图标的句柄。 以下示例演示如何创建两个不同的图标句柄:一个用于标准问题图标,另一个用于作为应用程序资源定义文件中的资源包含的自定义图标。
HICON hIcon1; // icon handle
HICON hIcon2; // icon handle
// Create a standard question icon.
hIcon1 = LoadIcon(NULL, IDI_QUESTION);
// Create a custom icon based on a resource.
hIcon2 = LoadIcon(hinst, MAKEINTRESOURCE(460));
// Create a custom icon at run time.
应用程序应实现自定义图标作为资源,并且应使用 LoadIcon 或 LoadImage 函数,而不是在运行时创建图标。 此方法可避免设备依赖、简化本地化,并使应用程序能够共享图标位图。 但是,以下示例使用 CreateIcon 基于位图位掩码在运行时创建自定义单色图标;它用于说明系统如何解释图标位图位掩码。
HICON hIcon3; // icon handle
// Yang icon AND bitmask
BYTE ANDmaskIcon[] = {0xFF, 0xFF, 0xFF, 0xFF, // line 1
0xFF, 0xFF, 0xC3, 0xFF, // line 2
0xFF, 0xFF, 0x00, 0xFF, // line 3
0xFF, 0xFE, 0x00, 0x7F, // line 4
0xFF, 0xFC, 0x00, 0x1F, // line 5
0xFF, 0xF8, 0x00, 0x0F, // line 6
0xFF, 0xF8, 0x00, 0x0F, // line 7
0xFF, 0xF0, 0x00, 0x07, // line 8
0xFF, 0xF0, 0x00, 0x03, // line 9
0xFF, 0xE0, 0x00, 0x03, // line 10
0xFF, 0xE0, 0x00, 0x01, // line 11
0xFF, 0xE0, 0x00, 0x01, // line 12
0xFF, 0xF0, 0x00, 0x01, // line 13
0xFF, 0xF0, 0x00, 0x00, // line 14
0xFF, 0xF8, 0x00, 0x00, // line 15
0xFF, 0xFC, 0x00, 0x00, // line 16
0xFF, 0xFF, 0x00, 0x00, // line 17
0xFF, 0xFF, 0x80, 0x00, // line 18
0xFF, 0xFF, 0xE0, 0x00, // line 19
0xFF, 0xFF, 0xE0, 0x01, // line 20
0xFF, 0xFF, 0xF0, 0x01, // line 21
0xFF, 0xFF, 0xF0, 0x01, // line 22
0xFF, 0xFF, 0xF0, 0x03, // line 23
0xFF, 0xFF, 0xE0, 0x03, // line 24
0xFF, 0xFF, 0xE0, 0x07, // line 25
0xFF, 0xFF, 0xC0, 0x0F, // line 26
0xFF, 0xFF, 0xC0, 0x0F, // line 27
0xFF, 0xFF, 0x80, 0x1F, // line 28
0xFF, 0xFF, 0x00, 0x7F, // line 29
0xFF, 0xFC, 0x00, 0xFF, // line 30
0xFF, 0xF8, 0x03, 0xFF, // line 31
0xFF, 0xFC, 0x3F, 0xFF}; // line 32
// Yang icon XOR bitmask
BYTE XORmaskIcon[] = {0x00, 0x00, 0x00, 0x00, // line 1
0x00, 0x00, 0x00, 0x00, // line 2
0x00, 0x00, 0x00, 0x00, // line 3
0x00, 0x00, 0x00, 0x00, // line 4
0x00, 0x00, 0x00, 0x00, // line 5
0x00, 0x00, 0x00, 0x00, // line 6
0x00, 0x00, 0x00, 0x00, // line 7
0x00, 0x00, 0x38, 0x00, // line 8
0x00, 0x00, 0x7C, 0x00, // line 9
0x00, 0x00, 0x7C, 0x00, // line 10
0x00, 0x00, 0x7C, 0x00, // line 11
0x00, 0x00, 0x38, 0x00, // line 12
0x00, 0x00, 0x00, 0x00, // line 13
0x00, 0x00, 0x00, 0x00, // line 14
0x00, 0x00, 0x00, 0x00, // line 15
0x00, 0x00, 0x00, 0x00, // line 16
0x00, 0x00, 0x00, 0x00, // line 17
0x00, 0x00, 0x00, 0x00, // line 18
0x00, 0x00, 0x00, 0x00, // line 19
0x00, 0x00, 0x00, 0x00, // line 20
0x00, 0x00, 0x00, 0x00, // line 21
0x00, 0x00, 0x00, 0x00, // line 22
0x00, 0x00, 0x00, 0x00, // line 23
0x00, 0x00, 0x00, 0x00, // line 24
0x00, 0x00, 0x00, 0x00, // line 25
0x00, 0x00, 0x00, 0x00, // line 26
0x00, 0x00, 0x00, 0x00, // line 27
0x00, 0x00, 0x00, 0x00, // line 28
0x00, 0x00, 0x00, 0x00, // line 29
0x00, 0x00, 0x00, 0x00, // line 30
0x00, 0x00, 0x00, 0x00, // line 31
0x00, 0x00, 0x00, 0x00}; // line 32
hIcon3 = CreateIcon(hinst, // application instance
32, // icon width
32, // icon height
1, // number of XOR planes
1, // number of bits per pixel
ANDmaskIcon, // AND bitmask
XORmaskIcon); // XOR bitmask
为了创建图标, CreateIcon 将以下事实数据表应用于 AND 和 XOR 位掩码。
AND 位掩码 | XOR 位掩码 | 显示 |
---|---|---|
0 | 0 | 黑色 |
0 | 1 | White |
1 | 0 | 屏幕 |
1 | 1 | 反向屏幕 |
若要在运行时创建彩色图标,必须使用 CreateIconIndirect 函数,该函数基于 ICONINFO 结构的内容创建图标。
在关闭之前,应用程序必须使用 DestroyIcon 销毁它使用 CreateIcon 或 CreateIconIndirect 创建的任何图标。 无需销毁由其他函数创建的图标。
获取图标大小
下面是如何从 HICON 句柄获取图标大小的示例代码:
// Also works for cursors
BOOL GetIconDimensions(__in HICON hico, __out SIZE *psiz)
{
ICONINFO ii;
BOOL fResult = GetIconInfo(hico, &ii);
if (fResult) {
BITMAP bm;
fResult = GetObject(ii.hbmMask, sizeof(bm), &bm) == sizeof(bm);
if (fResult) {
psiz->cx = bm.bmWidth;
psiz->cy = ii.hbmColor ? bm.bmHeight : bm.bmHeight / 2;
}
if (ii.hbmMask) DeleteObject(ii.hbmMask);
if (ii.hbmColor) DeleteObject(ii.hbmColor);
}
return fResult;
}
显示图标
应用程序可以加载并创建图标以显示在应用程序的工作区或子窗口中。 以下示例演示如何在窗口的工作区中绘制图标,其设备上下文 (DC) 由 hdc 参数标识。
HICON hIcon1; // icon handle
HDC hdc; // handle to display context
DrawIcon(hdc, 10, 20, hIcon1);
系统会自动为窗口显示类图标 () 。 应用程序可以在注册窗口类时分配类图标。 应用程序可以使用 SetClassLong 函数替换类图标。 此函数更改给定类的所有窗口的默认窗口设置。 以下示例将类图标替换为其资源标识符为 480 的图标。
HINSTANCE hinst; // handle to current instance
HWND hwnd; // main window handle
// Change the icon for hwnd's window class.
SetClassLongPtr(hwnd, // window handle
GCLP_HICON, // changes icon
(LONG_PTR) LoadIcon(hinst, MAKEINTRESOURCE(480))
);
有关窗口类的详细信息,请参阅 窗口类。
共享图标资源
以下代码使用 函数 CreateIconFromResourceEx、 DrawIcon 和 LookupIconIdFromDirectoryEx 以及多个资源函数基于另一个可执行文件中的图标数据创建图标句柄。 然后,它会在窗口中显示图标。
安全警告: 错误地使用 LoadLibrary 可能会通过加载错误的 DLL 来损害应用程序的安全性。 有关如何使用不同版本的 Windows 正确加载 DLL 的信息,请参阅 LoadLibrary 文档。
HICON hIcon1; // icon handle
HINSTANCE hExe; // handle to loaded .EXE file
HRSRC hResource; // handle to FindResource
HRSRC hMem; // handle to LoadResource
BYTE *lpResource; // pointer to resource data
int nID; // ID of resource that best fits current screen
HDC hdc; // handle to display context
// Load the file from which to copy the icon.
// Note: LoadLibrary should have a fully explicit path.
//
hExe = LoadLibrary("myapp.exe");
if (hExe == NULL)
{
//Error loading module -- fail as securely as possible
return;
}
// Find the icon directory whose identifier is 440.
hResource = FindResource(hExe,
MAKEINTRESOURCE(440),
RT_GROUP_ICON);
// Load and lock the icon directory.
hMem = LoadResource(hExe, hResource);
lpResource = LockResource(hMem);
// Get the identifier of the icon that is most appropriate
// for the video display.
nID = LookupIconIdFromDirectoryEx((PBYTE) lpResource, TRUE,
CXICON, CYICON, LR_DEFAULTCOLOR);
// Find the bits for the nID icon.
hResource = FindResource(hExe,
MAKEINTRESOURCE(nID),
MAKEINTRESOURCE(RT_ICON));
// Load and lock the icon.
hMem = LoadResource(hExe, hResource);
lpResource = LockResource(hMem);
// Create a handle to the icon.
hIcon1 = CreateIconFromResourceEx((PBYTE) lpResource,
SizeofResource(hExe, hResource), TRUE, 0x00030000,
CXICON, CYICON, LR_DEFAULTCOLOR);
// Draw the icon in the client area.
DrawIcon(hdc, 10, 20, hIcon1);