MFC六大关键技术之仿真学习笔记(八)

       前一节写到,在类关系中我们已经建立了一种消息映射的机制,消息具体是如何在类中传递的,是一个值得我们去研究的问题,待我一一道来。


*Command Routing(命令传递)

实现消息的纵向流动,我们并不希望消息只呈单线发展,我们更渴望得到的是走访映射表的功能。


这是MFC的消息泵,展示出了各个函数的调用顺序,假若CMyFrameWnd收到WM_COMMAND消息,那么消息将会尝试在数种路线传递,就像以下:


在消息进行遍历的途中,我们能发现最多的就是虚函数。

我来理一下仿真的流程:

先上函数成员表:


(1)一般Windows消息:  

AfxWndProc -> AfxCallWndProc -> CWnd::WindowProc -> AfxFindMessageEntry;

(2)CMyFrameWnd 得到 WM_COMMAD

AfxWndProc -> AfxCallWndProc -> CWnd::WindowProc 

LRESULT CWnd::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	AFX_MSGMAP* pMessageMap;
	AFX_MSGMAP_ENTRY* lpEntry;

	if (nMsg == WM_COMMAND)
	{
		if (OnCommand(wParam,lParam))
		{
			return 1L;
		}
		else
		{
			return (LRESULT)DefWindowProc(nMsg, wParam, lParam);
		}
	}

	pMessageMap = GetMessageMap();
	for (; pMessageMap != NULL; pMessageMap = pMessageMap->pBaseMessageMap)
	{
		lpEntry = pMessageMap->lpEntries;
		printlpEntries(lpEntry);
	}

	return 0;
}

 -> (virtual)CFrameWnd::OnCommad  [OnCommand(wParam,lParam)]

BOOL CFrameWnd::OnCommand(WPARAM wParam, LPARAM lParam)
{
	return CWnd::OnCommand(wParam, lParam);
}

-> CWnd::OnCommad  [CWnd::OnCommand(wParam,lParam)]

BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
{
	return OnCmdMsg(0, 0);
}

->  (virtual)CFrameWnd::OnCmdMsg  [OnCmdMsg(0, 0)]

BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode)
{
	CView* pView = GetActiveView();
	if (pView->OnCmdMsg(nID,nCode))
	{
		return TRUE;
	}

	if (CWnd::OnCmdMsg(nID,nCode))
	{
		return TRUE;
	}

	CWinApp* pApp = AfxGetApp();
	if (pApp->OnCmdMsg(nID, nCode))
	{
		return TRUE;
	}

	return FALSE;
}
初见端倪,消息从这里呈多线流动:

线路①:-> CView::OnCmdMsg  [pView->OnCmdMsg(nID,nCode)]

BOOL CView::OnCmdMsg(UINT nID, int nCode)
{
	if (CWnd::OnCmdMsg(nID,nCode))
	{
		return TRUE;
	}

	BOOL bHandled = FALSE;
	bHandled = m_pDocument->OnCmdMsg(nID, nCode);
	return bHandled;
}
1.->( virtual) CCmdTarget::OnCmdMsg [CWnd::OnCmdMsg(nID,nCode)]

此线到达顶端,如被处理返回TRUE。

路线为:

1221  CMyView
122  CView
12  CWnd
1  CCmdTarget

2.->CDocument::OnCmdMsg  -> CCmdTarget::OnCmdMsg  [m_pDocument->OnCmdMsg(nID, nCode)]

此线到达顶端,如被处理返回TRUE。

路线为:

131  CMyDoc
13  CDocument
1  CCmdTarget

线路②: ->(virtual)CCmdTarget::OnCmdMsg  [CWnd::OnCmdMsg(nID,nCode)]

此线到达顶端,如被处理返回TRUE。

路线为:

1211  CMyFrameWnd
121  CFrameWnd
12  CWnd
1  CCmdTarget

线路③: ->(virtual)CCmdTarget::OnCmdMsg  [pApp->OnCmdMsg(nID, nCode)]

此线到达顶端,如被处理返回TRUE。

路线为:

1111  CMyWinApp
111  CWinApp
1  CCmdTarget


消息到达CCmdTarget::OnCmdMsg以后,(virtual)GetMessageMap对消息映射表进行遍历,如果找到匹配消息进行处理,未找到则返回FALSE,交由DefWindowProc进行处理。这样仿真直观的解释了消息是如何在MFC框架中进行流动的。


到此,MFC的关键仿真技术已经学习完成,学习笔记暂时写到这里。

相关代码下载:http://download.csdn.net/detail/u010125463/8784495




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值