Mfc 是windows下c++应用程序的开发框架,它封装了几乎所有的windows api,其执行速度可以与C相比,且程序占用内存小。
Mfc程序中的主要类:
1、 应用程序类 CWinApp
应用程序的初始化、执行和结束工作都是由应用程序类完成。它控制了程序执行的流程。每个mfc应用程序都必须有且只有一个CWinApp类的派生类的对象,一般将其声明为全局类型,这样可以保证先调用该对象的构造函数。
程序执行时,先调用CWinApp类内封装好的WinMain()函数开始程序,然后调用InitInstance()函数来执行应用程序的初始化,之后进入Run()函数,实现API函数中的GetMessage、TranslateMessage、DispatchMessage的功能。最后程序退出时调用ExitInstance().
2、 视图类CView
视图类是文档和用户的中介,可以直观的显示出来。CView中两个主要的函数:OnDraw(),GetDocument()。
3、 文档类 CDocument
文档对象是存放程序数据的抽象表示的地方,它通常是用“文件”菜单上的“新建”或“打开”命令创建,并且通常保存在文件中。
4、 窗口框架类CFrameWnd
视图和框架的区别:视图显示在文档框架窗口中。在单文档程序中,文档框架窗口就是应用程序的主框架窗口,在多文档应用程序中,文档窗口就是显示在主框架窗口中的子窗口。通常我们不使用CFrameWnd类的成员函数。
5、 文档模板类CDocTemplate
文档模板将文档类、视图类和窗口框架类的对象联系起来,在单文档应用程序中的文档模板类是CSingleDocTemplate,在多文档应用程序中文档模板类是CMultiDocTemplate,二者都由CDocTemplate类派生。
MFC类库层状:
CObject是MFC类库的首要基础类,大部分的MFC类都由CObject类派生,我们编写程序时创建的各种类也是由CObject类派生。
CObject类的主要派生类:
1、CCmdTarget类,是CObject类的一个重要派生类,是MFC消息映射结构的基础。CCmdTarget中包含了Windows事件驱动程序设计的概念。CCmdTarget类派生了许多重要的类,如CView、CWinApp、CDocument、CWnd、CFrameWnd等。如果用户想创建一个拥有消息循环和支持消息处理机制的类,可以从这些类中派生。用户很少从CCmdTarget类中直接派生类。Cwnd类支持不同类型的窗口,包括可视化控件、对话框和视图。
2、异常处理类CException
3、文件服务类
4、图形处理类
5、同步类
6、Internet相关类
7、数据库相关类
8、其他派生类
还有一些非CObject类的派生类。
MFC类库分为两个部分:一部分是MFC类、另一部分是宏与全局函数(变量)。
如果MFC类是MFC的核心,则全局函数和宏则发挥着在核心之间穿针引线的作用。
MFC消息处理模式
消息的分类:
1、 标准Windows消息
除了WM_COMMAND消息,所有以WM_为前缀的消息都是标准Windows消息。如窗口、鼠标移动、窗口大小改变,程序启动或退出甚至每一段固定的时间都将产生标准windows消息。
标准windows消息由窗口和视图处理,CWnd和它的派生类都可以接受标准windows消息,这类消息中通常含有如何对消息进行处理的一些参数。标准Windows消息都有默认的处理函数,这些函数在CWnd类中进行了预定义。
2、 控件通知消息
控件通知消息是由编辑框、列表框等控件或子窗口产生并传向父窗口的消息。它以WM_COMMAND为消息名,在消息的参数中包含具体的控件通知代码,以区别具体的控件通知消息。
控件通知消息必须由窗口类的对象,也就是直接或间接的由CWnd类或其他派生类的对象进行处理,如主框架窗口类、子框架窗口类或窗口类等。
3、 命令消息
命令消息也以WM_COMMAND为消息名,在消息中包含命令标识符,以区别具体的命令。命令消息由用户界面对象产生,菜单、加速键、工具栏都是可以产生命令消息的用户界面对象。
命令消息可以被更广泛的对象处理,不仅仅局限于窗口类。所有派生自CCmdTarget类都可以处理命令消息。
标准windows消息和控件通知消息均由窗口类对象即CWnd类或CWnd类的派生类对象进行处理。命令消息可由所有派生自CCmdTar类的对象进行处理。
消息标识符取值范围:
消息类型 | 取值范围 |
系统定义消息 | 0x0000----0x03FF |
用户自定义内部消息 | 0x0400---0x07FF |
系统定义消息 | 0x8000---0xBFFF |
用户自定义外部消息 | 0XC000----0xFFFF |
消息映射
MFC使用消息映射机制来进行消息处理。通过一些宏将特定的消息映射到派生类中相应的成员函数上。消息映射机制实际上就是消息及其处理函数的一一对应表以及处理、分析这张表的应用程序框架内部的一些程序代码。
在MFC中,继承CCmdTarget的类都可以有自己的消息映射,如果要建立消息映射,需要:
1、 在类的头文件中声明消息映射表,它通常情况下被写在一个类定义的最后。
DECLARE_MESSAGE_MAP()
2、 在类的代码中(.cpp)加入消息映射表
BEGIN_MESSAGE_MAP(x, y)
ON_COMMAND();
ON_BN_CLICKED()
ON_MESSAGE()
END_MESSAGE_MAP()
BEGIN_MESSAGE_MAP()宏有两个参数,第一个参数为该消息映射所属类的名称,第二个参数指出前一个类的直接基类。每个消息映射都是由一组宏定义构成,这些在消息映射内部的宏称为映射宏。消息映射中使用的映射宏由所处理消息的类型决定,映射宏中可以没有参数,也可以有多个参数。
标准windows消息映射宏:这类宏的名称不确定,标准windows消息映射宏没有参数。
命令消息映射宏:包括ON_COMMAND,ON_COMMAND_RANGE, ON_COMMAND_EX等。宏定义如下:ON_COMMAND(id, memberFxn), ON_COMMAND_EX(id1, id2, memberFxn),
控件消息映射宏:包括ON_CONTROL,ON_CONTROL_RANGE等。
其他映射宏:ON_MESSAGE用于用户自定义消息,ON_REGISTED_MESSAGE用于已经使用RegisterWindowsMessage函数注册的Windows消息。宏定义如下:
ON_MESSAGE(message, memberFxn)
ON_REGISTERED_MESSAGE(nMessageVariable,memberFxn)
消息处理函数
所有的消息处理函数原型前面都有关键字afx_msg前缀。
消息传递
在应用程序中,产生消息时系统使用CWinApp类的Run函数来检索消息,并把消息发送到适当的窗口。MFC程序中,命令消息与非命令消息采用两种不同的消息传递方式。
非命令的消息传递:(非命令消息,即标准的Windows消息和控件通知消息),必须由窗口类对象,也就是直接或间接由CWnd类或其派生类的对象进行处理。这个窗口可能是主框架窗口、标准控件、对话框、视图或其他类型的子窗口。
在程序运行过程中,每个windows窗口都和窗口对象联系在一起。每个窗口对象都有自己的消息映射和处理函数。MFC利用消息映射把消息与其对应的处理函数相匹配。
命令消息的传递:当某个命令产生消息后,它被应用程序沿着命令消息的传送路径发送。传递路径的每一个对象都按着顺序检查自己的消息映射,看看能否处理这个消息,如果消息处理函数匹配,则调用处理函数进行处理消息并不再搜素后面的对象,反之就继续进行下去。