C++ 如何使用计时器绘制文本?

C++ 如何使用计时器绘制文本?,c++,windows,timer,drawtext,C++,Windows,Timer,Drawtext,我在WM_定时器中使用了DrawText函数,但它不起作用。如何解决这个问题?谢谢大家! LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_CREATE: SetTimer(hwnd,23, 1000,NULL);

我在WM_定时器中使用了DrawText函数,但它不起作用。如何解决这个问题?谢谢大家!

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    switch (message)
    {
    case WM_CREATE:
        SetTimer(hwnd,23, 1000,NULL);
        break;

    //case WM_TIMER: ***** dont work *****
    case WM_PAINT: // ***** work, but used 25% CPU *****
        {
        RECT rect;
        HFONT hFont;
        hdc = BeginPaint(hwnd, &ps);
        hFont = CreateFontA(16,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, VARIABLE_PITCH,TEXT("Arial"));
        SelectObject(hdc,hFont);
        SetRect(&rect, 3, 3, 90, 50);
        SetTextColor(hdc, RGB(0,0,255));

        time_t rawtime;
        struct tm * timeinfo;
        char buffer [80];

        time ( &rawtime );
        timeinfo = localtime ( &rawtime );
        strftime (buffer,80,"%I:%M:%S %p\n%m/%d/%Y",timeinfo);

        wchar_t wtext[30];
        mbstowcs(wtext, buffer, strlen(buffer)+1);//Plus null
        LPWSTR ptr = wtext;



        DrawTextW(hdc, ptr, -1,&rect, DT_NOCLIP | DT_CENTER);

        DeleteObject(hFont);

        InvalidateRect(hwnd, &rect, TRUE);
        UpdateWindow(hwnd);

        EndPaint(hwnd, &ps);
        break;
        }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, message, wparam, lparam);
    }
    return 0;
}

不要从
WM\u PAINT
调用
invalidate()

不要从
WM\u定时器
上绘画。可以(用
GetWindowDC()
而不是
BeginPaint()
来完成,但这不是一个好主意

相反,将
invalidate()
放在
WM\u计时器中,并将绘图代码放在
WM\u PAINT
中。正如@typ1232在注释中所说,您可以通过只创建一次字体来优化,但这并不是严格必要的


UpdateWindow()
调用通常是不必要的,除非您处于一个紧张的CPU循环中,需要立即显示窗口:如果失效是在计时器中完成的,并且超时时间不太短,则不需要它。但是如果超时时间很短,则可以强制重新绘制调用
UpdateWindow()
无效竖立()
之后,不要从
WM\u PAINT
调用
无效竖立()
更新窗口()
,否则将创建无限的重新绘制循环

不要使用
WM\u定时器进行绘制。可以使用
GetWindowDC()
而不是
BeginPaint()
进行绘制,但这不是一个好主意

相反,将
invalidate()
放在
WM\u计时器中,并将绘图代码放在
WM\u PAINT
中。正如@typ1232在注释中所说,您可以通过只创建一次字体来优化,但这并不是严格必要的


UpdateWindow()
调用通常是不必要的,除非您处于一个紧张的CPU循环中,需要立即显示窗口:如果失效是在计时器中完成的,并且超时时间不太短,则不需要它。但是如果超时时间很短,则可以强制重新绘制调用
UpdateWindow()
就在
invalidate()之后

您的WM\u定时器代码应该准备要绘制的字符串,保存它,然后调用Invalidate。WM\u定时器代码不能直接绘制,原因之一是在WM\u定时器消息期间BeginPaint无法正常工作。BeginPaint仅在WM\u PAINT消息期间定义。因此WM\u定时器可以准备要绘制的数据,但随后使用请求生成WM_油漆


您还必须从WM\U绘制代码中删除InvalidateBurst和UpdateWindow调用。它们将导致绘制的无限循环。

您的WM\U计时器代码应该准备要绘制的字符串,保存它,然后调用InvalidateBurst。WM\U计时器代码不能直接绘制,原因之一是在WM\U绘制期间BeginPaint无法正常工作IMER message.BEGIPAINT仅在WM_PAINT消息期间定义。因此WM_TIMER可以准备要绘制的数据,但随后使用INVALIDATE请求生成WM_PAINT


您还必须从WM_PAINT代码中删除InvalidateBurst和UpdateWindow调用。它们将导致无限的绘制循环。

创建字体是非常CPU密集的工作。尝试只做一次,而不是在每个WM_PAINT事件中都做一次。调用
WM_计时器。
也是@typ1232所说的。创建字体是非常CPU密集的工作。试试看只做一次,而不是在每次WM_绘画活动上。让你的
WM_定时器
调用。还有@typ1232所说的。