I would like to create 32 bit color icons programmatically using C++ and Win API. For this purpose I use the following code which I found here.
HICON CreateSolidColorIcon(COLORREF iconColor, int width, int height)
{
// Obtain a handle to the screen device context.
HDC hdcScreen = GetDC(NULL);
// Create a memory device context, which we will draw into.
HDC hdcMem = CreateCompatibleDC(hdcScreen);
// Create the bitmap, and select it into the device context for drawing.
HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, width, height);
HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcMem, hbmp);
// Draw your icon.
//
// For this simple example, we're just drawing a solid color rectangle
// in the specified color with the specified dimensions.
HPEN hpen = CreatePen(PS_SOLID, 1, iconColor);
HPEN hpenOld = (HPEN)SelectObject(hdcMem, hpen);
HBRUSH hbrush = CreateSolidBrush(iconColor);
HBRUSH hbrushOld = (HBRUSH)SelectObject(hdcMem, hbrush);
Rectangle(hdcMem, 0, 0, width, height);
SelectObject(hdcMem, hbrushOld);
SelectObject(hdcMem, hpenOld);
DeleteObject(hbrush);
DeleteObject(hpen);
// Create an icon from the bitmap.
//
// Icons require masks to indicate transparent and opaque areas. Since this
// simple example has no transparent areas, we use a fully opaque mask.
HBITMAP hbmpMask = CreateCompatibleBitmap(hdcScreen, width, height);
ICONINFO ii;
ii.fIcon = TRUE;
ii.hbmMask = hbmpMask;
ii.hbmColor = hbmp;
HICON hIcon = CreateIconIndirect(&ii);
DeleteObject(hbmpMask);
// Clean-up.
SelectObject(hdcMem, hbmpOld);
DeleteObject(hbmp);
DeleteDC(hdcMem);
ReleaseDC(NULL, hdcScreen);
// Return the icon.
return hIcon;
}
In principle the code works and I can use it to create colored icons at runtime using the Win API. However, I have some problems and questions about that code (and creating icons in general) which I would like to discuss.
Any help is highly appreciated.
When do I actually have to destroy the icon?
read about DestroyIcon
It is only necessary to call
DestroyIcon
for icons and cursors created with the following functions:CreateIconFromResourceEx
(if called without theLR_SHARED
flag),CreateIconIndirect
, andCopyIcon
. Do not use this function to destroy a shared icon. A shared icon is valid as long as the module from which it was loaded remains in memory. The following functions obtain a shared icon.
LoadIcon
LoadImage
(if you use theLR_SHARED
flag)CopyImage
(if you use theLR_COPYRETURNORG
flag and thehImage
parameter is a shared icon)CreateIconFromResource
CreateIconFromResourceEx
(if you use theLR_SHARED
flag)
so you need call DestroyIcon
for not shared icon, when you are finished using it
ComboBoxEx
not destroy image list which you assign to it with CBEM_SETIMAGELIST
- so this image list must be valid until ComboBoxEx
valid and you must destroy it yourself later.
ImageList_AddIcon
Because the system does not save hicon, you can destroy it after the macro returns
in other words ImageList_AddIcon
make copy of your icon, and you can destroy your original icon, after macro return
for create 32 bit color icon try code like this:
HICON CreateGradientColorIcon(COLORREF iconColor, int width, int height)
{
HICON hIcon = 0;
ICONINFO ii = { TRUE };
ULONG n = width * height;
if (PULONG lpBits = new ULONG[n])
{
PULONG p = lpBits;
ULONG x, y = height, t;
do
{
x = width, t = --y << 8;
do
{
*p++ = iconColor | ((t * --x) / n << 24);
} while (x);
} while (y);
if (ii.hbmColor = CreateBitmap(width, height, 1, 32, lpBits))
{
if (ii.hbmMask = CreateBitmap(width, height, 1, 1, 0))
{
hIcon = CreateIconIndirect(&ii);
DeleteObject(ii.hbmMask);
}
DeleteObject(ii.hbmColor);
}
delete [] lpBits;
}
return hIcon;
}
when I draw (DrawIconEx(, DI_IMAGE|DI_MASK)
) this icon over green mesh I view next:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With