Reputation: 8025
I used DrawText function within WM_TIMER, but it dont work. How to fix this? Thank you!
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;
}
Upvotes: 0
Views: 1134
Reputation: 10415
Your WM_TIMER code should prepare the string to be drawn, save it and then call InvalidateRect. The WM_TIMER code can not draw directly, and one reason is that BeginPaint will not work properly during a WM_TIMER message. BeginPaint is only defined during a WM_PAINT message. So WM_TIMER can prepare the data to be drawn, but then use InvalidateRect to request that a WM_PAINT be generated.
You must also remove the InvalidateRect and UpdateWindow calls from the WM_PAINT code. They will cause an infinite loop of painting.
Upvotes: 2
Reputation: 98388
Do not call InvalidateRect()
or UpdateWindow()
from WM_PAINT
, or you will create an infinite loop of repaints.
Do not paint from the WM_TIMER
. It can be done (with GetWindowDC()
instead of BeginPaint()
but it isn't such a good idea.
Instead put the InvalidateRect()
in the WM_TIMER
and leave the drawing code in WM_PAINT
. You can optimize, as @typ1232 said in the comments, by creating the font only once, but that's not strictly necessary.
The UpdateWindow()
call should not generally be necessary, unless you are in a tight CPU loop and need to show the window just now: if the invalidation is done in a timer and the timeout is not too short you won't need it. But if your timeout is very short you can force the redraw calling UpdateWindow()
just after InvalidateRect()
.
Upvotes: 2