我在WM_TIMER中使用了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;
}
最佳答案
不要从InvalidateRect()
调用UpdateWindow()
或WM_PAINT
,否则将创建无限循环的重画。
不要从WM_TIMER
绘画。可以(用GetWindowDC()
代替BeginPaint()
来完成,但这不是一个好主意。
而是将InvalidateRect()
放在WM_TIMER
中,并将图形代码保留在WM_PAINT
中。您可以优化,就像@ typ1232在评论中说的那样,只需创建一次字体就可以了,但这不是绝对必要的。
通常,不需要UpdateWindow()
调用,除非您处于紧密的CPU循环中并且需要立即显示该窗口:如果无效是在计时器中完成的,并且超时时间不太短,则不需要它。但是,如果您的超时时间很短,则可以在UpdateWindow()
之后强制重绘调用InvalidateRect()
。