深入探讨MFC消息循环和消息泵
消息分为队列消息(进入线程的消息队列)和非队列消息(不进入线程的消息队列)。对于队列消息,最常见的是鼠标和键盘触发的消息,例如WM_MOUSERMOVE,WM_CHAR等消息;还有例如:WM_PAINT、WM_TIMER和WM_QUIT。当鼠标、键盘事件被触发后,相应的鼠标或键盘驱动程序就会把这些事件转换成相应的消息,然后输送到系统消息队列,由Windows系统负责把消息加入到相应线程的消息队列中,于是就有了消息循环(从消息队列中读取并派送消息)。还有一种是非队列消息,他绕过系统队列和消息队列,直接将消息发送到窗口过程。例如,当用户激活一个窗口系统发送WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。创建窗口时发送WM_CREATE消息。在后面你将看到,MS这么设计是很有道理的,以及他的整套实现机制。
这里讲述MFC的消息循环,消息泵。先看看程序启动时,怎么进入消息循环的:
_tWinMain ->AfxWinMain ->AfxWinInit ->CWinThread::InitApplication ->CWinThread::InitInstance ->CWinThread::Run |
非对话框程序的消息循环的事情都从这CWinThread的一Run开始...
第一部分:非对话框程序的消息循环机制。
//thrdcore.cpp // for tracking the idle time state // acquire and dispatch messages until a WM_QUIT message is received. // phase2: pump messages while available // reset "no idle" state after pumping "normal" message } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)); ASSERT(FALSE); // not reachable |
这是一个无限循环,他的退出条件是收到WM_QUIT消息:
if (!PumpMessage()) |
在PumpMessage中,如果收到WM_QUIT消息,那么返回FALSE,所以ExitInstance()函数执行,跳出循环,返回程序的退出代码。所以,一个程序要退出,只用在代码中调用函数
VOID PostQuitMessage( int nExitCode )。指定退出代码nExitCode就可以退出程序。
下面讨论一下这个函数Run的流程,分两步:
1,第一个内循环phase1。bIdle代表程序是否空闲。他的意思就是,如果程序是空闲并且消息队列中没有要处理的消息,那么调用虚函数OnIdle进行空闲处理。在这个处理中将更新UI界面(比如工具栏按钮的enable和disable状态),删除临时对象(比如用FromHandle得到的对象指针。由于这个原因,在函数之间传递由
相关新闻>>
- 发表评论
-
- 最新评论 更多>>