GetMessage()会在主消息循环中返回-1吗?

时间:2011-03-13 08:22:59

标签: c++ windows winapi

根据MSDN Library中的GetMessage API,当出现错误时,它可能会返回-1。该文档提供了应避免的常见错误的代码片段:

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

文件说:

  

-1返回值的可能性   意味着这样的代码可能导致致命   应用错误。相反,使用代码   像这样:

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

我的问题是,在每个示例代码中,包括从Microsoft Visual Studio创建的默认应用程序,主消息循环如下所示:

while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

请注意,上面的GetMessage的第二个参数是NULL。如果上面的代码有效,这是否意味着这里的GetMessage将永远不会返回-1,因此不需要处理-1的返回值?

4 个答案:

答案 0 :(得分:4)

您应该遵循GetMessage()的MSDN文档中指定的规则。这样做很轻松,并不是说你的代码中散布着大量的消息循环。

Visual Studio团队与Windows团队是分开的,他们犯的错误与其他人一样!

我认为我无法想象GetMessage()会返回错误,但这是错误处理的本质 - 这并不意味着您不应该正确处理错误。

答案 1 :(得分:3)

你提到的文件说:

  

如果有错误,则返回值为-1。例如,如果 hWnd 是无效的窗口句柄或 lpMsg 是无效指针,则函数将失败。

在第二个示例中,涵盖了这两种情况:msg是典型的堆栈分配结构,因此&msg始终是有效指针。 NULLhwnd参数中传递,是该参数的可接受值。 wMsgFilterMinwMsgFilterMax均为零,这也是有效组合。

因此GetMessage()在参数验证期间不会失败。文档没有明确提及它是否在其他情况下返回-1(例如,内存耗尽)。那就是说,我已经和你的第二个例子一样调用了GetMessage()一段时间了,我从来没有看到它返回-1并将我的消息循环变成一个无限循环。当然,你的里程可能会有所不同,但这样做似乎很安全。

答案 2 :(得分:3)

鉴于默认情况下VS会给你错误的代码,而且似乎没有人关心,这很可能会导致当前版本的Windows 中没有麻烦

GetMessage 的某些未来版本可能会返回-1。但是,由于现在错误的代码必须存在于如此多的现有应用程序中,这将破坏大量现有代码。鉴于微软致力于向后兼容,我认为他们不太可能改变许多程序所依赖的GetMessage的行为。

尽管如此,您仍应遵循文档。

答案 3 :(得分:3)

我的直觉(又名Raymond Chen通灵力量)告诉我,GetMessage(&msg, NULL, 0, 0)只会在极端罕见的灾难性故障(例如消息队列的损坏)的情况下返回-1。在这种情况下,测试它有点像在C ++程序中捕获std :: bad_alloc:当它发生时,它可能为时已晚。让流程挂起(通过忽略GetMessage()== -1)或死亡(通过不捕获bad_alloc)是可以接受的,除非当然所说的流程控制核电站。

这完全取决于你想要的正式程度。我会在商业应用程序中专门测试-1,但不是在为个人使用而编写的小实用程序中。