天天看点

4.1内部运行机制-消息映射

一、一些基本概念
1、几个重要头文件
afx.h        绝大部分类的声明头文件
afxwin.h   包含了afx.h和windows.h
afxext.h   -提供了扩展窗口类的支持(工具栏,状态栏等      
2、使用MFC做自己的库程序(MFCAppWizard dll)
规则动态库:可以被任意程序调用
扩展动态库:只能被支持MFC的程序调用      
3、MFC窗口程序
单文档视图构架程序。
CFrameWnd     -框架窗口类;
CWinApp          -应用程序类,负责管理整个程序的执行流程;
CDocument      -文档类,负责管理数据(数据的提取、转换、存储等操作);
CView               -视图窗口类,负责显示数据      
多文档视图构架程序。
CMDIChildWnd      -子框架窗口类,负责管理子框架窗口。
CMDIFrameWnd    -主框架窗口类
CWinApp               -应用程序类,负责管理整个程序的执行流程;
CDocument           -文档类,负责管理数据(数据的提取、转换、存储等操作);
CView                    -视图窗口类,负责显示数据      
对话框程序
CWinApp       -应用程序类,负责管理整个程序的执行流程;
CDialog          -对话框类      
4、基本类介绍
CObject              -mfc库绝大部分类的基类,封装了MFC库中最基本的一些机制,运行时类信息机制/动态创建机制/序列化机制.
CCmdTarget       -消息映射机制基类
CWinThread/CWinApp      -应用程序类
CDocTemplate及其子类      -文档模版类
CDocument及其子类          -文档类,封装了对各种数据的操作。
Exceptions                         - 异常类,封装了MFC中的各种异常情况。
CFile              -文操作类
CWnd            -所有窗口类基类
FrameWindows          框架窗口类,封装了对各种框架窗口的操作
ControlBars               -各种工具栏类,封闭了对各种工具栏的操作
Dialog Boxes              对话框类。
Views            视图窗口类
Controls        控件类
CDC/CGdiObject         封装了绘图操作
CArray/AList/CMap     对C++中的数据的封装,以C开头
 
二、消息映射机制
2.1什么是消息
窗口消息通常由三部分总成:1、无符号整数,即消息值  2、消息附带的WPARAM参数
3、附带的LPARAM类型参数。我们通常说的消息是狭义上的消息,也就是一个无符号整数,通常定义为宏。
 
2.2什么是消息映射机制
 	MFC使用消息映射机制处理消息。在程序中的表现即是消息映射表(以及消息处理函数的声明和实现代码):消息与消息处理函数一一对应。窗口收到消息–>消息映射表中查找相应消息处理函数->消息处理函数进行处理。
和SDK不同:SDK在消息窗口过程中一一判断消息值进行相应处理。
 
2.3Windows消息分类
Window消息分为系统消息和用户自定义消息两类。
	1.标准Windows消息。除WM_COMMAND外以WM_开头的消息是标准消息。例如,WM_CREATE、WM_CLOSE。
	2.命令消息。消息名为WM_COMMAND,消息中附带了标识符ID来区分是来自哪个菜单、工具栏按钮或加速键的消息。
       3.通知消息。通知消息一般由列表框等子窗口发送给父窗口,消息名也是WM_COMMAND,其中附带了控件通知码来区分控件。
 
	CWnd的派生类可以接收上面三种消息。命令消息还可以由文档类等接收。
 
	用户自定义消息实际上就是用户定义一个宏作为消息。值应大于WM_USER.。然后此宏就可以跟系统消息一样使用,窗口类中可以定义它的处理函数。
 
2.4消息映射表
	除了一些没有基类的类或CObject的直接派生类外,其他类都可以自动生成消息映射表。
	在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间的内容成为消息映射入口项。
	除了在实现文件中添加消息映射表外,在定义的头文件中还会添加一个宏调用:
	DECLARE_MESSAGE_MAP()
	一般这个宏调用写在类定义的结尾处。
 
2.5添加消息处理函数
无论自动还是手动添加,都有三个步骤:
	a、在类定义中加入消息处理函数的声明,注意是以afx_msg打头。如ON_CREATE的消处理函数声明:afx_msg  int OnCreate(LPCREATESTRUCT  lpCreateStruct)
	b、在类的消息映射表中添加该消息的消息映射入口项。如WM_CREATE的消息映射入口项:ON_WM_CREATE()
	c、在类的实现文件中添加消息处理函数的实现。如:
intMianFram:: OnCreate(LPCREATESTRUCT  lpCreateStruct){….}
通过上面三个步骤后,ON_CREATE等消息就可以在窗口类中被消息处理函数处理了。
 
2.6各种Windows消息的消息处理函数
都与WM_CREATE类似
	命令消息映射入口形式如:ON_COMMAND(ID_VIEW_CUSTOMIZE,CMainFram::OnViewCustomize)。前面参数为消息,后面的是消息处理函数。
	若要批量处理消息,可以采用形如:ON_COMMAND_RANEG(ID_VIEW_A,ID_VIEW_B, &CMainFrame::OnApplicationLook). 这样消息A到B之间的函数都由后面的消息处理函数处理。函数原型为afx_msg void OnApplicationLook(UINT id);,参数id为用户操作的菜单项等的ID
 
通知消息的消息映射入口项形如:
ON_NOTIFY(wNotifyCode,id,memberFxn);
参数依次为消息通知码,控件标识id,消息处理函数。
通知消息处理函数原型为:
       
afx_msgvoid memberFxn(NMHDR* pNotifyStruct, LRESULT * result);
 Typedef sturct tagNMHDR{
               HWND hwndFrom;
               UINT idFrom;
               UINT code;
      } NMHDR;
           
参见MSDN.
如果用户要自定义消息,首先要定义消息宏,如#define WM_UPDATE_WND(WM_USER+1)
	再到消息映射表中添加消息映射入口项:ON_MESSAGE(WM_UPDATE_WND,CMainFrame,OnUpdateWnd).
	然后在头文件中添加消息函数声明:afx_msg LRESULT OnUpdateWnd(WPARAM wParam,LPARAM lParam);
	最后在实现文件中实现此函数。