在Windows对话框中处理WM_ERASEBKGND时如何避免闪烁
时间:2020-03-06 15:03:08 来源:igfitidea点击:
我有一个调整大小的对话框。它还具有一个自定义背景,我根据WM_ERASEBKGND调用(当前是对FillSolidRect的简单调用)进行绘制。
调整对话框大小时,将发生巨大的闪烁。为了减少闪烁,我列举了所有子窗口并将它们添加到剪切区域。这似乎有所帮助-现在,在所有子控件重新绘制时,闪烁在大多数情况下都是显而易见的。
调整大小时如何使对话框无闪烁?我怀疑双重缓冲必须发挥作用,但是我不确定如何通过带有子控件的对话框来做到这一点(无需使所有子控件成为所有者绘制或者类似的东西)。
我应该注意,尽管欢迎使用纯基于Win32的解决方案,但我使用的是C ++(不是.NET)和MFC :)
注意:我尝试过但无法解决(不确定原因)的一件事是:
CDC memDC; memDC.CreateCompatibleDC(pDC); memDC.FillSolidRect(rect, backgroundColor); pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
解决方案
实际上,双缓冲是使这项工作唯一的方法。
只要我们确保" CLIPCHILDREN",儿童控件就会自理。
在WM_ERASEBKGND处理中不执行任何操作,并将擦除作为主WM_PAINT的一部分进行。我们可以更聪明地绘制,以便仅重画无效区域,或者更容易地对图形进行双缓冲。
通过在擦除背景中不做任何事情,我们可以将所有绘图代码都放在一个位置,这应该使其他人更容易遵循和维护。
尝试将以下行添加到OnInitDialog函数中:
ModifyStyle(0, WS_CLIPCHILDREN, 0);
假定" FillSolidRect"是背景的擦除,然后从WM_ERASEBKGND返回TRUE。
要执行代码片段中几乎要执行的双重缓冲,我们将需要使用CreateCompatibleBitmap并将其选择到memDC中。
如果目标是WinXP或者更高版本,则还可以使用WS_EX_COMPOSITED样式在默认情况下为具有此样式的顶级窗口启用双缓冲。请记住,这有其自身的局限性-具体来说,不再需要使用GetDC等绘制OnPaint循环。