资源描述:
《深入探讨mfc消息循环和消息泵》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、深入探讨MFC消息循环和消息泵首先,应该清楚MFC的消息循环(::GetMessage,::PeekMessage),消息泵(CWinThread::PumpMessage)和MFC的消息在窗口之间的路由是两件不同的事情。在MFC的应用程序中(应用程序类基于CWinThread继承),必须要有一个消息循环,他的作用是从应用程序的消息队列中读取消息,并把它派送出去(::DispatchMessage)。而消息路由是指消息派送出去之后,系统(USER32.DLL)把消息投递到哪个窗口,以及以后消息在窗
2、口之间的传递是怎样的。 消息分为队列消息(进入线程的消息队列)和非队列消息(不进入线程的消息队列)。对于队列消息,最常见的是鼠标和键盘触发的消息,例如WM_MOUSERMOVE,WM_CHAR等消息;还有例如:WM_PAINT、WM_TIMER和WM_QUIT。当鼠标、键盘事件被触发后,相应的鼠标或键盘驱动程序就会把这些事件转换成相应的消息,然后输送到系统消息队列,由Windows系统负责把消息加入到相应线程的消息队列中,于是就有了消息循环(从消息队列中读取并派送消息)。还有一种是非队列消息,他绕
3、过系统队列和消息队列,直接将消息发送到窗口过程。例如,当用户激活一个窗口系统发送WM_ACTIVATE,WM_SETFOCUS,andWM_SETCURSOR。创建窗口时发送WM_CREATE消息。在后面你将看到,MS这么设计是很有道理的,以及他的整套实现机制。 这里讲述MFC的消息循环,消息泵。先看看程序启动时,怎么进入消息循环的:_tWinMain->AfxWinMain->AfxWinInit->CWinThread::InitApplication->CWinThread::InitIns
4、tance->CWinThread::Run 非对话框程序的消息循环的事情都从这CWinThread的一Run开始... 第一部分:非对话框程序的消息循环机制。//thrdcore.cpp//mainrunningroutineuntilthreadexitsintCWinThread::Run(){ ASSERT_VALID(this); //fortrackingtheidletimestate BOOLbIdle=TRUE; LONGlIdleCount=0; //acquireanddis
5、patchmessagesuntilaWM_QUITmessageisreceived. for(;;) { //phase1:checktoseeifwecandoidlework while(bIdle&& !::PeekMessage(&m_msgCur,NULL,NULL,NULL,PM_NOREMOVE)) { //callOnIdlewhileinbIdlestate if(!OnIdle(lIdleCount++))locatedintheTomb,DongShenJiaban
6、g,deferthenextdayfocusedontheassassination.Linping,Zhejiang,1ofwhichliquorwinemasters(WuzhensaidinformationisCarpenter),whogotAfewbayonets,duetomissedfatal,whennightcame bIdle=FALSE;//assume"noidle"state } //phase2:pumpmessageswhileavailable do { /
7、/pumpmessage,butquitonWM_QUIT if(!PumpMessage()) returnExitInstance(); //reset"noidle"stateafterpumping"normal"message if(IsIdleMessage(&m_msgCur)) { bIdle=TRUE; lIdleCount=0; } }while(::PeekMessage(&m_msgCur,NULL,NULL,NULL,PM_NOREMOVE)); }
8、 //无限循环,退出条件是收到WM_QUIT消息。 ASSERT(FALSE); //notreachable}这是一个无限循环,他的退出条件是收到WM_QUIT消息:if(!PumpMessage()) returnExitInstance(); 在PumpMessage中,如果收到WM_QUIT消息,那么返回FALSE,所以ExitInstance()函数执行,跳出循环,返回程序的退出代码。所以,一个程序要退出,只用在代码中调用函数 VOIDPostQuitMessa