2008-10-02 78 views
9

我有一个调整大小的对话框。它还具有一个自定义背景,我在响应WM_ERASEBKGND调用(当前是对FillSolidRect的简单调用)中绘制了一个自定义背景。如何在Windows对话框中处理WM_ERASEBKGND时避免闪烁

当对话框调整大小时,会发生巨大的闪烁。为了尝试减少闪烁,我列举了所有子窗口并将它们添加到剪辑区域。这似乎有一点帮助 - 现在闪烁现象在所有儿童控制器中都很明显,因为它们被重新绘制。

如何在调整大小时使对话框无闪烁?我怀疑双缓冲必须发挥一部分,但我不知道如何做到这一点与儿童控制的对话(没有使所有的孩子控制所有者绘制或类似的东西)。

我要指出,我使用C++(不是.NET)和MFC,虽然纯基于Win32的解决方案,欢迎:)

注意:有一件事我试过,但没有工作(不肯定为什么)是:

CDC memDC; 
memDC.CreateCompatibleDC(pDC); 
memDC.FillSolidRect(rect, backgroundColor); 

pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY); 

回答

8

假设“FillSolidRect”是你的背景的擦除然后从该WM_ERASEBKGND返回TRUE。

要执行您在代码片段中几乎要做的双缓冲,您需要使用CreateCompatibleBitmap并将其选择到您的memDC中。

3

双缓冲确实是使这项工作的唯一方法。

只要您确认CLIPCHILDREN,子控件将自行照顾自己。

5

在WM_ERASEBKGND处理中不做任何事情,并将其作为主WM_PAINT的一部分进行擦除。您可以更智能地绘画,以便仅重绘无效区域,或者更简单地双重缓冲绘图。

通过在擦除背景中不做任何事情,您可以将所有绘图代码放在一个位置,这样可以让其他人更容易跟踪和维护。

6

尝试添加下面一行到你的OnInitDialog函数:

ModifyStyle(0, WS_CLIPCHILDREN, 0); 
5

如果您的目标是WinXP或更高版本,则也可以使用WS_EX_COMPOSITED样式为默认情况下的顶级窗口启用双缓冲。请记住,这有其自己的一套限制 - 具体而言,不再使用GetDC绘制OnPaint周期等。

4

您可以将InvalidateRect方法的参数设置为false。这将阻止您在窗口重新绘制时发送WM_ERASEBKGND。 Here是防止窗口闪烁的不错链接。