抑制WM_ERASEBKGND的正确方法是什么?

时间:2012-08-22 12:59:15

标签: winapi doublebuffered

如果我需要使用双缓冲,我需要禁止WM_ERASEBKGND消息。

我可以处理WM_ERASEBKGND并立即返回。但是,我可以将WNDCLASS / WNDCLASSEX的{​​{1}}设置为hbrBackground而不处理NULL消息吗?这是正确的方法吗?

2 个答案:

答案 0 :(得分:5)

是的,将hbrBackground设置为NULL是避免实施无操作WM_ERASEBKGND处理程序的合适方法。

当您将WM_ERASEBKGND传递给DefWindowProc时,它会检查窗口类中的背景画笔。如果有的话,用它填充肮脏的区域。如果背景画笔为null,则它不执行任何操作并返回。这与拥有自己的无操作WM_ERASEBKGND处理程序基本相同。

WM_ERASEBKGND处理程序的返回值会影响fErase调用PAINTSTRUCT时获得的WM_PAINT字段BeginPaintWM_PAINT处理程序应检查fErase以确定是否需要删除背景本身或是否已由WM_ERASEBKGND完成。 (虽然我从未见过有人检查过它。)如果你让DefWindowProc处理WM_ERASEBKGND,如果它有颜色编号或画笔,它将返回TRUE FALSE hbrBackgroundNULL

答案 1 :(得分:1)

我认为设置hbrBackground = GetStockObject(HOLLOW_BRUSH)比将其设置为NULL更为正确。

An article on Raymond Chen's The Old New Thing有所区别:

  

如果您不想要自动背景绘图,请通过空心画笔。如果您想要自定义背景绘图,请将NULL作为画笔传递。

The MSDN documentation for WNDCLASS' hbrBackground成员说:

  

当此成员为NULL时,应用程序必须在请求在其客户区域中绘制时绘制自己的背景。要确定是否必须绘制背景,应用程序可以处理WM_ERASEBKGND消息或测试fErase函数填充的PAINTSTRUCT结构的BeginPaint成员。

MSDN documentation for WM_ERASEBKGND说:

  

DefWindowProc函数使用hbrBackground结构的WNDCLASS成员指定的类背景画笔擦除背景。如果hbrBackgroundNULL,则应用程序应处理WM_ERASEBKGND消息并删除背景。

我的解释是将hbrBackground设置为NULL然后忽略处理WM_ERASEBKGND并不意味着严格合法(但可能有效); hbrBackground = NULL是一个承诺,您将自己处理WM_ERASEBKGND,而不是让DefWindowProc尝试使用空指针进行绘制。