从FillRectangle中略微不需要的透明度 [英] Slight undesired transparency from FillRectangle
问题描述
我有一个用 WS_EX_LAYERED
窗口样式创建的窗口。我目前使用GDI +绘制一个内存位图,并使用 UpdateLayeredWindow
更新分层窗口的图形内容。
I have a window created with the WS_EX_LAYERED
window style. I am currently drawing onto a memory bitmap using GDI+, and using UpdateLayeredWindow
to update the graphical content of my layered window.
我的代码片段:
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%的不透明填充,这不是我想要的。
When creating my SolidBrush
, I specified the value of 254 for the alpha component. This results in a 99.6% opaque fill, which is not what I want.
当我指定255作为alpha组件,似乎没有填充;我的窗口变得完全透明。这是一个问题,因为我希望绘制100%不透明的形状,但我也希望绘制一些不是。
When I specify 255 as the alpha component, there appears to be no fill; my window becomes completely transparent. This is an issue because I wish to draw shapes that are 100% opaque, but I also wish to draw some that aren't.
推荐答案
似乎有一些qwerks与 FillRectangle
。当我们观察到使用 FillEllipse
与α分量为255的 SolidBrush
时,会导致形状被呈现完全(不透明)。
There seems to be some qwerks with FillRectangle
. This becomes apparent when we observe that using FillEllipse
with a SolidBrush
whose alpha component is 255, results in the shape being rendered perfectly (opaque).
这里有两个解决方案,每个解决问题为我:
Here are two work-arounds that I came up with, which each solve the issue for me:
-
致电
FillRectangle
两次 b
$ b
Call
FillRectangle
twice
SolidBrush b(Color(254, 255, 0, 0));
gfx.FillRectangle(&b, Rect(0, 0, width, height));
gfx.FillRectangle(&b, Rect(0, 0, width, height));
由于相同区域被填充两次,它们将混合并创建RGB(255,0,0 )无论窗口后面的内容(它现在是100%不透明)。
Since the same area is being filled twice, they will blend and create RGB(255, 0, 0) regardless of the content behind the window (it's now 100% opaque). I do not prefer this method, as it requires every rectangle to be drawn twice.
使用 FillPolygon
而非
与 FillEllipse
, FillPolygon
似乎没有颜色问题,除非您像这样调用
Just as with FillEllipse
, FillPolygon
doesn't seem to have the colour issue, unless you call it like so:
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
。或者 - 很可能 - FillPolygon
有一些问题,它由 FillRectangle
调用。但是,如果你向数组添加一个额外的 Point
,你可以绕过它:
The above code will result in a 100% transparent window. I am guessing that this is either due to some form of optimisation that passes the call to FillRectangle
instead. Or - most likely - there is some problem with FillPolygon
, which is called by FillRectangle
. However, if you add an extra Point
to the array, you can get around it:
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%不透明的形状,这解决了我的问题。
The above code will indeed draw a 100% opaque shape, which fixes my problem.
这篇关于从FillRectangle中略微不需要的透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!