我的目标是有一个全屏覆盖不可见的“ Canvas ”,我可以在上面使用 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);
虽然它用作 Canvas ,但经过数小时的谷歌搜索,我仍然无法半透明地在其上绘图。
我在撰写本文时添加了我的程序当前显示内容的屏幕截图。例如,我希望能够做的是使右上角的黑框(用 Rectangle
绘制)半透明,以便显示其下方的 stackoverflow 页面内容。
This是一个我发现我满怀希望的问题,但生成的文本只是背景颜色 ((COLORREF)0xFEEDBEEF)
和文本颜色的混合组合。我发现的其他事情要么只是使元素完全不可见,什么都不做,要么需要一些像 MFC 这样的库。我希望尽可能仅使用 win32 函数,因为我希望能够实现尽可能高的 FPS。
我不在乎这是否不适用于所有 Windows 版本,只要它适用于 7 到 10。
最佳答案
如果您只需要一个矩形区域的透明度,其中所有像素都具有相同的透明度(又名 alpha)值或完全透明,您可以使用 SetLayeredWindowAttributes()
与 alpha 值和/或颜色键的组合。
UpdateLayeredWindow()
如果您需要能够定义每个像素的透明度,这是可行的方法。
为此你必须创建 memory DC并在其中选择一个 32bpp 位图。您可以使用 buffered paint API以减轻任务。雷蒙德陈有一个blog post with a code sample关于那个。
您可以绘制到内存 DC 中,但是您不能为此使用大部分 GDI API,因为 GDI 会忽略 alpha channel (透明度)。我建议使用 GDI+这允许您指定 alpha 值。
完成绘制到内存 DC 后,您将调用 UpdateLayeredWindow()
并将该内存 DC 作为参数传递给 hdcSrc
参数,以使结果在屏幕上可见。
可能影响的说明:
SetLayeredWindowAttributes( hwnd, 0, 176, LWA_ALPHA );
SetLayeredWindowAttributes( hwnd, colorkey, 0, LWA_COLORKEY );
SetLayeredWindowAttributes( hwnd, colorkey, 176, LWA_ALPHA|LWA_COLORKEY );
UpdateLayeredWindow( ... )
请注意最后一个示例中形状的抗锯齿边缘和透明度渐变。只有使用 UpdateLayeredWindow()
才能实现类似的事情。
关于c++ - 在不可见的分层窗口中半透明绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43712796/