45fan.com - 路饭网

搜索: 您的位置主页 > 网络频道 > 阅读资讯:WTL消息循环机制的详细分析

WTL消息循环机制的详细分析

2016-08-29 08:16:52 来源:www.45fan.com 【

WTL消息循环机制的详细分析

WTL消息循环机制实现了消息过滤和空闲处理机制。

消息过滤


首先看一下CMessageLoop的核心逻辑CMessageLoop.Run()的代码:

int CMessageLoop.Run()
{
BOOL bDoIdle = TRUE;
int nIdleCount = 0;
BOOL bRet;

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("::GetMessage returned -1 (error)/n"));
continue;// error, don't process
}
else if(!bRet)
{
ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting/n"));
break;// WM_QUIT, exit message loop
}
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++的接口,即只定义了抽象虚拟函数。

class CMessageFilter {
public:
virtual BOOL PreTranslateMessage(MSG* pMsg) = 0;
};


这样,任何类想要实现消息过滤,只需实现这个接口。在C++中就采用继承。然后再实现PreTranslateMessage()函数即可。

ATL/WTL App Wizard生成的框架窗口中实现PreTranslateMessage()的代码如下:

BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if(CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg))
return TRUE;
return m_view.PreTranslateMessage(pMsg);
}


这种消息过滤机制的好处是任何实现了CMessageFilter接口的对象,都可以接受消息过滤。

程序通过AddMessageFilter()和RemoveMessageFilter()把这些对象加入到CMessageLoop中。

空闲处理


空闲处理的机制和消息过滤类似。这里不再介绍。我们要把主要经历放在WTL的框架窗口分析上。稍后,我们将进入这部分内容。
 

本文地址:http://www.45fan.com/a/question/69173.html
Tags: 深入 WTL 剖析
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部