mfc学习笔记之如何修改mfc消息机制处理顺序

学习mfc时知道了mfc的消息处理机制是有着顺序的,首先是视图类CView类先处理,如果视图类不处理消息则会由文档类CDocument处理,如果文档类不处理消息则会由框架类CFrameWnd处理,加入框架类不处理则会由应用程序类CWinApp类处理,但是这个顺序是怎么来的呢,跟踪MFC代码调试发现是跟MFC库代码顺序有关,相关MFC函数代码如下

BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,
    AFX_CMDHANDLERINFO* pHandlerInfo)
{
    CPushRoutingFrame push(this);

    // pump through current view FIRST
    CView* pView = GetActiveView();
    if (pView != NULL && pView->OnCmdMsg(nID,
     nCode,   pExtra, pHandlerInfo))
        return TRUE;

    // then pump through frame
    if (CWnd::OnCmdMsg(nID,
     nCode, pExtra,   pHandlerInfo))
        return TRUE;

    // last but not least, pump through app
    CWinApp* pApp = AfxGetApp();
    if (pApp != NULL && pApp->OnCmdMsg(
    nID, nCode, pExtra, pHandlerInfo))
        return TRUE;

    return FALSE;
}

由代码可以看出来MFC的消息处理会在此处进行选择对象处理,而首先选择的就是视图类,如图所示
这里写图片描述
在视图类的消息处理函数中,如果会处理会进入文档类处理,如图所示
这里写图片描述
因此我们给视图类,文档类,框架类都加入消息循环,然后加入ON_COMMAND处理新建消息
运行程序,结果如下
这里写图片描述

视图类处理了这个ON_COMMAND消息,屏蔽视图类和文档类的这个消息,结果如下

这里写图片描述

此时则是框架类处理了这个消息,那么我们如何修改这个处理顺序呢,只需要重写框架类的OnCmdMsg方法即可
首先新建一个自己要优先处理消息的类,这个类继承自CCmdTarget并加入消息循环宏

class CMyTarget : public CCmdTarget
{
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnNew();
};

BEGIN_MESSAGE_MAP(CMyTarget,CCmdTarget)
    ON_COMMAND(ID_NEW,OnNew)
END_MESSAGE_MAP()

然后在这个类中加入消息处理函数

void CMyTarget::OnNew()
{
    AfxMessageBox("自己的类处理新建被点击");
}

定义框架类

class CMyFrameWnd : public CFrameWnd
{
    DECLARE_MESSAGE_MAP()
public:
    virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)
    ON_COMMAND(ID_NEW,OnNew)
    ON_WM_CREATE()
END_MESSAGE_MAP(

并重写OnCmdMsg方法,代码如下

BOOL CMyFrameWnd::OnCmdMsg( UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo )
{
    CMyTarget cMyTarget;
    if (cMyTarget.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
        return TRUE;
    return CFrameWnd::OnCmdMsg(nID,nCode,pExtra,pHandlerInfo);
}

在这个重写方法里定义CMyTarget对象,然后调用cMyTarget.OnCmdMsg方法处理消息,最后为了安全,再次调用MFC的消息处理函数CFrameWnd::OnCmdMsg函数,此时结果应当会弹出“自己的类处理新建被点击”对话框,结果运行结果如下
这里写图片描述
至此成功修改了MFC消息处理顺序,因此我们可以看出MFC的消息处理顺序可以根据自己的需要任意修改而不是一成不变的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值