2

I'm trying to print a text in the WM_COMMAND case, because I need a text to be printed after a button was pushed.

Here's the code I have:

switch(msg)
{
default:
    return DefWindowProc(hwnd, msg, wParam, lParam);
case WM_COMMAND:
    switch (LOWORD(wParam))
    {
    case 1:
        PAINTSTRUCT ps;
        HDC         hDC;
        hDC = BeginPaint(hwnd, &ps);
        {
            TextOut(hDC, 10, 50, "hello", 5);
        }
        EndPaint(hwnd, &ps);
        UpdateWindow(hwnd);
        break;
    }
    break;
}

Sadly it doesn't print anything.

edit:

I can use TextOut() during WM_COMMAND that way:

HDC         hDC;
hDC = GetDC(hwnd);
TextOut(hDC, 10, ypos, "Warnings: ", 10);
UpdateWindow(hwnd);
Steffen Moritz
  • 7,277
  • 11
  • 36
  • 55
tgikf
  • 557
  • 4
  • 17
  • 1
    You do realize that [the MSDN documentation for `BeginPaint()`](http://msdn.microsoft.com/en-us/library/dd183362.aspx) very clearly states that **"an application should not call `BeginPaint` except in response to a `WM_PAINT` message"**? Calling `BeginPaint()`/`EndPaint()` during `WM_COMMAND` processing simply won't work. – In silico Apr 12 '11 at 07:46
  • 1
    Oh... Sorry, my bad. But i still need to print my Text in WM_COMMAND... Any ideas? – tgikf Apr 12 '11 at 07:50
  • 1
    No question should be apologized for :-). `BeginPaint()` returns a DC that can paint only on areas which have been invalidated by either having other windows obscuring them, or by direct intent using `InvalidateRect()`. Therefore it should be used only & always inside WM_PAINT. For any other purpose, `GetDC()` is used. – Assaf Levy Apr 12 '11 at 08:20
  • My comment isn't meant to put you down or anything like that; you don't have to apologize. :-) But it was an important point that would prevent your original code from ever working. Generally if a function isn't working the way you think it does, you should look for its documentation (in this case, MSDN). – In silico Apr 13 '11 at 19:04

2 Answers2

8

It's best to structure your program so that all painting is performed in WM_PAINT.

so you could change it to be something like:

LRESULT CALLBACK WndProc(/*blah blah blah*/) 
{
    static wchar_t my_text[] = L"hello";
    static BOOL show_btn_text = FALSE;
    HDC dc;
    PAINTSTRUCT ps;
    switch (msg) {
          case WM_COMMAND:
               switch (LOWORD(wParam)) {
                  case 1:
                       show_btn_text = !show_btn_text;
                       InvalidateRect(hwnd, NULL, TRUE); //tells windows that the whole client area needs to be repainted
                       break;
               }
               return 0;
           case WM_PAINT:
                dc = BeginPaint(hwnd, &ps);
                if (show_btn_text) {
                    TextOut(dc, 0, 0, my_text, wcslen(my_text));
                }
                EndPaint(hwnd, &ps);

            return 0;
            /*the rest of the window procedure
    }
}
Brian
  • 159
  • 3
6
  • For painting inside of WM_PAINT: BeginPaint/EndPaint.
  • For painting outside of WM_PAINT: GetDC/ReleaseDC.
Johann Gerell
  • 24,991
  • 10
  • 72
  • 122