I'm a bit confused by the MSDN page for WM_PRINTCLIENT
and related functionality in a few ways:
What value should I return from my window procedure? The documentation is missing a "Return value" section entirely. (It is also missing in the Visual Studio 2012 offline documentation disc's version of the page.) Raymond Chen's original scratch program returns zero; is this the preferred option?
The summary and Remarks section for WM_PRINTCLIENT
indicates that I should only draw the client area, but the LPARAM lists all the possible WM_PRINT
flags — so what should I do, ignore it and unconditionally draw just the client area or draw everything requested? (My intention with this question is not to second-guess the documentation; I'm just looking to implement this message correctly.)
I want to, as a convenience/kindness, provide the WM_PAINT
with DC in wParam functionality mentioned in the WM_PAINT
documentation as an option as well. How should I interpret LPARAM in this case? Or is there a reason I shouldn't provide this alternative route? (Corollary: if LPARAM is to be ignored, should I draw the entire client area unconditionally?)
Thanks.
Update Rephrasing the third part:
The documentation for WM_PAINT
includes the paragraph
For some common controls, the default WM_PAINT message processing checks the wParam parameter. If wParam is non-NULL, the control assumes that the value is an HDC and paints using that device context.
I would like to provide this behavior in my control in addition to WM_PRINTCLIENT
for completeness's sake. Is there a reason I should NOT do so? And if doing so wouldn't hurt, how should I interpret the lParam, and should I draw the entire client rect?
What value should I return from my window procedure?
You return 0 to indicate that the message was handled. Do not call DefWindowProc().
but the LPARAM lists all the possible WM_PRINT flags
That was a bit sloppy, a copy/paste fumble from the WM_PRINT article. The only flags you should test are PRF_ERASEBKGND, but only if your draw method requires having the background painted, and PRF_CLIENT, which will always be set in common usage of the message.
How should I interpret LPARAM in this case?
Hard to decode that question, WM_PAINT doesn't use the lparam argument. But yes, you want a common function that implements the painting so you can call it both from your WM_PAINT and your WM_PRINTCLIENT message handlers. Boilerplate code in your window procedure ought to look like:
case WM_PAINT: {
HDC hdc = BeginPaint(hWnd, &ps);
Draw(hdc);
EndPaint(hWnd, &ps);
break;
}
case WM_PRINTCLIENT: {
HDC hdc = (HDC)wParam;
DWORD flags = (DWORD)lParam;
if (flags & PRF_ERASEBKGND) SendMessage(hWnd, WM_ERASEBKGND, (WPARAM)hdc, NULL);
if (flags & PRF_CLIENT) Draw(hdc);
break;
}
Where void Draw(HDC hdc)
is your common paint function.