MFC文档视图(三):命令消息路由
2015-05-12 17:06
225 查看
我们知道命令消息就是由菜单栏,工具栏或加速键(我们一般叫做快捷键)产生的消息.
前面有讲过标准消息就由其对应的CWnd类的子类处理就OK,子类不处理就回溯回父类.不用转给其他类处理.但命令消息不同,只要是继承自CCmdTarget的类都可以处理,也就是说前面提到的5个核心的类(CWinApp,CSingleDocTemplate,CFrameWnd,CView,CDocument)都可以处理它.
那一个命令消息发出来到底谁去处理呢 ?
首先你猜想着要是不是上面5个类都有对应的宏去映射下就都可以处理.也就是5个类同时处理? 显然不是这样.一次只让一个类去处理的.于是就会给这5个类排下优先次序.先看前面有对应的消息映射宏不,有的话就让该类来处理,排名靠后的类就不管他们了.反正就这样依次检查.
这里以SDI项目(single document inerface)为例来说下.假如点下菜单栏中的File-->Open发出一个消息,看下这消息是怎么被处理的.
假如继承自CWinApp,CFrameWnd,CView,CDocument的4个类中都写上宏
ON_COMMAND(ID_FILE_OPEN, OnOpen);
定义了函数afx_msg void OnFileOpen();
这样一来说明这4个类都有能力来处理命令消息了,但有能力处理未必就真让它处理.就像你觉得自己有能力当个啥领导了,但大领导未必就真让你当,最是把你作为候选人而已.
首先我们知道那些菜单,工具栏都是由CFrameWnd创建的.但实际上最先不是由它来处理.(实际上准确的讲是这4个类的子类来处理,为了讨论方便就说父类的名字好了)
1.先是由CView来处理,你Debug的时候会看到执行到CView的OnFileOpen函数.执行完这函数后其他类中相同的OnFileOpen不会被执行到.
2.如果CView没有处理则由CDocument来处理.你可以把CView中的宏ON_COMMAND(ID_FILE_OPEN, OnOpen)注释掉.这样debug下就发现会执行CDocument中的函数OnFileOpen了
3.如果CDocument也没有处理则由CFrameWnd来处理.同样你把CDocument的宏ON_COMMAND(ID_FILE_OPEN, OnOpen)注释掉.这样debug下就发现会执行CFrameWnd中的函数OnFileOpen了
4.如果CDocument也没处理则由CWinApp来处理.你把CFrameWnd的宏ON_COMMAND(ID_FILE_OPEN, OnOpen)注释掉.这样debug下就发现会执行CWinApp中的函数OnFileOpen了
所以路由的顺序是1.CView -- > 2.CDocument --->3.CFrameWnd -->3.CWinApp
当然如果是MDI项目的话顺序就不太一样.是下面这样
1.CView --> 2.CDocument -->3.CMDIChildWnd--> 4.CWinApp -->5.CMDIFrameWnd
(注:貌似有些书上讲是CWinApp最后一个,但实际上测试的时候发现不是.你反正自己在VS中debug测下就知道了)
前面有讲过标准消息就由其对应的CWnd类的子类处理就OK,子类不处理就回溯回父类.不用转给其他类处理.但命令消息不同,只要是继承自CCmdTarget的类都可以处理,也就是说前面提到的5个核心的类(CWinApp,CSingleDocTemplate,CFrameWnd,CView,CDocument)都可以处理它.
那一个命令消息发出来到底谁去处理呢 ?
首先你猜想着要是不是上面5个类都有对应的宏去映射下就都可以处理.也就是5个类同时处理? 显然不是这样.一次只让一个类去处理的.于是就会给这5个类排下优先次序.先看前面有对应的消息映射宏不,有的话就让该类来处理,排名靠后的类就不管他们了.反正就这样依次检查.
消息路由的次序
这里以SDI项目(single document inerface)为例来说下.假如点下菜单栏中的File-->Open发出一个消息,看下这消息是怎么被处理的.假如继承自CWinApp,CFrameWnd,CView,CDocument的4个类中都写上宏
ON_COMMAND(ID_FILE_OPEN, OnOpen);
定义了函数afx_msg void OnFileOpen();
这样一来说明这4个类都有能力来处理命令消息了,但有能力处理未必就真让它处理.就像你觉得自己有能力当个啥领导了,但大领导未必就真让你当,最是把你作为候选人而已.
首先我们知道那些菜单,工具栏都是由CFrameWnd创建的.但实际上最先不是由它来处理.(实际上准确的讲是这4个类的子类来处理,为了讨论方便就说父类的名字好了)
1.先是由CView来处理,你Debug的时候会看到执行到CView的OnFileOpen函数.执行完这函数后其他类中相同的OnFileOpen不会被执行到.
2.如果CView没有处理则由CDocument来处理.你可以把CView中的宏ON_COMMAND(ID_FILE_OPEN, OnOpen)注释掉.这样debug下就发现会执行CDocument中的函数OnFileOpen了
3.如果CDocument也没有处理则由CFrameWnd来处理.同样你把CDocument的宏ON_COMMAND(ID_FILE_OPEN, OnOpen)注释掉.这样debug下就发现会执行CFrameWnd中的函数OnFileOpen了
4.如果CDocument也没处理则由CWinApp来处理.你把CFrameWnd的宏ON_COMMAND(ID_FILE_OPEN, OnOpen)注释掉.这样debug下就发现会执行CWinApp中的函数OnFileOpen了
所以路由的顺序是1.CView -- > 2.CDocument --->3.CFrameWnd -->3.CWinApp
当然如果是MDI项目的话顺序就不太一样.是下面这样
1.CView --> 2.CDocument -->3.CMDIChildWnd--> 4.CWinApp -->5.CMDIFrameWnd
(注:貌似有些书上讲是CWinApp最后一个,但实际上测试的时候发现不是.你反正自己在VS中debug测下就知道了)
相关文章推荐
- MFC文档视图(三):命令消息路由
- MFC文档视图(三):命令消息路由
- MFC命令消息路由过程(视图、框架、应用)
- MFC中框架文档视图结构的命令路由处理
- mfc浅析(1) 文档视图结构中,缺省的命令处理
- MFC 文档 视图 框架窗口间的关系 和消息传送规律
- 多文档视图间切换消息处理 MFC
- 为MFC单文档视图中创建的CTreeCtrl添加消息响应
- MFC浅析(3) 文档视图结构中命令的处理流程
- MFC浅析(3) 文档视图结构中命令的处理流程
- 深入浅出MFC“文档/视图”架构(6)--相互关系及消息流动
- [MFC]文档/视图结构的命令传送和预定义命令ID(包括命令处理程序)
- MFC命令消息的路由
- 【MFC】多文档多视图工程:视图间消息发送
- MFC消息映射和命令路由
- 如何为SDI程序中多个不同视图路由命令消息
- MFC----文档 视图 框架窗口间的关系 和消息传送规律
- VC 2010 + MFC + MDI多文档视图框架:视图框架窗口激活的消息通知
- MFC浅析 -- 文档视图结构中,缺省的命令处理
- MFC 文档 视图 框架窗口间的关系 和消息传送规律