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:
- When someone opens your menu, a message is sent to your window telling it to draw the window.
DispatchMessage()
sends the message to your WndProc
, like all other messages.
- Since you don't handle this message, it is passed to Windows (since your
WndProc
more than likely calls DefWindowProc
)
- As the default operation, Windows draws the menu and starts another default message loop which will not call
DoSomething()
- This loop fetches the messages destined for your application and dispatches them to your application by calling
WndProc
, so your application doesn't freeze and continues to operate (minus the DoSomething()
call).
- Once the menu is closed, control will be returned to your message loop (only at this point will the
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).