090916(星期三):MFC消息路由1

本文详细解析了MFC中的命令路由机制,介绍了关键函数如AfxWndProc的作用及调用流程,并探讨了如何通过消息映射处理WM_COMMAND消息。此外,还分析了CTreeCtrl类处理双击事件的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、命令路由Command Routing

1,增加一个函数列表

与消息循环相关的函数

注意

None

AfxWndProc

Global

None

AfxCallWndProc

Global

CCmdTarget

OnCmdMsg

Virtual

CDocument

OnCmdMsg

Virtual

CWnd

WindowProc

Virtual

OnCommand

Virtual

DefWindowProc

Virtual

CFrameWnd

OnCommand

Virtual

OnCmdMsg

Virtual

CView

OnCmdMsg

virtual

 

2,全局函数AfxWndProc是推动引擎的起始点,在MFC中的CWinThread::Run中被调用,作为实验,这里在main函数中调用。AfxWndProcMFC中有四个参数,这里加上一个表示谁获得了消息。

AfxWndProc(0, WM_CREATE, 0, 0, pMyFrame);表示pMyFrame获得了一个WM_CREATE消息。

 

LRESULT AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam,

CWnd *pWnd) // last param. pWnd is added by JJHou.

{

cout << "AfxWndProc()" << endl;

return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);

}

LRESULT AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg,

WPARAM wParam, LPARAM lParam)

{

cout << "AfxCallWndProc()" << endl;

// 交给类的消息处理函数

LRESULT lResult = pWnd->WindowProc(nMsg, wParam, lParam);

return lResult;

}

 

CWnd::WindowProc首先判断消息是否为WM_COMMAND,不是的话直接向父类推。每到一个累的MessageMap,原本都应该比较所处理消息的数组(AFX_MSGMAP_ENTRY)的每个元素,比较成功则进行处理。

 

LRESULT CWnd::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)

{

AFX_MSGMAP* pMessageMap;

AFX_MSGMAP_ENTRY* lpEntry;

if (nMsg == WM_COMMAND) // special case for commands

{

if (OnCommand(wParam, lParam))

return 1L; // command handled

else

return (LRESULT)DefWindowProc(nMsg, wParam, lParam);

}

pMessageMap = GetMessageMap();

for (; pMessageMap != NULL;

pMessageMap = pMessageMap->pBaseMessageMap)

{

lpEntry = pMessageMap->lpEntries;

printlpEntries(lpEntry);

}

return 0; // J.J.Hou: if find, should call lpEntry->pfn,

        // otherwise should call DefWindowProc.

// for simplification, we just return 0.

}

 

 

 

 

二、寻找CTreeCtrl处理双击事件的函数

1,类的声名

#define DECLARE_MESSAGE_MAP() 

private:  

static const AFX_MSGMAP_ENTRY _messageEntries[]; 

 

protected:  

static AFX_DATA const AFX_MSGMAP messageMap;  

virtual const AFX_MSGMAP* GetMessageMap() const; 

 

2,定义时的宏

BEGIN_MESSAGE_MAP(CTreeCtrl, CWnd)

       //{{AFX_MSG_MAP(CTreeCtrl)

       ON_WM_DESTROY()

       //}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

#define ON_WM_DESTROY()  

{

    WM_DESTROY, 0, 0, 0, AfxSig_vv,  

(AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&OnDestroy

},

如此看来没有加入双击事件的函数,是在基类里面?

 

3 继承图

CObject

CCmdTarget

    CWnd

        CTreeCtrl

基类CWnd不可能做到树形项目的展开啊。

 

 

 

明天继续。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值