Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WM_PRINTCLIENT (and related) documentation confusion-related questions

Tags:

winapi

paint

msdn

I'm a bit confused by the MSDN page for WM_PRINTCLIENT and related functionality in a few ways:

  1. 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?

  2. 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.)

  3. 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?

like image 885
andlabs Avatar asked Sep 29 '22 06:09

andlabs


1 Answers

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 you 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.

like image 79
Hans Passant Avatar answered Oct 05 '22 06:10

Hans Passant