Using Icons
The following topics describe how to perform certain tasks related to icons:
Creating an Icon
To use an icon, your application must get a handle to the icon. The following example shows how to create two different icon handles: one for the standard question icon and one for a custom icon included as a resource in the application's resource-definition file.
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.
An application should implement custom icons as resources and should use the LoadIcon or LoadImage function, rather than create the icons at run-time. This approach avoids device dependence, simplifies localization, and enables applications to share icon bitmaps. However, the following example uses CreateIcon to create a custom monochrome icon at run-time, based on bitmap bitmasks; it is included to illustrate how the system interprets icon bitmap bitmasks.
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
To create the icon, CreateIcon applies the following truth table to the AND and XOR bitmasks.
AND bitmask | XOR bitmask | Display |
---|---|---|
0 | 0 | Black |
0 | 1 | White |
1 | 0 | Screen |
1 | 1 | Reverse screen |
To create a colored icon at run time you must use the CreateIconIndirect function, which creates a icon based on the content of an ICONINFO structure.
Before closing, your application must use DestroyIcon to destroy any icon it created by using CreateIcon or CreateIconIndirect. It is not necessary to destroy icons created by other functions.
Getting the Icon size
Here is example code how to get the icon size from the HICON handle:
// 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;
}
Displaying an Icon
Your application can load and create icons to display in the application's client area or child windows. The following example demonstrates how to draw an icon in the client area of the window whose device context (DC) is identified by the hdc parameter.
HICON hIcon1; // icon handle
HDC hdc; // handle to display context
DrawIcon(hdc, 10, 20, hIcon1);
The system automatically displays the class icon(s) for a window. Your application can assign class icons while registering a window class. Your application can replace a class icon by using the SetClassLong function. This function changes the default window settings for all windows of a given class. The following example replaces a class icon with the icon whose resource identifier is 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))
);
For more information about window classes, see Window Classes.
Sharing Icon Resources
The following code uses the functions CreateIconFromResourceEx, DrawIcon, and LookupIconIdFromDirectoryEx, and several of the resource functions, to create an icon handle based on icon data from another executable file. Then, it displays the icon in a window.
Security Warning: Using LoadLibrary incorrectly can compromise the security of your application by loading the wrong DLL. Refer to the LoadLibrary documentation for information on how to correctly load DLLs with different versions of Windows.
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);