PostQuitMessage和PeekMessage的诡异行径
//=====================================================================
//TITLE:
// PostQuitMessage和PeekMessage的诡异行径
//AUTHOR:
// norains
//DATE:
// Monday 8- March-2010
//Environment:
// WINDOWS CE 5.0
// WINDOWS XP
//=====================================================================
在将程序从WinCE移植到WinXP中,发现之前移植运行得正常的程序,居然无法退出了。经过排查,发现问题出在这段代码:
消息循环的代码也很简单:
代码意思很简单,如果是CMD_EXIT命令的话,就直接发送PostQuitMessage消息,退出消息循环。而调用PeekMessage的目的也非常简单,就是去掉鼠标左键消息。因为在处理第一次鼠标按键的过程中,可能用户还在不停地点击相同的按钮,从而导致同一个按钮的不停的滞后响应。
这段代码结构在WinCE5.0下是没有任何问题的,一切跑得非常正常顺畅。但如果是在WinXP下,就迥然不同了--GetMessage看起来根本就没有接收到WM_QUIT消息!
说无法接收其实也不完全对,如果你在PostQuitMessage这行代码设置断点,停在断点时,然后再按F5让其继续全速奔跑,那么程序又能正常退出了。
是不是很诡异?那时候PeekMessage没调用,只是在PostQuitMessage这里暂停了一下,就一切正常了。
最后真正的原因我也没有找到,因为我也没有WinXP的内核代码。但根据过往的经验推测,这个应该是多线程的原因。很可能是WinCE和WinXP在消息处理模型不一样的缘故。WinCE可能为了节约资源,消息是一个一个进行处理;而WinXP不同部分的消息,可能是分为多个线程来进行处理。
以我们的代码进行推测,当正常运行时,在我们调用PostQuitMessage后,WM_QUIT还没有进入准备的消息队列。而调用PeekMessge去除鼠标左键消息的时候,同时也将WM_QUIT从队列中移除。
而在PostQuitMessage设置断点的情况可能有点不同。跑过这句后,可能WM_QUIT已经进入了准备的消息队列,所以之后的结果就如我们之前所预想的。
不过,这也只是我的推测,究竟实际是否如此,还望大家指教。