Saturday, October 13, 2007

Where does Visual Studio fail?

When you create a new Win32 project in Visual C++ 2005, you get a message loop that looks like this:
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

So what's wrong with that? Probably the fact that the MSDN documentation for GetMessage specifically says not to write code that looks like that! This is what it does say:
Warning

Because the return value can be nonzero, zero, or -1, avoid code like this:

while (GetMessage( lpMsg, hWnd, 0, 0)) ...

The possibility of a -1 return value means that such code can lead to fatal application errors. Instead, use code like this:

BOOL bRet;

while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

Perhaps it doesn't make much difference in actuality, but you would have thought they would at least make the code in their template consistent with their own documentation (which comes with Visual Studio in the MSDN library, I might add..)

2 comments:

Anonymous said...

I noticed that too; it's been around since forever--except for one minor detail.
MSDN says not to use a simple while() loop when using GetMessage on a SPECIFIC window, as the possibility of having the window destroyed sometime in the loop's lifetime is a completely valid, if not likely issue.
However, if you're passing NULL for the window, then you lose that point of failure; the only other possible cause for a return value of -1 that the MSDN mentions is a bad parameter (in the form of a bad pointer to msg) passed to GetMessage...in which case your code would break anyway from the getgo.

It's an important difference; silly that MSDN doesn't point out that its caveat is only if you're GetMessaging a specific window. Which you generally don't, since you miss WM_QUIT messages.

DisplayNameHere said...

Those two instances are only examples given on MSDN though; there could very well be more cases, either way it would be wrong to assume otherwise because the documentation doesn't state that.