【发布时间】:2017-01-17 07:34:15
【问题描述】:
我有一个静态控件,我通过使用位图将 STM_IMAGE 发送到控件来设置图像。这工作正常,但我希望位图具有透明背景。我有以下代码:
case WM_PAINT:
{
HBITMAP hbmBmp, hbmMask;
BITMAP bm;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
HWND hCtrl = GetDlgItem(hWnd, ID_BUTTONNEWGAME);
hbmBmp = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_NEWGAMEBUTTONBITMAP));
GetObject(hbmBmp, sizeof(BITMAP), &bm);
hbmMask = CreateBitmapMask(hbmBmp, RGB(0, 0, 0));
HDC hDCMem = CreateCompatibleDC(hdc);
HDC hDCMem2 = CreateCompatibleDC(hdc);
HDC hdcResult = CreateCompatibleDC(hdc);
SelectObject(hDCMem, hbmMask);
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hDCMem, 0, 0, SRCAND);
SelectObject(hDCMem, hbmBmp);
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hDCMem, 0, 0, SRCPAINT);
// At this point I can see the bitmap with a transparent background at (0,0)
// The following code attempts to copy from hdc into a memory DCand to form a new bitmap
//that I use in the STM_SETIMAGE message
HBITMAP newBitmap = CreateCompatibleBitmap(hdc, bm.bmWidth, bm.bmHeight); // create blank bitmap
SelectObject(hdcResult, newBitmap); // store in memory DC
BitBlt(hdcResult, 0, 0, bm.bmWidth, bm.bmHeight, hdc, 0, 0, SRCCOPY); // copy from hdc to memory DC
// This line is just for checking that hdcResult contains the correct data
// It copies back from the memory DC into hdc to the right of the original bitmap
// I now see two bitmaps with transparent bitmaps next to each other as I expected
BitBlt(hdc, bm.bmWidth, 0, bm.bmWidth, bm.bmHeight, hdcResult, 0, 0, SRCCOPY);
EndPaint(hWnd, &ps);
// sending this does not set the bitmap on the static control
// I do not see anything where the control should be
SendMessage(hCtrl, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)newBitmap);
}
break;
在下面的代码中使用 SS_BITMAP 样式创建静态控件:
case WM_CREATE:
{
HWND newGameText = CreateWindowW(
L"STATIC",
L"",
WS_VISIBLE | WS_CHILD | SS_BITMAP | SS_NOTIFY, // Styles
150, // x position
150, // y position
74, // width
24, // height
hWnd, // Parent window
(HMENU)ID_BUTTONNEWGAME,
(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
}
break;
我需要将位图复制到设备上下文中控件的特定位置(这似乎不合理)还是我在做一些完全不可能/愚蠢的事情?
【问题讨论】:
-
我知道我还应该在使用后删除设备上下文。
-
您没有创建具有 (alpha) 透明度的位图。对
BitBlt的前两次调用通过仅写入未被遮罩的像素来创建透明度的错觉。完成后,尚未更改的像素仍然具有其背景颜色。如果您想要透明度,请使用 STM_SETIMAGE 和IMAGE_ICON。图标支持透明度(甚至可能使用 introduction of PNG support 实现 alpha 透明度)。 -
谢谢,但我在按钮上看不到任何东西,甚至没有不透明的位图。我将编辑 OP 以使其更清晰。
-
您的静态控件是否具有
SS_BITMAP样式?顺便说一句,既然它的ID是ID_BUTTONNEWGAME,那真的是静态控件吗?在传递之前从设备上下文中选择newBitmap可能也是一个好主意。否则它归设备上下文所有。一旦你实施了适当的清理,这将成为一个问题。 -
是的,该控件是使用 SS_BITMAP 样式创建的。我将创建代码添加到 OP。