Как нарисовать текст с таймером?

Я использовал функцию DrawText в WM_TIMER, но она не работает. Как это исправить? Спасибо!

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;
}

0

Решение

Не звони InvalidateRect() или же UpdateWindow() от WM_PAINTИли вы создадите бесконечный цикл перекрашиваний.

Не рисовать с WM_TIMER, Это Можно быть сделано (с GetWindowDC() вместо BeginPaint() но это не такая хорошая идея.

Вместо этого поставьте InvalidateRect() в WM_TIMER и оставить код для рисования в WM_PAINT, Вы можете оптимизировать, как сказал @ typ1232 в комментариях, создав шрифт только один раз, но это не является строго обязательным.

UpdateWindow() вызов обычно не требуется, если только вы не находитесь в тесном цикле ЦП и не хотите показывать окно только сейчас: если аннулирование выполнено в таймере и тайм-аут не слишком короткий, он вам не понадобится. Но если ваш тайм-аут очень короткий, вы можете вызвать перерисовку UpdateWindow() сразу после InvalidateRect(),

2

Другие решения

Ваш код WM_TIMER должен подготовить строку для рисования, сохранить ее и затем вызвать InvalidateRect. Код WM_TIMER не может быть нарисован напрямую, и одна из причин заключается в том, что BeginPaint не будет работать должным образом во время сообщения WM_TIMER. BeginPaint определяется только во время сообщения WM_PAINT. Таким образом, WM_TIMER может подготовить данные для рисования, но затем использовать InvalidateRect, чтобы запросить создание WM_PAINT.

Вы также должны удалить вызовы InvalidateRect и UpdateWindow из кода WM_PAINT. Они вызовут бесконечный цикл покраски.

2

По вопросам рекламы [email protected]