UpdateLayeredWindow使用的代码是
HDC hdc = GetWindowDC(hWnd);
int width = 400;
int height = 300;
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, width, height);
HDC hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBitmap);
BLENDFUNCTION blend = { 0 };
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.AlphaFormat = AC_SRC_ALPHA;
blend.SourceConstantAlpha = 255;
RECT rcClient;
GetClientRect(hWnd, &rcClient);
HBRUSH brush = CreateSolidBrush(RGB(128, 128, 128));
FillRect(hdcMem, &rcClient,brush);
POINT ptDst = { 0, 0 };
SIZE sizeWnd = { width, height };
POINT ptSrc = { 0, 0 };
UpdateLayeredWindow(hWnd, hdc, NULL, &sizeWnd, hdcMem, &ptSrc, 0, &blend, ULW_ALPHA);
// 释放资源
DeleteDC(hdcMem);
DeleteObject(hBitmap);
ReleaseDC(hWnd, hdc);
在我看来,这个窗口应该是完全不透明的,混合时SourceConstantAlpha值为255,但实际上,它是半透明的。看起来像这样 但是当我使用 RGB(255, 255, 255) 时,它是完全不透明的。而当我使用 RGB(0, 0, 0) 时,它是完全透明的。 看来画笔的RGB影响透明度。我不明白aplha是如何混合的。
我尝试修改RGB和SourceConstantAlpha。它们都对alpha值有影响。我查阅了WinAPI的文档。公式是Dst.Alpha = Src.Alpha + (1 - Src.Alpha) * Dst 。Α。似乎当 SourceConstantAlpha 为 255 时,窗口应该完全不透明,但事实并非如此。这对我来说很困惑。我想知道 alpha 是如何混合的。
当位图具有 Alpha 通道(即每像素 Alpha)时,会设置此标志。请注意,API 使用预乘 Alpha,这意味着位图中的红色、绿色和蓝色通道值必须与 Alpha 通道值进行预乘。例如,如果 Alpha 通道值为 x,则在调用之前,红色、绿色和蓝色通道必须乘以 x 并除以 0xff。
https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-blendfunction
这就是为什么
RGB(0,0,0)
制作了一个完全透明的窗口。
建议使用
SetLayeredWindowAttributes
,它严格遵循用于描述分层窗口不透明度的alpha值。
当bAlpha为0时,窗口完全透明。当 bAlpha 为 255 时,窗口不透明。