What is the correct way to suppress WM_ERASEBKGND?
-
27-06-2021 - |
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?
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 theWM_ERASEBKGND
message or test thefErase
member of thePAINTSTRUCT
structure filled by theBeginPaint
function.
And the MSDN documentation for WM_ERASEBKGND
says:
The
DefWindowProc
function erases the background by using the class background brush specified by thehbrBackground
member of theWNDCLASS
structure. IfhbrBackground
isNULL
, the application should process theWM_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.