【发布时间】:2017-01-08 13:22:14
【问题描述】:
我想使用 C++ 和 Win API 以编程方式创建 32 位颜色图标。为此,我使用了我找到的以下代码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;
}
原则上代码可以工作,我可以使用它在运行时使用 Win API 创建彩色图标。但是,我有一些关于该代码(以及一般创建图标)的问题和疑问,我想讨论一下。
- 使用此功能创建的图标似乎不是 32 位色深。如果我使用像 RGB(218, 112, 214) 这样的颜色,我希望它是浅紫色。但是,实际显示的颜色是灰色的。如何更改代码以使颜色真正为 32 位 RGB?
- 创建的图标完全填充了颜色,我想在它周围有一个黑色的薄边框...如何实现?
- 在 MSDN documentation 中(有点往下)提到“在关闭之前,您的应用程序必须使用 DestroyIcon 销毁它使用 CreateIconIndirect 创建的任何图标。没有必要销毁其他创建的图标" 但是,在文档中,例如CreateIcon 在 MSDN 中据说 “当你使用完图标后,使用 DestroyIcon 函数将其销毁。” 这几乎是一个矛盾。我什么时候必须真正销毁图标?
- 当我将图标添加到图像列表并将此列表添加到组合框时,这些规则是否也适用? IE。我是否必须清理图像列表和每个关联的图标?
非常感谢任何帮助。
【问题讨论】:
-
嗯,那个面具看起来不像一个合适的面具。它用于 AND 操作,因此您可以简单地使用 hbmp 代替。
-
是的,对于蒙版需要使用
CreateBitmap和cBitsPerPel==1而不是CreateCompatibleBitmap,对于颜色也需要CreateBitmap和cBitsPerPel==32和RGB你不使用alpha -
嗯,但是在 CreateBitmap 的 MSDN 文档中,它说对于彩色位图,出于性能原因应该使用 CreateCompatibleBitmap 而不是 CreateBitmap,所以两者都不应该工作吗?我为位图尝试了 CreateBitmap(width, height, 1, 32, 0),为掩码尝试了 hbmpMask = CreateBitmap(width, height, 1, 1, 0) 但没有任何改变(但我不确定其余参数如以 lpvBits 为例)