Draw semitransparently in invisible layered window
c++, winapi, windows
Solution
If you only need transparency for a rectangular area where all pixels either have the same transparency (aka alpha) value or are completely transparent, you can use `SetLayeredWindowAttributes()` with a combination of alpha value and/or color key.
`UpdateLayeredWindow()` is the way to go if you need to be able to define transparency per-pixel.
For that you have to create memory DC and select a 32bpp bitmap into it. You may use the buffered paint API to ease the task. Raymond Chen has a blog post with a code sample about that.
You can draw into the memory DC, but you can't use most of GDI API for that, because GDI ignores the alpha channel (transparency). I suggest using GDI+ which allows you to specify the alpha values.
After you have completed drawing into the memory DC, you would call `UpdateLayeredWindow()` and pass that memory DC as the argument for the `hdcSrc` parameter to make the result visible on screen.
Illustration of possible effects:
SetLayeredWindowAttributes( hwnd, 0, 176, LWA_ALPHA );
SetLayeredWindowAttributes( hwnd, colorkey, 0, LWA_COLORKEY );
SetLayeredWindowAttributes( hwnd, colorkey, 176, LWA_ALPHA|LWA_COLORKEY );
UpdateLayeredWindow( ... )
Note the antialiased edge of the shape and the transparency gradient in the last example. Things like that are only possible with `UpdateLayeredWindow()`.
Problem
My goal is to have a fullscreen overlaying invisible "canvas" on which I can draw using win32's various drawing functions. The way I am currently attempting it is this: ``` 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); ``` Although this serves as a canvas, hours of googling later, I am still unable to draw on it semitransparently. I have added a screenshot of what my program is currently displaying as I am writing this. What I would like to be able to do is, for example, make the black box in the top right corner (drawn with `Rectangle`) semitransparent so as to reveal the stackoverflow page content below it. This is a question I found that I was hopeful about, but the resulting text is just a blended combination of the background color `((COLORREF)0xFEEDBEEF)` and text color. Other things I have found have either just made the element fully invisible, done nothing at all, or required some library like MFC. I want to only use win32 functions if at all possible, as I would like to be able to achieve the highest FPS possible. I do not care if this doesn't work on all Windows versions as long as it does on 7 up to 10.