You can send your main thread WM_TIMER messages. The lParam for the message is the address of a callback function, or you can leave it NULL and handle it yourself in your message pump.
In this example, we are sending the timer to the thread message pump, there is no requirement to have a window associated with the timer.
UINT timer;
VOID CALLBACK Timer(HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime
)
{
KillTimer(0, timer);
}
timer=SetTimer(0, // window handle
0, // id of the timer message, leave 0 in this case
10000, // millis
Timer // callback
);
// pump messages
while (GetMessage) etc...
The Timer callback will be called by DispatchMessage. This question reminded me of the recent ONT.