特殊的WM_QUIT消息

发送WM_QUIT消息可以让Window程序关闭,但经测试用下面程序却无法达到目的:

CWnd *pWnd = CWnd::FindWindow(NULL, “My Window”);

HWND hWnd = pWnd->GetSafeHwnd();

SendMessage(hWnd, WM_QUIT, 0, 0);

而经过尝试,发现用PostMessage却可以:

PostMessage(hWnd, WM_QUIT, 0, 0);

不知道原因,当然要查MSDN了,看一下MSDN的介绍:

TheSendMessagefunction sends the specified message to a window or windows. It calls the window procedure for the specified window and does not return until the window procedure has processed the message.

ThePostMessagefunction places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.

MSDN的解释上看,感觉SendMessagePostMessage更加安全,因为,SendMessage要等到窗体消息处理完才返回,而PostMessage发送消息后就立即返回,这更令人茫然。既然从这上面看不出SendMessage无法实现的原因,那么就从消息WM_QUIT上查。

TheWM_QUITmessage indicates a request to terminate an application and is generated when the application calls thePostQuitMessagefunction. It causes theGetMessagefunction to return zero.

当应用程序调用PostQuitMessage函数的时候, WM_QUIT消息终止一个程序的,它促使GetMessage函数返回0

可这里根本就没提SendMessage无法完成终止程序的原因。但在Remark中,却有这样一句:

Do not post theWM_QUITmessage using thePostMessagefunction; usePostQuitMessage。至于为什么,就得看PostQuitMessage做什么事了。现在不讨论为什么不让使用PostMessage发送WM_QUIT消息,但就为什么SendMessage无法完成PostMessage能完成的功能来做一下研究。

注意到WM_QUIT消息让消息循环终止归根结底是让GetMessage返回为0,而GetMessage函数是从消息对列里取一条消息,然后再返回,只能当消息为WM_QUIT时才返回0结束消息循环。再仔细看一下SendMessage的注释发现,SendMessage直接发送到窗口,并调用窗口处理程序,完成消息响应,即SendMessage根本就没有将消息发到消息对列中,因此GetMessage无法从消息对列中收到WM_QUIT的消息。而PostMessage却直接发送消息到消息对列中,然后立即返回,这一点点的区别就解决了我们上面的问题。

了解了这一点,就不难理解上面注释中说的为什么不让直接使用PostMessage来发送WM_QUIT消息来终止程序了。

另外需要注意的是,发送消息让对话框关闭,应该发送WM_CLOSE消息,这样可以让对话框完成它自身的资源释放回收。

你可能感兴趣的:(qui)