Windows消息响应机制之四:PostQuitMessage和GetMessage函数 .
来源:互联网 发布:北斗神拳 崇明 岛 知乎 编辑:程序博客网 时间:2024/06/01 22:46
Windows是消息驱动的操作系统。在Windows环境下编程必须熟练掌握Windows消息响应机制。
今天在练习Win32编程时碰到一个关于GetMessage函数的问题。这个问题之前一直没有引起过我的注意,但是今天
在网上搜索发现这个问题很多程序员都跟我一样处于一知半解的状态。
在Win32应用程序的主函数中有一段消息循环收发的代码:
while (GetMessage(&Msg, hWnd, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
在Debug环境下启动程序后点击关闭按钮可以正常关闭掉窗口,但是VS2008却无法正常退出执行状态(即应用程序没有正常返回)。于是我按如下步骤进行了Debug:
(1).在消息处理函数中WM_DESTORY的处理中设置断点,点击关闭按钮case WM_DESROTY代码段可以执行;
(2).当程序执行到case WM_DESROTY代码段之后再在主函数的TranslateMessage(&Msg)处设置断点
(3).按下F5发现程序可以执行到TranslateMessage(&Msg)处。
经过上述步骤Debug后发现当在WM_DESTORY消息处理过程中调用PostQuitMessage(0)函数后程序的消息循环代码段可以继续执行,但是按MSDN的描述PostQuitMessage函数会往线程的消息队列中插入一个WM_QUIT消息,而GetMessage函数在收到WM_QUIT消息后会返回一个非正数。
后来在网上搜索网友克塞前来拜访的一段解释:
对PostQuitMessage而言,它实际上并不发送WM_QUIT消息,他所做的实际是设置一些特殊的系统标志,而队列存取体系根据这个标志并结合一些比较复杂的算法来决定在某时某处引发实际的WM_QUIT。当算法临界时,GetMessage(hwnd)照样能获取WM_QUIT。而如果你PostThreadMessage(WM_QUIT),那么一个实际的WM_QUIT消息会被队列,GetMessage(hwnd)永远不会获得这个退出消息。一个最简单的满足算法要求的实验可以是这样:你在WM_CLOSE消息里PostQuitMessage,然后在启动程序后,首先移动窗口,然后关闭窗口,则程序能够正常退出,设置断点调试可以发现,GetMessage(hwnd)确实捕获了这个理论上发给线程队列的退出消息,并且打印内存栈可以发现,消息本身确实是发给线程队列而非窗口队列的。反之,如果你先使hwnd失效,则无论你如何操作,GetMessage(hwnd)永远不会收到退出消息。所以总结起来说,最终能否退出首先取决于hwnd是否失效,虽然这并不是能解释这个问题的根本原因,但至少是一个正确的部分表象原因。
现阶段由于我个人的水平还无法鉴别其真伪,所以这段解释暂且先记录下来作为日后的学习参考。
今天在练习Win32编程时碰到一个关于GetMessage函数的问题。这个问题之前一直没有引起过我的注意,但是今天
在网上搜索发现这个问题很多程序员都跟我一样处于一知半解的状态。
在Win32应用程序的主函数中有一段消息循环收发的代码:
while (GetMessage(&Msg, hWnd, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
在Debug环境下启动程序后点击关闭按钮可以正常关闭掉窗口,但是VS2008却无法正常退出执行状态(即应用程序没有正常返回)。于是我按如下步骤进行了Debug:
(1).在消息处理函数中WM_DESTORY的处理中设置断点,点击关闭按钮case WM_DESROTY代码段可以执行;
(2).当程序执行到case WM_DESROTY代码段之后再在主函数的TranslateMessage(&Msg)处设置断点
(3).按下F5发现程序可以执行到TranslateMessage(&Msg)处。
经过上述步骤Debug后发现当在WM_DESTORY消息处理过程中调用PostQuitMessage(0)函数后程序的消息循环代码段可以继续执行,但是按MSDN的描述PostQuitMessage函数会往线程的消息队列中插入一个WM_QUIT消息,而GetMessage函数在收到WM_QUIT消息后会返回一个非正数。
后来在网上搜索网友克塞前来拜访的一段解释:
对PostQuitMessage而言,它实际上并不发送WM_QUIT消息,他所做的实际是设置一些特殊的系统标志,而队列存取体系根据这个标志并结合一些比较复杂的算法来决定在某时某处引发实际的WM_QUIT。当算法临界时,GetMessage(hwnd)照样能获取WM_QUIT。而如果你PostThreadMessage(WM_QUIT),那么一个实际的WM_QUIT消息会被队列,GetMessage(hwnd)永远不会获得这个退出消息。一个最简单的满足算法要求的实验可以是这样:你在WM_CLOSE消息里PostQuitMessage,然后在启动程序后,首先移动窗口,然后关闭窗口,则程序能够正常退出,设置断点调试可以发现,GetMessage(hwnd)确实捕获了这个理论上发给线程队列的退出消息,并且打印内存栈可以发现,消息本身确实是发给线程队列而非窗口队列的。反之,如果你先使hwnd失效,则无论你如何操作,GetMessage(hwnd)永远不会收到退出消息。所以总结起来说,最终能否退出首先取决于hwnd是否失效,虽然这并不是能解释这个问题的根本原因,但至少是一个正确的部分表象原因。
现阶段由于我个人的水平还无法鉴别其真伪,所以这段解释暂且先记录下来作为日后的学习参考。
- Windows消息响应机制之四:PostQuitMessage和GetMessage函数
- Windows消息响应机制之四:PostQuitMessage和GetMessage函数 .
- Windows消息响应机制之四:PostQuitMessage和GetMessage函数
- Windows 消息响应机制之二:消息
- Windows 消息响应机制之二:消息 .
- 深入GetMessage,PeekMessage以及Windows消息机制
- 深入GetMessage,PeekMessage以及Windows消息机制
- Windows消息响应机制
- Windows消息响应机制
- Windows消息响应机制之三:线程与消息队列
- Windows消息响应机制之三:线程与消息队列 .
- Windows消息响应机制之五:MFC消息响应机制分析
- windows消息响应机制之一:消息分析器
- windows消息响应机制之一:消息分析器
- C++ windows消息机制和入口函数
- Windows 线程消息队列和GetMessage实现内幕
- Windows 消息GetMessage伪代码
- VC编程Windows消息处理机制、阻塞试验、SetTimer、MessageBox、小心消息响应处理函数
- CString转char * ,string
- Windows消息响应机制之三:线程与消息队列 .
- STM32F4之FPU性能的充分发挥-设置要点
- BSTR,CString,LPCTSTR三者之间的转化
- 程序学习-错误的学习方法及解决方法
- Windows消息响应机制之四:PostQuitMessage和GetMessage函数 .
- C#/.NET主线程与子线程之间的关系
- 第三届蓝桥杯Java高职组决赛第四题
- ruby哈希表
- epoll
- Java之枚举(Enum)
- erlang 关于异常
- 2013年7月最新Windows市场份额
- C# Socket编程