问题
If I need to use double buffering, I need to suppress WM_ERASEBKGND message.
I can handle WM_ERASEBKGND and return immediately. But can I set the WNDCLASS/WNDCLASSEX's hbrBackground to NULL and not handle the WM_ERASEBKGND message? Is this a correct way?
回答1:
Yes, setting hbrBackground to NULL is an appropriate way to avoid implementing a no-op WM_ERASEBKGND handler.
When you pass WM_ERASEBKGND on to DefWindowProc, it checks the background brush in the window's class. If there is one, it fills the dirty region with it. If the background brush is null, it does nothing and returns. That's essentially the same as having your own do-nothing WM_ERASEBKGND handler.
The return value from the WM_ERASEBKGND handler affects the fErase field of the PAINTSTRUCT you get when WM_PAINT calls BeginPaint. The WM_PAINT handler is supposed to check fErase to find out whether it needs to erase the background itself or if it was already done by WM_ERASEBKGND. (Though I've never actually seen anyone check it.) If you let DefWindowProc handle WM_ERASEBKGND it will return TRUE if it has a color number or brush and FALSE if the hbrBackground is NULL.
回答2:
I believe that it is more correct to set hbrBackground = GetStockObject(HOLLOW_BRUSH) than it is to set it to NULL.
An article on Raymond Chen's The Old New Thing makes a distinction:
If you don't want automatic background drawing, then pass the hollow brush. If you want custom background drawing, then pass
NULLas the brush.
The MSDN documentation for WNDCLASS's hbrBackground member says:
When this member is
NULL, an application must paint its own background whenever it is requested to paint in its client area. To determine whether the background must be painted, an application can either process theWM_ERASEBKGNDmessage or test thefErasemember of thePAINTSTRUCTstructure filled by theBeginPaintfunction.
And the MSDN documentation for WM_ERASEBKGND says:
The
DefWindowProcfunction erases the background by using the class background brush specified by thehbrBackgroundmember of theWNDCLASSstructure. IfhbrBackgroundisNULL, the application should process theWM_ERASEBKGNDmessage and erase the background.
My interpretation is that setting hbrBackground to NULL and then neglecting to handle WM_ERASEBKGND not meant to be strictly legal (but probably works); hbrBackground = NULL is a promise that you will handle WM_ERASEBKGND yourself and not let DefWindowProc try to paint with a null pointer.
来源:https://stackoverflow.com/questions/12073721/what-is-the-correct-way-to-suppress-wm-erasebkgnd