MFC单文档模式中,四个类对消息处理的优先级

MFC的单文档架构,有四个类(这里忽略About对话框类):

  1. MainFrame
  2. App
  3. Doc
  4. View

这四个类和MVC设计模式的关系如下:

  1. MainFrame代表着MVC的C (Control)。
  2. App可以理解为对hInstance的封装。
  3. Doc对应着MVC的M (Model)。
  4. View对应着MVC的V (View)。

这四个类全部继承自CCmdTarget类,所以它们都具有处理消息的能力。问题是:同一个WM_COMMAND消息,谁先处理,谁后处理(4个类对消息处理的优先级问题)?

现在做试验分析,首先要明确WM_COMMAND消息的产生方式。以下三种情况都能产生WM_COMMAND消息:

  1. 菜单选项的点击
  2. 控件状态的改变(例如按钮按下)
  3. 键盘快捷键的按下

首先增加一个菜单选项:

然后在每个类中,都进行如下操作:进入类向导,在Command标签中增加关于此菜单项的处理函数:

在每个函数内部写一个AfxMessageBox()函数,作为标记:

这样,现在每个类都有了标记用的弹框提示。运行程序,点击此菜单项,就知道这四个类对WM_COMMAND消息处理的优先权了:

结果是View类对VM_COMMAND消息作出了响应。经测试,一旦一个类处理了消息,其他类就不会处理了(也就是说只会弹出一个对话框(刚才设置了4个AfxMessageBox)),这四个类的优先级顺序为:

  1. View
  2. Doc
  3. MainFrame
  4. App

现在探究这个顺序的原因。研究的方法是在CSingleView::OnHelpTestcmd()函数里下断点,断下来之后分析栈回溯:

分析之后找到原因:CFrameWnd::OnCmdMsg()函数内部,通过顺序结构规定了这四个类对WM_COMMAND消息的处理优先级:

从代码以及注释中,可以清楚地看到这个优先级:View第一,下一个是MainFrame,最后是App。Doc哪里去了?Doc和View绑定到一个函数里去了,继续看栈中的函数CView::OnCmdMsg()

这里可以看到对Doc的处理(紧跟着View)。

原文地址:https://www.cnblogs.com/zhugehq/p/13855333.html