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




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章