C++ 如何使用计时器绘制文本?
我在WM_定时器中使用了DrawText函数,但它不起作用。如何解决这个问题?谢谢大家!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);
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所说的。