根据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的返回值?
答案 0 :(得分:4)
您应该遵循GetMessage()
的MSDN文档中指定的规则。这样做很轻松,并不是说你的代码中散布着大量的消息循环。
Visual Studio团队与Windows团队是分开的,他们犯的错误与其他人一样!
我认为我无法想象GetMessage()
会返回错误,但这是错误处理的本质 - 这并不意味着您不应该正确处理错误。
答案 1 :(得分:3)
你提到的文件说:
如果有错误,则返回值为-1。例如,如果 hWnd 是无效的窗口句柄或 lpMsg 是无效指针,则函数将失败。
在第二个示例中,涵盖了这两种情况:msg
是典型的堆栈分配结构,因此&msg
始终是有效指针。 NULL
在hwnd
参数中传递,是该参数的可接受值。 wMsgFilterMin
和wMsgFilterMax
均为零,这也是有效组合。
因此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,但不是在为个人使用而编写的小实用程序中。