MFC(视图窗口、WM_COMAND命令消息)

本文介绍了MFC中视图窗口和COMMAND消息的处理机制。当不同窗口产生消息时,MFC会按特定顺序查找处理函数。COMMAND消息的处理顺序为:视图类>文档类>框架类>APP类。同时,强调了视图窗口必须被激活,才能处理COMMAND消息,因为处理流程依赖于框架类中保存的当前活动视图对象指针。

视图窗口

命令消息

正常情况下,不同窗口产生不同的消息时,MFC会自动找到对应的类对象,遍历该对象的消息数组,找不到对应的消息,会再去其父类找对应的消息,也就是说,只要是该窗口产生的消息就会到这个类及其父类找处理函数,但是相对来说,COMMAND消息就不同,因为不管是视图类APP类还是框架类都可以处理COMMAND消息,而且获取COMMAND消息的先后顺序是:视图类>文档类>框架类>APP类

执行COMMAND消息过程如下:

//WM_COMMAND消息的路线
AfxWndProc(...)//线进入窗口处理程序
{
  CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
             //获取和hWnd绑定在一起的框架类对象地址(pFrame===pWnd)
  AfxCallWndProc(pWnd...)//参数pWnd===pFrame
  { 
    pWnd->WindowProc(...)//函数内部this为pFrame===pWnd 调用框架窗口的处理程序
    {
      OnWndMsg(...)//函数内部this为pFrame===pWnd
      //这个函数内部根据消息不同分为两路
      //当是Command消息从下面这条线路走
      //当是其他消息是就会遍历其类和其父类的消息函数链表
      {
OnCommand(wParam, lParam)//函数内部this为pFrame
{
  CWnd::OnCommand(..)//函数内部this为pFrame
  {
    OnCmdMsg(...)//函数内部this为pFrame   *****CFrameWnd::OnCmdMsg 起点
    {
      CView* pView = GetActiveView()//函数内部this为pFrame
      {
        return this->m_pViewActive;//活动视图窗口对象地址
      }对象
      pView->OnCmdMsg(..) ===>终点 CCmdTarget::OnCmdMsg 此函数内部this为pView,该函数就是遍历类的消息处理函数链表
      m_pDocument->OnCmdMsg(.)==>终点CCmdTarget::OnCmdMsg 此函数内部this为文档类对象
      CWnd::OnCmdMsg(..)==>终点 CCmdTarget::OnCmdMsg 此函数内部this为pFrame

      CWinApp* pApp = AfxGetApp();//获取&theApp
      pApp->OnCmdMsg(..)==>终点 CCmdTarget::OnCmdMsg 此函数内部this&theApp
      			}
      		}
      	}
      }
    }
  }
}

对象关系

对象关系图:
在这里插入图片描述
theApp对象里面成员变量m_pMainWnd保存了框架类对象地址,框架类对象成员m_pViewActive保存的是当前活动的视图类对象,视图类对象的成员m_pDocument保存的是文档类对象的地址,文档类对象里面有一个链表包含了所有视图对象的地址。

m_pMainWnd = pFrame;//框架类对象的地址pFrame赋值给APP类里面的成员变量m_pMainWnd 
m_ViewActive = pView;//视图类对象的地址pView赋值给框架类对象里面的成员变量m_ViewActive 

为什么在视图类处理COMMAND消息的时候,必须先点击激活视图窗口,才能获取视图类里面的COMMAND消息呢?

因为COMMAND消息的处理过程中,会先拿到框架类对象的成员m_ViewActive ,即当前活动的视图窗口类,然后遍历视图类里面是否有COMMAND的消息,然后遍历文档类,然后遍历框架类,最后遍历APP类,当没有视图窗口处于激活状态,框架类里的m_ViewActive 为空,一旦m_ViewActive 为空,当要处理COMMAND消息的时候,会先判断该变量,该变量为空就不会再去处理视图类消息了,自然,视图类无法获取COMMAND消息,因为这个过程到获取m_ViewActive 变量的时候就被打断了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值