我在客户区有一个透明背景的应用程序,因为窗口没有分层,所以它被绘制为黑色。在它的每一条 WM_PAINT 消息中,我都在对内存 DC 执行 BitBlt,之后我使用带有 UpdateLayeredWindow 的内存 DC 到分层画布窗口。
内存-DC的设置:
HDC hdcMemory = CreateCompatibleDC(NULL);
HBITMAP bmpMemory = CreateDIBSection(hdcMemory, (BITMAPINFO*)&m_BitmapInfoHeader,
DIB_RGB_COLORS, (void **)&m_pDIBSectionBits, NULL, (DWORD)0);
SelectObject(hdcMemory, bmpMemory);
在 WM_PAINT 中,我使用 BitBlt 函数将应用程序客户区 DC 信息复制到内存 DC。之后,我将使用内存 DC 执行 UpdateLayeredWindow 到分层画布窗口 DC(它的 CWnd)。所以它是实时的,结果是:我有一个正常的应用程序窗口和一个分层的窗口,除了不规则的形状和每像素的透明度。
在 32 位桌面颜色深度下一切正常!如果我切换到 16 位,分层画布窗口就会变得混乱。绘图看起来很糟糕,整个窗口虽然可以点击。
它认为这是因为缺少 alpha 通道信息。
所以我在谷歌上搜索了很多解决方案。我发现在这种情况下,我必须使用
HDC hdcMemory = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
而不是 CreateCompatibleDC(NULL)。因为兼容的 DC 会给我一个 16 位的 DC。
使用 CreateDC 绘图效果更好。但是整个窗口仍然是可点击的,并且在分层窗口中透明度被绘制为黑色。
所以我认为问题出在 BitBlt 或 CreateDIBSection 的 BitmapInfoHeader 上。
我不知道是使用 BitmapInfoHeader.biBitCount = 32 还是 BitmapInfoHeader.biBitCount = 16 位。认为它是 32。那么 biCompression -> BI_RGB 或 BI_BITFIELDS 呢?
如何在 BitBlt(..., SRCCOPY) 16 位 DC 到 memory-DC 之后将 alpha 通道信息添加到 memory-DC,以便它与 UpdateLayeredWindow 一起使用?(也许:将 rgb 通道与 alpha 通道预乘?)不知道该怎么做。
我稍微接近了 16 位桌面颜色深度问题。
HDC hdcMemory = CreateCompatibleDC(NULL);
以上似乎工作。但是我的 UpdateLayeredWindow 函数产生的结果看起来很乱。
所以,这是因为缺少黑色!每个全黑的像素都变得透明。您可以查看并单击。所有其他像素都失去了黑色部分,只能点击通过。
我做了一个测试:我打开了Windows Paint.exe,制作了一个窗口宽度和高度以及黑色作为填充颜色的表面。
然后我把它放在我的分层窗口下(缺少黑色),再次将分层窗口作为前景窗口,然后ta-da,我的分层窗口与通过Paint.exe黑色像素的闪耀相结合看起来很正常。
所以我用 BitBlt 过期了,它又是光栅操作参数。但没有运气。
在使用 UpdateLayeredWindow 绘图之前,如何将黑色与 BitBlt 混合到我的 DC 中?