I am developing an app on Windows using the WinAPI. This app has a UI built using my own framework. Some views of this UI are animated and need to be refreshed over time.
Prior to implementing animated views, I was simply doing the following:
while (GetMessage(&msg, NULL, 0, 0)) {
// if (msg.message == WM_QUIT) {
// break;
// }
TranslateMessage(&msg);
DispatchMessage(&msg);
}
I’ve been using GetMessage instead of PeekMessage primarily for CPU resource savings. Redrawing of the UI and its elements is done in the WndProc function. When I receive, say, a WM_MOUSEMOVE event, I update the UI and trigger a redraw (all GPU-based).
Now, with animated views, I need something like the following (pseudo-code):
for (;;) {
for (animation in app->timeline) {
animation->tick(current_time, ...);
}
}
In this naive version, I have to iterate over all animations in the timeline to ensure they run, even if the timeline contains no active animations. This keeps the main thread running continuously, even when there’s no animation, which is not ideal. Consequently, I’d need to switch to using PeekMessage:
while (!done) {
for (animation in app->timeline) {
animation->tick(current_time, ...);
}
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
done = true;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
If I want to keep using GetMessage, what’s a good way to handle UI animations?
- Should I post a custom message like
MSG_START_ANIMATIONwhen an animation starts, which I would then process inWndProc? This could trigger a timer (viaSetTimer) that would generate aWM_TIMERmessage every 1/60th of a second. - Or is it better to run the UI animation in a separate thread and implement a similar scheduling system to
GetMessage, where the thread sleeps when there’s no work to do? - I should just stick to
PeekMessageand process the UI animation event on every iteration and not care about CPU usage? - Make my own queue messaging system like Chromium does which would include both my animation UI events + the native Windows messages?
I’m curious how others have approached this in the past and whether there are alternatives to the two methods I’m considering.
MsgWaitForMultipleObjectsExin combination with waitable timer objects? Also, what's the specific reason for using the "alertable" (-Ex) version?MWMO_INPUTAVAILABLE, also newer.