I want to handle WM_ERASEBKGND message by myself, because when I let Windows handle it, the whole application window is erased, including all child windows. If I send WM_ERASEBKGND message manually, I must get the context device and send it with the message in WPARAM. I retreive such a context device using GetDCEx() with DCX_CLIPCHILDREN flag and the clipping region is set properly (does not contaion child windows). Then in WM_ERASEBKGND part of message handling procedure, I get this context device, get the clipping rectangle using GetClipBox() and fill it with color simulating "the erasing of a window". It may be like this:
Code:
case WM_COMMAND:
{
// ...
// in response to e.g. toolbar button click
HDC hDC = GetDCEx(hWnd, NULL, DCX_CLIPCHILDREN | DCX_CACHE);
SendMessage(WM_ERASEBKGND, (WPARAM)hDC, 0);
// some drawing using hDC...
ReleaseDC(hWnd, hDC);
}
break;
// ...
case WM_ERASEBKGND:
{
RECT rcWin;
GetClipBox((HDC)wParam, &rcWin); // GetUpdRect() returns a free rectangle here!
FillRect(hDC, &rcWin, hBrush); // hBrush can be obtained by calling GetWindowLong()
}
break;
This works fine. But only when I send WM_ERASEBKGND by myself. If it's sent by Windows, for example as a result of calling BeginPaint() in WM_PAINT message:
Code:
case WM_PAINT:
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
// now Windows send a WM_ERASEBKGND message and return here
// some drawing...
EndPaint(hWnd, &ps);
// I don't remember the exact syntax of BeginPaint() and EndPaint(), it doesn't matter now
the clipping and even update rectangle is free. So I need to handle it like this:
Code:
case WM_ERASEBKGND:
{
RECT rcWin;
GetClipBox((HDC)wParam, &rcWin);
if (IsEmptyRect(rcWin)) GetClientRect(hWnd, &rcWin);
FillRect(hDC, &rcWin, hBrush);
}
break;
But in this case, I there is a whole window in rcWin so I'm back where I began with problem. I'm redrawing whole window. This flickers on slow computers.
My question is, how to get the proper update (or clipping) rectangle when WM_ERASEBKGND is sent automatically by Windows?