一、命令路由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函数中调用。AfxWndProc在MFC中有四个参数,这里加上一个表示谁获得了消息。
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不可能做到树形项目的展开啊。
明天继续。