在使用C(WIN32 API)时在窗口中显示字符串输出

8

我希望能够找到一种合适的方式,以便在创建的窗口中输出字符字符串并将其显示出来。 我之前一直在使用textout()函数,但是由于它只绘制窗口,一旦窗口最小化并恢复,窗口上显示的数据就会消失。 当要显示的数据超过窗口大小时,只有与窗口大小相等的数据被显示,其他数据则被截断。 还有其他的方式可以在窗口上输出数据吗?

2个回答

14

您可以在窗口中放置一个静态或者一个编辑框(标签和文本框)来展示数据。

WM_CREATE期间调用其中之一:

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

或者

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

如果您使用 Edit,则用户还可以滚动、复制和粘贴文本。

在这两种情况下,都可以使用 SetWindowText() 更新文本:

SetWindowText(hWndExample, TEXT("Control string"));
(Daboyzuk提供)

2
+1,我甚至没有考虑到原帖作者可能想要控制权,因为已经提到了TextOut,所以我直接开始绘制文本。很可能这正是原帖作者真正想要的。 - Daboyzuk
@Daboyzuk 很遗憾,我不太熟悉本地Win32或C窗口编程,无法提供示例 :) - Deanna
3
这是一个示例:对于静态文本,使用HWND StaticExample = CreateWindowEx("STATIC", "Text Goes Here", WS_VISIBLE | WS_CHILD | SS_LEFT, 10,10,100,100,hWnd,NULL,hInstance,NULL);;对于编辑框,使用 HWND EditExample = CreateWindowEx("EDIT", "Text Goes Here", WS_VISIBLE | WS_CHILD | ES_LEFT, 10,10,100,100,hWnd,NULL,hInstance,NULL);。请注意,这些代码用于创建窗口控件。 - Daboyzuk
@Deanna:对我来说它运行得很好,但如果我想连续显示文本怎么办?我需要重复调用CreateWindowEx吗? - Ayse
1
@AyeshaHassan 不,你需要在 WM_CREATE 中创建窗口,然后只需调用 SetWindowText() 来设置内容。这就是为什么我在回复中分开了这些行,但我会让它更清晰一些。 - Deanna
显示剩余2条评论

8

如果在WM_PAINT中完成,TextOut应该完美地工作。这样可以在缩小和重新调整大小时每次绘制。

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;
}

您可能也对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;
}

这将在给定的矩形中绘制文本。


Draw Text会在给定的矩形内自动换行。
如果您希望将整个窗口作为绘制区域,可以使用GetClientRect(hWnd, &rec);而不是SetRect(&rec,10,10,100,100);


不错!但我不太喜欢在switch语句中放置大块的代码 - 而且你也需要返回一些东西。我认为他想要一个解决方案,如果文本行太长就换行。 - Rup
2
是的,在 switch 语句内编写代码很糟糕,但我只是想提供一个最简单的示例。实际上太简单了,正如你指出的那样,我设法简化了返回值 =) 已编辑!如果 DrawText 超出矩形范围,它将自动换行,但我会添加一个脚注,感谢您的提醒。 - Daboyzuk
@Dabaooyzuk:非常感谢您的帮助。我尝试了一下,对于显示单个字符串效果很好。但是如果我想要多次显示某些内容怎么办?有什么建议吗? - Ayse
1
@Ayesha Hassan 当你需要替换你已经绘制的值时,你调用 InvalidateRect(RECT,TRUE),这告诉窗口需要重新绘制此部分内容。然而,Deanna的例子中,使用SetWindowText (或Static_SetText(hwnd, text) / Edit_SetText(hwnd,text)) 将是更好的解决方案。 - Daboyzuk
在WM_PAINT中需要使用ReleaseDC吗? 我看到的其他示例没有使用它。 - LovelyHanibal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接