GetMessage函数第二个参数的问题

转载地址:https://blog.csdn.net/shyrgst/article/details/7322268

今天在学习VC++深入详解的过程中发现当GetMessage的Hwnd参数不为NULL的时候,会导致应用程序接收不到WM_QUIT消息,此时关闭窗口时,窗口可以正常析构但是应用程序不会正常退出,必须通过任务管理器结束。原因如下:

from:http://fyca.blog.163.com/blog/static/129633842006227134350/

HWND hWnd = CreateWindowEx(...);

MSG msg;

while( TRUE ) {
   if( GetMessage( &msg, NULL, 0, 0 ) == FALSE )
      break;
   TranslateMessage( &msg );
   DispatchMessage( &msg );
}

消息循环这样写当然没问题, 但为什么GetMessage的第二个参数不能是窗口的句柄hWnd呢, 毕竟当前程序只有一个窗口啊? 如果是hWnd, 程序运行时没有任何问题, 但是当你将窗口关闭后会发现程序并未真正退出, 而且此时cpu占用为100%, Why?

MSDN中解释如下:

当GetMessage第二个参数为NULL时:
GetMessage retrieves messages for any window that belongs to the calling thread and thread messages posted to the calling thread using the PostThreadMessage function.

中文翻译:GetMessage取得 那些属于调用线程的窗口的消息 和 通过PostThreadMessage函数投递(发送)到调用线程的线程消息**.

**这样问题就明白了, GetMessage需要检索到WM_QUIT返回一个FALSE结束消息循环, 而WM_QUIT是通过PostQuitMessage(0){IN WM_DESTROY OF WindowProc}发送, 属于线程消息, 而非普通的窗口消息. 如果在GetMessage中用hWnd而不是NULL, 虽然WM_QUIT 消息仍会出现在程序的消息队列中,但GetMessage却无法检索到, 而且此时窗口已经被销毁了, 如果还想取得hWnd的窗口消息, 只可能发生错误( cpu占用100%, 死循环? )**.

也适用于PeekMessage

所以,当窗口被销毁的时候,窗口的句柄自然也就是无效句柄了,那么GetMessage将返回-1。所以循环为死循环。

在MSDN中,推荐的代码写法是这样的,

Return Values

If the function retrieves a message other than WM_QUIT, the return value is nonzero.

If the function retrieves the WM_QUIT message, the return value is zero.

If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle or lpMsg is an invalid pointer. To get extended error information, call GetLastError.

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, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}


猜你喜欢

转载自blog.csdn.net/songsong2017/article/details/83507314