Frage

I have encountered a, so it seems to me, strange behaviour of the WinAPI. In my program I am setting a timer for the window with

::SetTimer(window_handle, timer_id, 10, NULL);

and handle the WM_TIMER message in my window procedure. To reduce the amount of cpu time needed I am also using the ::WaitMessage function in my message pump. Turns out now that, as long as I have the ::WaitMessage function there, the WM_TIMER messages just stop coming after a while. If I remove it from my message pump everything works just fine as expected.

Now I wonder wether I set up my timer wrong or if this is standard behaviour of ::WaitMessage. Searching MSDN and the web did not give me an idea why this is like this.

Here is the message pump I use:

while(true) {
    if(GetMessage(&msg, _window_handle, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    } else { 
        return 0; 
    }

    WaitMessage();
}

Hope that someone can clear this up for me.

War es hilfreich?

Lösung

Yes, this will randomly fail to process more timer messages. A pretty hard rule for WaitMessage() is that the message queue should be empty before you call it. If it isn't empty then any messages left in the queue are marked as "seen" and WaitMessage() ignores them.

So the failure scenario is having two messages in the queue, say a mouse message and a timer message. You get the mouse message but leave the timer message. No additional timer message is generated since you haven't processed the pending one. The combination of GetMessage + WaitMessage is very troublesome, you'd have to use PeekMessage instead.

Just remove WaitMessage(), it serves no useful purpose here.

Andere Tipps

In addition to what Hans Passant said, you should reword the code. WaitMessage doesn't play well with GetMessage, use PeekMessage instead and keep WaitMessage only in the alternative code path (else), like so:

while( true )
{
    if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    else
    {
        WaitMessage();
    }
}

WaitMessage allows a thread to sleep until a message is in the queue.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top