Entering the Message Loop
Once the main window is created and displayed, the WinMain function can begin its primary task, which is to read messages from the application queue and dispatch them to the appropriate window.
The system does not send input directly to an application. Instead, it places all mouse and keyboard input from the user into a message queue, along with messages posted by the system and other applications. The application must read the message queue, retrieve the messages, and dispatch them so that the window procedure can process them.
The Generic application uses the following message loop. Note that bRet is a variable of type BOOL.
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 )
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
The GetMessage function retrieves a message from the queue. The DispatchMessage function sends each message to the appropriate window procedure. The TranslateMessage function translates virtual-key message into character messages. In Generic, this is necessary to implement menu access keys.
See Also
Build date: 3/25/2010
...
#include "asssert.h"
...
MSG msg = {0};
for(;;)
{
assert(sizeof(int) >= sizeof(BOOL)); // int ok to receive return value of GetMessage()
int res = GetMessage(&msg, 0, 0, 0);
assert(res != -1); // can't be anything wrong with call to GetMessage()
if(res == 0)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
*******************************************************************************************************
Or use __int64 and cast return value if you want to be pedantic:
...
begin_message_loop0:
MSG msg = {0};
__int64 res = 0;
assert(sizeof(res) >= sizeof(BOOL)); // pedantically future proof
while((res = (__int64)GetMessage(&msg, 0, 0, 0)) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
assert(res != -1); // can't be anything wrong with GetMessage() unless undocumented issue,
if(res == -1)
{
assert(IsValidWritePtr(&msg, sizeof(msg)));
goto begin_message_loop0; // must be an undocumented OS issue,
// in which case we almost certainly want to carry on anyway
}
********************************************************************************************************
Bottom line, the majority of - if not all - applications that run on Windows are not Real Time Systems that fly Jets or control the ABS or Traction Control systems on a car; there is no imperative to always handle failure gracefully. Programs crash sometimes, so don't go overboard with the error checking, except where it is appropriate to do so.
Bear in mind also that the message loop is what is being executed between messages in any windows application, so if you're checking for -1 with every GetMessage() call, you're introducing an additional comparison and conditional jump into code that is executed very often. So, unless you are passing specific params to GetMessage() and you cannot be certain of their validity, don't bother checking for -1, just make sure your MSG struct is valid.
So, for a main message loop in WinMain(), using <code>MSG msg = {0}; while(GetMessage(&msg, 0, 0, 0)){...}</code> is actually fine because you know all the params are valid, so GetMessage() has no reason to fail. And if it does, the most likely culprit would be corruption of the stack around your MSG object which would almost certainly result in a crash regardless of whether you check the return value for == -1, and is indicitive of a much more serious problem in any case.
- 12/23/2011
- mcaizcm3