我做了一个小例子,在对话框类的PreTranslateMessage中,返回FALSE。在主窗口显示这个非模式对话框,在对话框拥有焦点的时候,仍然能够激活主窗口的快捷键。 总之,整个框架就是让每个消息的目标窗口(包括他的父窗口)都有机会参与消息到来之前的处理。呵呵~ 至此,非对话框的消息循环和消息泵的机制就差不多了。这个机制在一个无限循环中,不断地从消息队列中获取消息,并且保证了程序的线程消息能够得到机会处理,窗口消息在预处理之后被发送到相应的窗口处理过程。那么,还有一点疑问,为什么要一会儿调用::PeekMessage,一会儿调用::GetMessage呢,他们有什么区别? NOTE:一般来说,GetMessage被设计用来高效地从消息队列获取消息。如果队列中没有消息,那么函数GetMessage将导致线程休眠(让出CPU时间)。而PeekMessage是判断消息队列中如果没有消息,它马上返回0,不会导致线程处于睡眠状态。 在上面的phase1第一个内循环中用到了PeekMessage,它的参数PM_NOREMOVE表示并不从消息队列中移走消息,而是一个检测查询,如果消息队列中没有消息他立刻返回0,如果这时线程空闲的话将会引起消息循环调用OnIdle处理过程(上面讲到了这个函数的重要性)。如果将::PeekMessage改成::GetMessage(***),那么如果消息队列中没有消息,线程将休眠,直到线程下一次获得CPU时间并且有消息出现才可能继续执行,这样,消息循环的空闲时间没有得到应用,OnIdle也将得不到执行。这就是为什么既要用::PeekMessage(查询),又要用::GetMessage(做实际的工作)的缘故。 第二部分: 对话框程序的消息循环机制 基于对话框的MFC工程和上面的消息循环机制不一样。实际上MFC的对话框工程程序就是模式对话框。他和上面讲到的非对话框程序的不同之处,主要在于应用程序对象的InitInstance()不一样。
NOTE: InitInstance函数返回FALSE,由最上面程序启动流程可以看出,CWinThread::Run是不会得到执行的。也就是说,上面第一部分说的消息循环在对话框中是不能执行的。实际上,对话框也有消息循环,她的消息循环在CDialog::DoModal()虚函数中的一个RunModalLoop函数中。
|
正在阅读:深入探讨MFC消息循环和消息泵深入探讨MFC消息循环和消息泵
2004-05-31 10:37
出处:CSDN
责任编辑:linjixiong
键盘也能翻页,试试“← →”键