首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ WinAPI TextOut()更新文本

C++ WinAPI TextOut()更新文本
EN

Stack Overflow用户
提问于 2014-02-27 03:01:45
回答 2查看 13.1K关注 0票数 1

我正在使用WinAPI创建一个Windows应用程序。在处理窗口的WM_PAINT消息时,我使用TextOut()函数向用户显示更新后的文本。

代码语言:javascript
复制
case WM_PAINT:
{
     PAINTSTRUCT ps;
     HDC hdc;
     hdc = BeginPaint(hwnd, &ps);
     SelectObject(hdc, hfDefault);

     // display the user data in the window
     TextOut(hdc,10,70, "Points: 0", 9);
     TextOut(hdc,10,85, "Level: 0", 8);

     // ...
     EndPaint(hwnd, &ps);
}
break;

如何在调用函数后更改TextOut()打印的文本以及决定打印文本长度的最后一个参数?

我找到的关于使用TextOut()的一切都是关于文本字体的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-27 03:24:40

也许是这样的.

代码语言:javascript
复制
// I'll assume hwnd is global
void OnSomeActionToRefreshValues()
{
    HDC hdc = ::GetDc(hwnd);
    DrawValues(hdc, 88, 99);
    ReleaseDC(hdc);
}

void DrawValues(HDC hdc, int points, int level)
{
    // Might need a rectangle here to overwrite old text
    SelectObject(hdc, hfDefault);    // I assume hfDefault is global
    TCHAR text[256];
    swprintf_s(text, 256, L"Points: %d", points);
    TextOut(hdc, 10, 70, text, wcslen(text));
    swprintf_s(text, 256, L"Level: %d", level);
    TextOut(hdc, 10, 85, text, wcslen(text));
}

在你赢的过程中:

代码语言:javascript
复制
case WM_PAINT:
    PAINTSTRUCT ps;
    HDC hdc;
    hdc = BeginPaint(hwnd,&ps);
    DrawValues(hdc, 88, 99);
    EndPaint(hwnd,&ps);
    break;
票数 4
EN

Stack Overflow用户

发布于 2021-08-25 17:51:53

为了在处理WM_PAINT消息时更新窗口中显示的文本,您需要为要显示的文本字符串提供一些源。

由于你最初的帖子有点旧,Windows API已经随着Windows的新版本发生了变化,当前版本的Windows 10和Windows 11已经处于测试阶段。

由于Windows XP是用于WinAPI的16位UNICODE,因此人们大多使用wchar_t文本字符。这要求文本字符串常量需要L修饰符,就像在L"wchar_t text"中一样。

使用Visual Studio2019,我组合了一个运行在Windows10上的简单示例。这是一个简单的Windows WinAPI桌面图形用户界面应用程序。我从Visual Studio中的一个新项目开始,让集成开发环境使用wWinMain()MyRegisterClass()InitInstance()WndProc()为Windows Desktop GUI应用程序生成框架。

然后,我修改了生成的源代码以执行以下操作:

在主窗口中提供了四个按钮,允许使用

  • 两个文本字符串,这些文本字符串会随着按钮点击次数的更新而更新

我选择使用默认字体,所以没有对用于显示文本的字体进行任何修改。如果需要修改字体,则需要添加代码以创建所需的字体,在用于绘制文本的HDC中选择新字体,然后使用TextOut()使用新字体绘制文本。使用该字体后,您需要将其换回,然后将其删除。

第一步是创建一个用于管理按钮和按钮点击的数据区。我选择在InitInstance()中创建按钮。

代码语言:javascript
复制
static struct {
    const wchar_t* txt;    // pointer to text to display on button face
    int      iCount;       // count of number of times button clicked
    HWND     hwnd;         // button window handle which identifies the button
} myButtons[] = {
    {L"Points up", 0, 0},
    {L"Points dwn", 0, 0},
    {L"Level up", 0, 0},
    {L"Level dwn", 0, 0}
};

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable

   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   // create the displayed window along with the buttons.
   // the buttons are in a single row at the top of the window.

   POINT myPoint = { 10, 10 };  // x, y

   for (auto &a : myButtons) {
       a.hwnd = CreateWindow(
           L"BUTTON",  // Predefined class; Unicode assumed 
           a.txt,      // Button text 
           WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
           myPoint.x,  // x position 
           myPoint.y,  // y position 
           100,        // Button width
           50,         // Button height
           hWnd,       // Parent window
           NULL,       // No menu.
           (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
           NULL);      // Pointer not needed.

       myPoint.x += 100 + 20;    // button width plus a separation distance
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

更新显示窗口的源代码如下。我们有两个函数,一个是按钮单击处理程序,用于确定哪个按钮被单击了;另一个是带有WM_PAINT消息处理程序的WndProc(),用于修改显示的窗口。

代码语言:javascript
复制
// process a button click event and return an indication
// whether the button handle matches one we are managing (1)
// or not managing (0).
int buttonClick(HWND hWnd, HWND hButton)
{
    // look through the list of buttons to see if the window handle
    // of the button event matches one of our buttons.
    for (auto &a : myButtons) {
        if (a.hwnd == hButton) {
            // this is one of our buttons so we increment button click count.
            // then invalidate the window area and update to trigger WM_PAINT message.
            a.iCount++;
            InvalidateRect(hWnd, NULL, TRUE);
            UpdateWindow(hWnd);
            return 1;    // indicate we processed this event.
        }
    }
    return 0;    // indicate we did not process this event
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            int wmCode = HIWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                // not a menu event so see if it is a button click or not.
                if (wmCode == BN_CLICKED) {
                    // if we are managing this button then we skip
                    // the DefWindowProc() otherwise it is called.
                    if (buttonClick(hWnd, (HWND)lParam))
                        break;
                }
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

            // TODO: Add any drawing code that uses hdc here...

            // create the text strings we are going to display/update

            wchar_t myText[2][64];
            // following swprintf_s() works because template
            // generates the proper call with the additional buffer
            // size argument.
            swprintf_s(myText[0], L"Points: %d", myButtons[0].iCount - myButtons[1].iCount);
            swprintf_s(myText[1], L"Level: %d", myButtons[2].iCount - myButtons[3].iCount);

            // get the text metrics of the font we are using to draw the text so
            // that we can find out how tall the letters are and can adjust the
            // distance for each line of text properly.
            TEXTMETRIC myTextMetric = { 0 };
            GetTextMetrics(hdc , &myTextMetric);

            // we will use a POINT struct for maintaining the point at which
            // the text output will start. x coordinate is horizontal position
            // and y coordinate is the vertical position.
            POINT myPoint = { 10, 150 };  // x, y
            int   myMargin = 5;

            // iterate over the list of strings we are displaying and
            // display each one on a separate line.
            for (auto &a : myText) {
                TextOut(hdc, myPoint.x, myPoint.y, a, wcslen(a));
                myPoint.y += myTextMetric.tmHeight + myMargin;
            }

            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22050749

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档