BitBlt + 16 位桌面颜色深度的 UpdateLayeredWindow 和 CreateDIBSection

发布于 2024-09-11 04:39:31 字数 1768 浏览 2 评论 0原文

我有一个在客户端区域具有透明背景的应用程序,该应用程序被绘制为黑色,因为窗口没有分层。在每个 WM_PAINT 消息中,我都对内存 DC 执行 BitBlt,之后我将内存 DC 与 UpdateLayeredWindow 一起使用到分层画布窗口。

内存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 到分层画布窗口 DC(它是 CWnd)执行 UpdateLayeredWindow。所以它是实时的,结果是:除了不规则形状和每像素透明度之外,我还有正常的应用程序窗口和分层窗口。

在 32 位桌面颜色深度下一切正常!如果我切换到 16 位,分层画布窗口就会变得混乱。绘图看起来很糟糕,整个窗口都可以点击。

它认为这是因为缺少 alpha 通道信息。

所以我用谷歌搜索了很多解决方案。我发现在这种情况下我必须创建内存 DC,

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

而不是 CreateCompatibleDC(NULL)。因为兼容的 DC 会给我一个 16 位的 DC。

使用 CreateDC 绘图效果更好。但整个窗口仍然可点击,并且分层窗口中的透明度被绘制为黑色。

所以我认为问题出在 BitBlt 或 CreateDIBSection 的 BitmapInfoHeader 上。

  1. 我不知道是否使用BitmapInfoHeader.biBitCount = 32或BitmapInfoHeader.biBitCount = 16位。认为是 32。那么 biCompression 呢 -> BI_RGB 或 BI_BITFIELDS?

  2. 如何在 BitBlt(..., SRCCOPY) 将 16 位 DC 添加到内存 DC 后将 alpha 通道信息添加到内存 DC,以便与 UpdateLayeredWindow 配合使用? (也许:将 RGB 通道与 alpha 通道预乘?)不知道该怎么做。


我更接近 16 位桌面颜色深度问题了。

HDC hdcMemory = CreateCompatibleDC(NULL);

上面的似乎有效。但我的 UpdateLayeredWindow 函数产生的结果看起来很混乱。

所以,这是因为黑色缺失了!每个全黑的像素都变得透明。你可以看穿并点击。所有其他像素都会失去黑色部分,只能点击。

我做了一个测试:我打开Windows Paint.exe,制作了一个窗口宽度和高度的表面,并用黑色作为填充颜色。

然后我把它放在我的分层窗口下面(缺少黑色),再次将分层窗口作为 forgerround 窗口,然后,哒哒,我的分层窗口与 Paint.exe 黑色像素的闪亮相结合,看起来很正常。

所以我用 BitBlt 过期了,它又是光栅操作参数。但没有运气。

在使用 UpdateLayeredWindow 进行绘制之前,如何使用 BitBlt 将黑色混合到我的 DC 中?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

彼岸花似海 2024-09-18 04:39:31

看看这里:
http://msdn.microsoft.com/en-us/library/aa453651。 ASPX
我确信这是一个光栅操作问题。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文