在隐形分层窗口中半透明地绘制

时间:2017-05-01 00:32:40

标签: c++ windows winapi

我的目标是让全屏覆盖不可见的"画布"我可以使用win32的各种绘图功能绘制。

我目前的尝试方式是:

WNDCLASSA myclass = { 0 };
myclass.lpfnWndProc = WindowProc3;
myclass.hInstance = GetModuleHandle(0);
myclass.lpszClassName = "MyCanvas";
myclass.hbrBackground = CreateSolidBrush(0xFEEDBEEF);
myclass.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClassA(&myclass);

...

HWND wnd = CreateWindowExA(WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT, "MyCanvas", 0, WS_POPUP | WS_VISIBLE, 0, 0, screen_width, screen_height, 0, 0, GetModuleHandle(0), 0);
SetLayeredWindowAttributes(wnd, 0xFEEDBEEF, 0, LWA_COLORKEY);

虽然这可以作为画布,稍后用谷歌搜索,但我仍无法半透明地画画。

我添加了一个屏幕截图,显示我正在编写的程序当前正在显示的内容。我希望能够做的是,例如,使右上角的黑框(用Rectangle绘制)半透明,以便揭示它下面的stackoverflow页面内容。

This是一个我发现有希望的问题,但结果文本只是背景颜色((COLORREF)0xFEEDBEEF)和文字颜色的混合组合。我发现的其他事情要么让元素完全不可见,什么都不做,要么像MFC那样需要一些库。我希望仅使用win32 功能,因为我希望能够达到最高的FPS。

我不在乎这是否适用于所有Windows版本,只要它在7到10之间。

Current state of the problem

1 个答案:

答案 0 :(得分:6)

如果您只需要所有像素具有相同透明度(又名 alpha )值或完全透明的矩形区域的透明度,则可以将SetLayeredWindowAttributes()与alpha组合使用值和/或颜色键。

如果您需要能够定义每像素的透明度,那么

UpdateLayeredWindow()就是您的选择。

为此你必须创建memory DC并选择一个32bpp的位图。您可以使用buffered paint API来简化任务。 Raymond Chen对此有一个blog post with a code sample

您可以绘制到内存DC,但是您不能使用大多数GDI API,因为GDI会忽略Alpha通道(透明度)。我建议使用GDI+来指定alpha值。

完成绘制到内存DC后,您将调用UpdateLayeredWindow()并将该内存DC作为hdcSrc参数的参数传递,以使结果在屏幕上可见。

可能影响的说明:

SetLayeredWindowAttributes with LWA_ALPHA

SetLayeredWindowAttributes( hwnd, 0, 176, LWA_ALPHA ); 

SetLayeredWindowAttributes with LWA_COLORKEY

SetLayeredWindowAttributes( hwnd, colorkey, 0, LWA_COLORKEY ); 

SetLayeredWindowAttributes with LWA_ALPHA|LWA_COLORKEY

SetLayeredWindowAttributes( hwnd, colorkey, 176, LWA_ALPHA|LWA_COLORKEY ); 

UpdateLayeredWindow

UpdateLayeredWindow( ... )

请注意最后一个示例中形状的抗锯齿边缘和透明度渐变。只有UpdateLayeredWindow()才能实现这样的目标。