8

I want a proper way in which I can output a character string and display it on a Window created. I had been using textout() function, but since it only paints the window, once the window is minimized and restored back, the data displayed on the window disappears. Also when the data to be displayed is exceeds the size of Window, only the data equal to window size is displayed and other data is truncated. Is there any other way to output data on a Window?

Ayse
  • 2,676
  • 10
  • 36
  • 61

2 Answers2

14

You can put a Static or an Edit control (Label and a text box) on your window to show the data.

Call one of these during WM_CREATE:

HWND hWndExample = CreateWindow("STATIC", "Text Goes Here", WS_VISIBLE | WS_CHILD | SS_LEFT, 10,10,100,100, hWnd, NULL, hInstance, NULL);

Or

HWND hWndExample = CreateWindow("EDIT", "Text Goes Here", WS_VISIBLE | WS_CHILD | ES_LEFT, 10,10,100,100, hWnd, NULL, hInstance, NULL);

If you use an Edit then the user will also be able to scroll, and copy and paste the text.

In both cases, the text can be updated using SetWindowText():

SetWindowText(hWndExample, TEXT("Control string"));

(Courtesy of Daboyzuk)

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
Deanna
  • 23,876
  • 7
  • 71
  • 156
  • 2
    +1, I hadn't even considered the OP might want the control, as TextOut was mentioned, I jumped straight on to drawing text. Its most likely this is what the OP is actually asking for. – Daboyzuk Mar 15 '13 at 13:59
  • @Daboyzuk Sadly I don't do native Win32 or C window programming enough to conjure up a sample :) – Deanna Mar 15 '13 at 14:02
  • 3
    This should suffice as an example: `HWND StaticExample = CreateWindowEx("STATIC", "Text Goes Here", WS_VISIBLE | WS_CHILD | SS_LEFT, 10,10,100,100,hWnd,NULL,hInstance,NULL);` for static, and `HWND EditExample = CreateWindowEx("EDIT", "Text Goes Here", WS_VISIBLE | WS_CHILD | ES_LEFT, 10,10,100,100,hWnd,NULL,hInstance,NULL);` for edit – Daboyzuk Mar 15 '13 at 14:11
  • @Deanna : It worked fine for me, but what if I want to display the text continuously? Do I have to call CreateWindowEx repeatedly? – Ayse Mar 16 '13 at 04:39
  • Basically I am reading data from my Socket continuoulsy in a buffer and I want to display that buffer on my window. – Ayse Mar 16 '13 at 04:41
  • 1
    @AyeshaHassan No, you create the window in `WM_CREATE` then just call `SetWindowText()` to set the contents. That's why I separated the lines in my reply, but I'll make a bit clearer, – Deanna Mar 16 '13 at 14:19
  • @Deanna: Thank You so much for the help :) – Ayse Mar 18 '13 at 05:01
8

TextOut should work perfectly fine, If this is done in WM_PAINT it should be drawn every time. (including on minimizing and re-sizing)

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_PAINT:
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

            TextOut(hdc, 10, 10, TEXT("Text Out String"),strlen("Text Out String"));

            EndPaint(hWnd, &ps);
            ReleaseDC(hWnd, hdc);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

You might also be interested in DrawText

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_PAINT:
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

            RECT rec;
            //       SetRect(rect, x ,y ,width, height)
            SetRect(&rec,10,10,100,100);
            //       DrawText(HDC, text, text length, drawing area, parameters "DT_XXX")
            DrawText(hdc, TEXT("Text Out String"),strlen("Text Out String"), &rec, DT_TOP|DT_LEFT);

            EndPaint(hWnd, &ps);
            ReleaseDC(hWnd, hdc);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

Which will draw the text to your window in a given rectangle,


Draw Text will Word Wrap inside of the given rect.
If you want to have your whole window as the draw area you can use GetClientRect(hWnd, &rec); instead of SetRect(&rec,10,10,100,100);

Daboyzuk
  • 449
  • 4
  • 14
  • Neat! But I'm not a huge fan of putting large blocks of code in a switch like that - and you need to return something too. I think he wanted a solution to wrap the line of text if it's too long, though. – Rup Mar 15 '13 at 11:58
  • 2
    Yeah, its horrible to code inside the switch, but I was just trying to throw in a minimal example. Too minimal, in fact, as you have pointed out I managed to streamline the return value =) Editted! DrawText will wrap the text if it goes outside the rect, But i'll add a footnote, thanks for that. – Daboyzuk Mar 15 '13 at 12:00
  • @Dabaooyzuk: Thanks alot for your help. I tried it and works fine for displaying a single string. but what if i want to display something multiple times? Any help? – Ayse Mar 16 '13 at 06:39
  • 1
    @Ayesha Hassan You call for InvalidateRect(RECT,TRUE) when you need to replace the value you've painted, this tell your window that this section needs to be redrawn, however Deanna's example, using SetWindowText (or Static_SetText(hwnd, text) / Edit_SetText(hwnd,text) ) would be a better solution to what you want. – Daboyzuk Mar 16 '13 at 14:32
  • Is ReleaseDC needed in WM_PAINT ? Other examples I have seen don't have it. – LovelyHanibal Feb 11 '23 at 06:24