深入剖析WTL—WTL消息循环机制详解

转载 2007年10月08日 14:05:00

 

消息过滤



首先看一下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的框架窗口分析上。稍后,我们将进入这部分内容。

深入剖析WTL—WTL消息循环机制详解

WTL消息循环机制实现了消息过滤和空闲处理机制。 消息过滤 首先看一下CMessageLoop的核心逻辑CMessageLoop.Run()的代码: int CMessageLoop.Run()...
  • zcxin
  • zcxin
  • 2013年10月23日 00:15
  • 1223

WTL 基础: 消息与消息反射

首先需要知道,消息是怎么来的。windows操作系统
  • xianlaowu
  • xianlaowu
  • 2014年04月12日 05:56
  • 729

STL,ATL,WTL之间的联系和区别

一、STL即 Standard Template Library (标准模板库)       STL是惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Le...
  • wangwenjing90
  • wangwenjing90
  • 2013年05月14日 14:44
  • 3965

WTL 详细介绍

转自:WTL for MFC Programmers, Part I - ATL GUI Classes 在你开始使用WTL或着在本文章的讨论区张贴消息之前,我想请你先阅读下面的材料。 你需要开...
  • worldy
  • worldy
  • 2013年11月05日 00:00
  • 3774

WTL 基础:CWindow 发现

心情好的话,我喜欢去看WTL或者ATL底层的源代码,有些我已经看过很多bian
  • xianlaowu
  • xianlaowu
  • 2014年04月13日 15:14
  • 1213

WTL基础: 显示图片(JPG, BMP, PNG, TIF等)

使用ATL 的Cimage类,图片文件大掉入和显示,变的shif
  • xianlaowu
  • xianlaowu
  • 2014年04月20日 12:06
  • 969

一个显示进度条的WTL状态栏类

引言   好久没用WTL写代码了,WTL已经更新到8.1版本,但依旧没有提供对VS2013的支持,网上有相关更改想到模板的方法,但向导界面和VS2013的风格严重不搭,丑的一逼……好在WTL代码结构很...
  • mousebaby808
  • mousebaby808
  • 2014年02月14日 14:54
  • 3090

WTL 窗口创建消息队列

ATLAPP.H包含了消息循环类、接口类、和产生应用程序所必需的一些基础类定义。        类定义如下:               CmessageFilter类---用于消息过滤的   ...
  • suhuaiqiang_janlay
  • suhuaiqiang_janlay
  • 2015年03月29日 11:09
  • 1308

深入剖析WTL—WTL框架窗口分析

WTL的基础是ATL。WTL的框架窗口是ATL窗口类的继承。因此,先介绍一下ATL对Windows窗口的封装。 由第一部分介绍的Windows应用程序可以知道创建窗口和窗口工作的逻辑是: ...
  • zcxin
  • zcxin
  • 2013年10月23日 01:42
  • 1458

WTL界面自绘系列-预备

本文不会阐述技术上的细节,旨在提供宏观的思路。 wi界面自绘
  • u011076878
  • u011076878
  • 2014年05月24日 15:38
  • 695
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深入剖析WTL—WTL消息循环机制详解
举报原因:
原因补充:

(最多只允许输入30个字)