Visual C++6.0 程序设计从入门到精通(三) - MFC的消息机制
2015-12-22 16:11
831 查看
1. 引言
MFC系统,乃至
Windows系统,是一个以消息为核心的系统,它将系统中发生的事件看做一个消息,放置在消息队列中,待系统在合适的时机进行处理。因此,理解
MFC系统的消息机制显得十分重要。因此,本文主要关注
MFC如何处理消息以及
Windows如何在
MFC编程中用代码产生消息。
1. MFC的消息驱动机制
MFC的消息驱动机制在用户和操作系统之间是双向的:1)操作系统响应应用程序界面对其的调用,其实质是用户调用操作系统函数调用并向操作系统发布消息(说明我要做什么);
2)操作系统向应用程序的具体处理函数发布用户响应的消息:其实质是操作系统分析消息队列将消息发布到具体的应用程序中响应函数中。
所以,在Windows中存在这样的说法: 用户调用了操作系统,操作系统调用了应用程序。
具体的消息驱动程序如下图:(以具体实例HelloMFC为例进行分析)
该图显示了以
MFC机制实现的应用程序框架类之间的关系。其中,
CHelloMFCApp类主要的作用是用来处理消息的,它统一管理程序收到的的所有消息,然后把消息分配给响应的对象。
CMainFrame是
CHelloMFCView的父窗口,也就是说视窗
View是显示在主框窗
MainFrame的客户区中。类
CHelloMFCView的作用是显示数据,而数据的来源是类
CHelloMFCDoc。在
MFC程序中,程序的数据是放在文档中的,而显示数据则是利用视窗方式,文档和视窗分离带来的好处就是一个文档可以同时具有多个视窗,每个视窗只显示文档中的一部分数据,或者以特定的风格显示文档中的数据。另一份好处是在程序中可以处理多个文档,通过不同的视窗的处理达到对不同的文档分别处理的目的。
2. MFC消息映射机制的代码实现
分三步:1)在资源对于的类定义中声明消息处理函数:
具体形式为:
class Foo { public: afx_msg void MsgProcedure(); DECLARE_MESSAGE_MAP() }
注意:
MsgProcedure()为消息的处理函数,用户在这里面添加对消息事件的处理代码;并且需要添加
afx_msg前缀,表明是一个
Windows消息;同时,函数的声明需要在
DECLARE_MESSAGE_MAP之前定义完成。
示例:
class CMyWnd : public CFrameWnd { public: ~CMyWnd(); CToolBar MyToolBar; afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnButton10(); afx_msg void OnButton11(); afx_msg void OnButton12(); afx_msg void OnButton13(); DECLARE_MESSAGE_MAP() };
2)建立消息处理函数和控件ID(控件、菜单、工具条等所有的资源ID)的函数映射表。
具体形式:
BEGIN_MESSAGE_MAP(thisClass, BaseClass) ON_COMMAND_KIND(RESOURCE_ID, MsgProcedure) END_MESSAGE_MAP()
注意:此处的映射宏建立资源ID和该资源的消息相应时间的映射,具体形式为在
MESSAGE_MAP宏之间按照上述形式建立映射:消息的种类(id, 消息处理函数的函数名)。
注意:资源id的保存时在
resource.h头文件定义一个ID宏,因此,此处的资源ID,不仅可以对应于各种资源的id(控件、菜单、工具条等所有的资源ID),也可以仅仅是一个宏定义,无需具备具体的资源。
具体实例:
BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd) ON_WM_CREATE() ON_COMMAND(ID_BUTTON40010,OnButton10) ON_COMMAND(ID_BUTTON40011,OnButton11) ON_COMMAND(ID_BUTTON40012,OnButton12) ON_COMMAND(ID_BUTTON40013,OnButton13) END_MESSAGE_MAP()
3)完成消息处理函数的编写
具体形式:
thisclass::MsgProcedure(Parameter) { }
示例:
void CMyWnd::OnButton13() { AfxMessageBox("Click button 13"); ::MessageBox(this->m_hWnd, "Very good!", "Button13", NULL); MessageBox("Oh, i know!", "Button13", MB_OK); }