我有一个使用 WS_EX_LAYERED
窗口样式创建的窗口。我目前正在使用 GDI+ 绘制内存位图,并使用 UpdateLayeredWindow
更新我的分层窗口的图形内容。
这是我的代码片段:
void Redraw(HWND hWnd, int width, int height) {
static bool floppy = true;
floppy = !floppy;
HDC hScreenDC = GetDC(HWND_DESKTOP);
HDC hMemDC = CreateCompatibleDC(hScreenDC);
HBITMAP hBmp = CreateCompatibleBitmap(hScreenDC, width, height);
HGDIOBJ hObj = SelectObject(hMemDC, hBmp);
Graphics gfx(hMemDC);
SolidBrush b(Color(254, (floppy ? 255 : 0), (floppy ? 0 : 255), 0));
gfx.FillRectangle(&b, Rect(0, 0, width, height));
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
POINT src = { 0, 0 };
SIZE size;
size.cx = width;
size.cy = height;
Assert(UpdateLayeredWindow(
hWnd,
hScreenDC,
NULL,
&size,
hMemDC,
&src,
RGB(0, 0, 0),
&blend,
ULW_ALPHA
));
SelectObject(hMemDC, hObj);
DeleteObject(hBmp);
DeleteDC(hMemDC);
ReleaseDC(HWND_DESKTOP, hScreenDC);
}
在创建 SolidBrush
时,我为 alpha 分量指定了值 254。这会导致 99.6% 的不透明填充,这不是我想要的。
当我指定 255 作为 alpha 分量时,似乎没有填充;我的 window 变得完全透明。这是一个问题,因为我希望绘制 100% 不透明的形状,但我也希望绘制一些不透明的形状。
最佳答案
FillRectangle
似乎有一些 qwerks。当我们观察到将 FillEllipse
与 Alpha 分量为 255 的 SolidBrush
一起使用时,这一点变得很明显,导致形状完美渲染(不透明)。
以下是我想出的两种解决方法,它们分别为我解决了问题:
调用
FillRectangle
两次SolidBrush b(Color(254, 255, 0, 0)); gfx.FillRectangle(&b, Rect(0, 0, width, height)); gfx.FillRectangle(&b, Rect(0, 0, width, height));
由于同一区域被填充两次,因此无论窗口后面的内容如何(现在是 100% 不透明),它们都会混合并创建 RGB(255, 0, 0)。我不喜欢这种方法,因为它需要每个矩形绘制两次。
使用
FillPolygon
相反与
FillEllipse
一样,FillPolygon
似乎没有颜色问题,除非你这样调用它:SolidBrush b(Color(255, 255, 0, 0)); Point points[4]; points[0] = Point(0, 0); points[1] = Point(width, 0); points[2] = Point(width, height); points[4] = Point(0, height); gfx.FillPolygon(&b, points, 4); //don't copy and paste - this won't work
上面的代码将产生 100% 透明的窗口。我猜测这可能是由于某种形式的优化将调用传递给
FillRectangle
所致。或者 - 最有可能的是 - 由FillRectangle
调用的FillPolygon
存在一些问题。但是,如果向数组添加额外的Point
,则可以绕过它:SolidBrush b(Color(255, 255, 0, 0)); Point points[5]; points[0] = Point(0, 0); points[1] = Point(0, 0); //<- points[2] = Point(width, 0); points[3] = Point(width, height); points[4] = Point(0, height); gfx.FillPolygon(&b, points, 5);
上面的代码确实会绘制一个 100% 不透明的形状,这解决了我的问题。
关于c++ - FillRectangle 出现轻微不合需要的透明度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19214921/