深入剖析WTL—WTL消息循环机制详解
2007-10-08 14:05
513 查看
[align=left]消息过滤[/align]
首先看一下CMessageLoop的核心逻辑CMessageLoop.Run()的代码:
在上面的代码中,有三个需要注意的地方。
消息循环中,首先调用PeekMessage()判断消息队列中是否有消息。如果没有,则调用OnIdle()函数。这就是调用空闲处理。
第二个注意点是,如果有消息,则调用GetMessage()得到消息。然后做判断,如果是错误返回,则对消息并不进行处理。然后再判断是否是WM_QUIT消息,如果是,则退出消息循环,从而结束该界面线程。
接下来是第三个注意点。在TranslateMessage()消息之前,调用了成员函数PreTranslateMessage()。这为在TranslateMessage()之前对消息进行处理提供了机会。
PreTranslateMessage()会遍历CMessageLoop中所有CMessageFilterd对象的PreTranslateMessage()函数,直到其中一个返回为TRUE或它们都返回为FALSE。当有一个返回为TRUE时,即对消息处理了,那么,就不再调用TranslateMessage(),而是进入下一个循环。
这种消息过滤机制提供了一种在不同窗口之间传递消息的机制。
CMessageFilter是一个C++的接口,即只定义了抽象虚拟函数。
这样,任何类想要实现消息过滤,只需实现这个接口。在C++中就采用继承。然后再实现PreTranslateMessage()函数即可。
ATL/WTLAppWizard生成的框架窗口中实现PreTranslateMessage()的代码如下:
这种消息过滤机制的好处是任何实现了CMessageFilter接口的对象,都可以接受消息过滤。
程序通过AddMessageFilter()和RemoveMessageFilter()把这些对象加入到CMessageLoop中。
[align=left]空闲处理[/align]
空闲处理的机制和消息过滤类似。这里不再介绍。我们要把主要经历放在WTL的框架窗口分析上。稍后,我们将进入这部分内容。
首先看一下CMessageLoop的核心逻辑CMessageLoop.Run()的代码:
intCMessageLoop.Run() { BOOLbDoIdle=TRUE; intnIdleCount=0; BOOLbRet; for(;;) { while(!::PeekMessage(&m_msg,NULL,0,0,PM_NOREMOVE)&& bDoIdle) { if(!OnIdle(nIdleCount++)) bDoIdle=FALSE; } bRet=::GetMessage(&m_msg,NULL,0,0); if(bRet==-1) { ATLTRACE2(atlTraceUI,0,_T("::GetMessagereturned-1(error)/n")); continue; //error,don'tprocess } elseif(!bRet) {ATLTRACE2(atlTraceUI,0,_T("CMessageLoop::Run-exiting/n")); break; //WM_QUIT,exitmessageloop } if(!PreTranslateMessage(&m_msg)) { ::TranslateMessage(&m_msg); ::DispatchMessage(&m_msg); } if(IsIdleMessage(&m_msg)) { bDoIdle=TRUE; nIdleCount=0; }} return(int)m_msg.wParam; } |
消息循环中,首先调用PeekMessage()判断消息队列中是否有消息。如果没有,则调用OnIdle()函数。这就是调用空闲处理。
第二个注意点是,如果有消息,则调用GetMessage()得到消息。然后做判断,如果是错误返回,则对消息并不进行处理。然后再判断是否是WM_QUIT消息,如果是,则退出消息循环,从而结束该界面线程。
接下来是第三个注意点。在TranslateMessage()消息之前,调用了成员函数PreTranslateMessage()。这为在TranslateMessage()之前对消息进行处理提供了机会。
PreTranslateMessage()会遍历CMessageLoop中所有CMessageFilterd对象的PreTranslateMessage()函数,直到其中一个返回为TRUE或它们都返回为FALSE。当有一个返回为TRUE时,即对消息处理了,那么,就不再调用TranslateMessage(),而是进入下一个循环。
这种消息过滤机制提供了一种在不同窗口之间传递消息的机制。
CMessageFilter是一个C++的接口,即只定义了抽象虚拟函数。
classCMessageFilter {public: virtualBOOLPreTranslateMessage(MSG*pMsg)=0;}; |
ATL/WTLAppWizard生成的框架窗口中实现PreTranslateMessage()的代码如下:
BOOLCMainFrame::PreTranslateMessage(MSG*pMsg) {if(CFrameWindowImpl<CMainFrame> ::PreTranslateMessage(pMsg)) returnTRUE; returnm_view.PreTranslateMessage(pMsg);} |
程序通过AddMessageFilter()和RemoveMessageFilter()把这些对象加入到CMessageLoop中。
[align=left]空闲处理[/align]
空闲处理的机制和消息过滤类似。这里不再介绍。我们要把主要经历放在WTL的框架窗口分析上。稍后,我们将进入这部分内容。
相关文章推荐
- 深入剖析WTL—WTL消息循环机制详解
- 深入剖析WTL—WTL消息循环机制详解
- 深入剖析WTL—WTL消息循环机制详解
- 深入剖析Android消息机制原理
- Android 消息机制之 handler、messageQueue、looper深入剖析
- 【VC++游戏开发#一】深入剖析MFC的WinMain和消息机制
- Android 消息循环机制之ThreadLocal 类详解
- 前端基础进阶(十二):深入核心,详解事件循环机制
- 深入剖析Android消息机制
- Android[中级教程] 深入剖析Android消息机制
- 深入剖析MFC中对于Windows消息处理、运行机制
- 深入核心,详解事件循环机制
- Android[中级教程] 深入剖析Android消息机制
- Android异步消息机制Handler详解,源码剖析(API 23)
- 安卓中的消息循环机制Handler及Looper详解
- 深入Android的消息机制源码详解~Handler,MessageQueue与Looper关系
- 深入剖析Android消息机制
- 深入详解Windows消息机制(2012年某公司实习生招聘面试试题)
- Android消息循环机制源码深入理解
- 安卓中的消息循环机制Handler及Looper详解