[英]How to redraw only a region of a layered window?
I have a layered window which is normally drawn this way: 我有一个通常以这种方式绘制的分层窗口:
private void SelectBitmap(Bitmap bitmap)
{
IntPtr screenDc = GetDC(IntPtr.Zero);
IntPtr memDc = CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr hOldBitmap = IntPtr.Zero;
try
{
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
hOldBitmap = SelectObject(memDc, hBitmap);
POINT sourceLocation = new POINT(0, 0);
BLENDFUNCTION blend = new BLENDFUNCTION();
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
SIZE newSize = new SIZE(bitmap.Width, bitmap.Height);
POINT newLocation = new POINT(Location.X, Location.Y);
UpdateLayeredWindow(Handle, screenDc,
ref newLocation, ref newSize,
memDc,
ref sourceLocation, 0,
ref blend,
ULW_ALPHA);
}
finally
{
ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero)
{
SelectObject(memDc, hOldBitmap);
DeleteObject(hBitmap);
}
DeleteDC(memDc);
}
}
However, this obviously redraw the whole window every time it's called. 但是,这显然会在每次调用时重新绘制整个窗口。 It's quite a performance drain on large window.
大窗口上的性能消耗很大。 (even on my top of the line PC, which make me wonder how people could handle that in Win2K)
(即使在我的高端PC上,这也使我想知道人们如何在Win2K中处理它)
If I read the Microsoft paper on the layered window, it says : UpdateLayeredWindow always updates the entire window. 如果我在分层窗口上阅读了Microsoft的论文,它说 :UpdateLayeredWindow总是更新整个窗口。 To update part of a window, use the traditional WM_PAINT and set the blend value using SetLayeredWindowAttributes.
要更新部分窗口,请使用传统的WM_PAINT并使用SetLayeredWindowAttributes设置混合值。
I just can't understand the above. 我只是无法理解以上内容。 How is WM_PAINT supposed to access the layered window bitmap and redraw only part of it on the window?
WM_PAINT应该如何访问分层的窗口位图并仅在窗口上重绘部分位图? From what I understood, layered windows simply disable the WM_PAINT message and expect the user to draw the window by himself.
据我了解,分层窗口只是禁用WM_PAINT消息,并希望用户自己绘制窗口。 There's obviously no way to bind the WM_PAINT to the custom drawing done.
很显然,没有办法将WM_PAINT绑定到完成的自定义工程图上。
Am I missing something very obvious? 我是否缺少一些显而易见的东西?
After long profiling, I found out it wasn't really the layered window update that was bottleneck. 经过长时间的分析,我发现瓶颈并不是真正的分层窗口更新。 Refreshing the whole screen, the SelectBitmap method above, on a 1920*1200 was taking about 6-8ms.
刷新整个屏幕,上面的SelectBitmap方法在1920 * 1200上耗时约6-8ms。 Sure, not very amazing, but plenty enough to refresh at 30 FPS+.
当然,不是很惊人,但足以以30 FPS +的速度刷新。
In my case, the performance drains was coming from some thread asking for refresh almost a hundred time per redraw, making everything sluggish. 以我为例,性能消耗来自某个线程,要求每次重绘刷新将近一百次,从而使所有操作都变得缓慢。 The solution was to break down the refresh/redraw and separate them.
解决方案是分解刷新/重画并将它们分开。 One would update (union) a region and the other, when not drawing, would take that region, draw it and then empty it.
一个将更新(联合)一个区域,而另一个在不绘制时将占据该区域,绘制该区域,然后将其清空。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.