您的位置:首页 > 其它

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测下就知道了)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: