2
votes

I have an application with transparent background in client area which is drawn black because the window is not layered. In each of it's WM_PAINT messages I am doing a BitBlt to a memory-DC, after that I use the memory-DC with UpdateLayeredWindow to a layered canvas window.

setup of memory-DC:

HDC hdcMemory = CreateCompatibleDC(NULL);
HBITMAP bmpMemory = CreateDIBSection(hdcMemory, (BITMAPINFO*)&m_BitmapInfoHeader,
DIB_RGB_COLORS, (void **)&m_pDIBSectionBits, NULL, (DWORD)0);
SelectObject(hdcMemory, bmpMemory);

In WM_PAINT I use the BitBlt function to copy the apps client area DC information to the memory-DC. After that I'm doing a UpdateLayeredWindow with the memory-DC to a layered canvas windows DC (its a CWnd). So it's in realtime, and the result is: I have the normal application window and a layered window besides with an irregular shape and per pixel transparency.

Everything works fine in 32-bit desktop color depth! If I switch to 16-bit, the layered canvas window gets messed up. The drawing looks bad and the whole window is click-though able.

It think it's because of the lack of alpha channel information.

So I googled so much for a solution. I found out that in this situation I have to create the memory-DC with

HDC hdcMemory = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);

instead of CreateCompatibleDC(NULL). Because the compatible DC would give me a 16-bit DC.

Drawing is better with CreateDC. But the whole window is still click-throughable and transparency is drawn black in the layered window.

So I think the problem is with BitBlt or the BitmapInfoHeader of CreateDIBSection.

  1. I don't know if to use BitmapInfoHeader.biBitCount = 32 or BitmapInfoHeader.biBitCount = 16 bit. Think it's 32. And what about biCompression -> BI_RGB or BI_BITFIELDS?

  2. How to add the alpha channel information to the memory-DC after BitBlt(..., SRCCOPY) the 16-bit DC to the memory-DC, so that it works with UpdateLayeredWindow? (maybe: pre-multiply the rgb channels with the alpha channel?) Dunno how to do.


I got a little bit closer to the 16-bit desktop color depth problem.

HDC hdcMemory = CreateCompatibleDC(NULL);

The above seems to work. But the result my UpdateLayeredWindow function produces looks messy.

So, this is because the black color is missing! Every pixel that was full black gets transparent. You can see through and click though. All other pixel lose their black part und only get click through.

I made a test: I opened Windows Paint.exe, made a surface of the windows width and height and black as filled color.

Then I put it under my layered window (with the missing black color), took the layered window as forgeround window again, and ta-da, my layered window looks normal in combination with the shining through Paint.exe black pixels.

So I expiremented with BitBlt and it's raster-operation parameter again. But no luck.

How can I blend the black color with BitBlt to my DC before drawing with UpdateLayeredWindow?

1

1 Answers

0
votes

take a look here: http://msdn.microsoft.com/en-us/library/aa453651.aspx i am convinced, that this is a raster operation-problem.