Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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 NULL as 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 the WM_ERASEBKGND message or test the fErase member of the PAINTSTRUCT structure filled by the BeginPaint function.

And the MSDN documentation for WM_ERASEBKGND says:

The DefWindowProc function erases the background by using the class background brush specified by the hbrBackground member of the WNDCLASS structure. If hbrBackground is NULL, the application should process the WM_ERASEBKGND message 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top