Reputation:
I'm developing an application that looks mainly like this:
while (true)
{
while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
DoSomething();
Sleep(1);
}
What I noticed is that DoSomething() doesn't get called when I click on the menu bar (displaying menu options). I've observed that DispatchMessage call blocks the messae loop until I get out of the menu bar!
How could I avoid this behaviour??
Thanks!
Upvotes: 3
Views: 2266
Reputation: 4022
The reason why is because Windows takes over the processing of messages when something like an application menu or message box is displayed, and that message loop which Windows uses won't call your DoSomething()
method. This may be hard to visualize, so I'll try to step through what is happening:
DispatchMessage()
sends the message to your WndProc
, like all other messages.WndProc
more than likely calls DefWindowProc
)DoSomething()
WndProc
, so your application doesn't freeze and continues to operate (minus the DoSomething()
call). DispatchMessage()
call from the very beginning return)In other words, when a menu is displayed, your message loop is replaced by a default one which looks like this (for example)
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
which, as you can see, won't call your DoSomething()
method.
To test this, try pausing your code in a debugger when no menu is displayed, and while one is. If you see the callstack, you will see that when a menu is displayed, messages are being processed by a Windows message loop, not by yours.
The only workaround I can think of (without multithreading) is if you start a timer and handle the WM_TIMER
message by calling DoSomething()
, but that would not be a perfect solution (since I presume your intent is to call DoSomething()
only when there are no messages left to process).
Upvotes: 3
Reputation: 5935
Spin off Translating and Dispatching the Msg into a separate Thread.
As long as DoSomething isn't dependent on Dispatching the Msg.
Although I might want to understand why the Dispatch is blocking; is this expected normal behavior?
Upvotes: -1