我想在给定窗口中绘制一个缓冲区(带有alpha信息!)。绘图是在WM_PAINT之外完成的(它是在从Chromium-Embedded-Framework调用的CefRenderHandler :: OnPaint方法中完成的。)
我遇到的问题是:
这是我到目前为止所做的:
OnPaint(...):
HDC screen_dc = GetDC(windowHandle);
RECT rcWin;
GetClientRect(windowHandle, &rcWin);
BITMAPINFO info;
ZeroMemory(&info, sizeof(BITMAPINFO));
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biWidth = width;
info.bmiHeader.biHeight = -height;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biSizeImage = width*height * 4;
info.bmiHeader.biCompression = BI_RGB;
void *buf;
HBITMAP hDib = CreateDIBSection(screen_dc, &info, DIB_RGB_COLORS, (void **)&buf, 0, 0);
memcpy(buf, buffer, width * height * 4); //buffer contains bitmap to draw
HDC hDibDC = CreateCompatibleDC(screen_dc);
HGDIOBJ hOldObj = SelectObject(hDibDC, hDib);
BLENDFUNCTION blendFunction_;
blendFunction.BlendOp = AC_SRC_OVER;
blendFunction.BlendFlags = 0;
blendFunction.SourceConstantAlpha = 255;
blendFunction.AlphaFormat = AC_SRC_ALPHA;
AlphaBlend(screen_dc, 0, 0, width, height, hDibDC, 0, 0, width, height, blendFunction);
SelectObject(hDibDC, hOldObj);
ReleaseDC(windowHandle, screen_dc);
DeleteObject(hDib);
DeleteDC(hDibDC);
创建窗口:
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = BrowserWindowWndProc;
wcex.hInstance = hinstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = WHITE_BRUSH;
wcex.lpszClassName = BROWSER_WINDOW_CLASS;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
RegisterClassEx(&wcex);
DWORD exStyle{0};
exStyle |= WS_EX_TOOLWINDOW;
exStyle |= WS_EX_LAYERED;
DWORD style {0};
style |= WS_SYSMENU;
style |= WS_VISIBLE;
HWND hWnd = CreateWindowEx(
exStyle,
BROWSER_WINDOW_CLASS,
BROWSER_WINDOW_CLASS,
style,
100,
100,
300,
300,
nullptr,
nullptr,
hinstance,
nullptr
);
...
SetLayeredWindowAttributes(hWnd, RGB(255, 255, 255), 255, LWA_COLORKEY);
你能帮我解决这些问题吗?
提前谢谢。
答案 0 :(得分:1)
没有必要同时使用AlphaBlend
和分层窗口。仅使用分层窗口:
void OnPaint(HDC hdc, int width, int height, HBITMAP hbitmap)
{
HDC memdc = CreateCompatibleDC(hdc);
auto oldbmp = SelectObject(memdc, hbitmap);
BITMAP bm;
GetObject(hbitmap, sizeof(bm), &bm);
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, memdc, 0, 0, SRCCOPY);
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
}
其中hbitmap
是先前创建的位图的句柄。使用SetLayeredWindowAttributes(hwnd, RGB(255,255,255), 255, LWA_COLORKEY);
或使用LWA_COLORKEY | LWA_ALPHA
调整透明度和Alpha级别。
假设OnPaint
是对WM_PAINT
的回复,请使用BeginPaint/EndPaint
代替GetDC/ReleaseDC
请注意WHITE_BRUSH
为零,因此wcex.hbrBackground = WHITE_BRUSH;
将背景画笔设置为零。改为指定画笔手柄。
或者,您可以在同一窗口中使用TransparentBlt
:
HDC memdc = CreateCompatibleDC(hdc);
auto oldbmp = SelectObject(memdc, hbitmap);
BITMAP bm;
GetObject(hbitmap, sizeof(bm), &bm);
TransparentBlt(hdc, 0, 0, width, height,
memdc, 0, 0, bm.bmWidth, bm.bmHeight, RGB(255, 255, 255));
SelectObject(memdc, oldbmp);
DeleteDC(memdc);