按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
第篇 深入 MFC 程式設計
return 0;
}
return bResult;
}
以下是另一路CDocument 的动作:
// in DOCCORE。CPP
BOOL CDocument::OnCmdMsg (UINT nID; int nCode; void* pExtra;
AFX_CMDHANDLERINFO* pHandlerInfo)
{
if (CCmdTarget::OnCmdMsg (nID; nCode; pExtra; pHandlerInfo))
return TRUE;
// otherwise check template
if (m_pDocTemplate != NULL &&
m_pDocTemplate…》OnCmdMsg (nID; nCode; pExtra; pHandlerInfo))
return TRUE;
return FALSE;
}
图9…5 画出FrameWnd 窗口收到命令消息后的四个尝试路径。第3章曾经以一个简单的
DOS 程序仿真出这样的绕行路线。
576
…………………………………………………………Page 639……………………………………………………………
第9章 訊息映射與命令繞行
CWinThread CWinApp CMyWinApp
; ; ; ; ; ; ; ; ; ;
0;0;0;0;0;0 0;0;0;0;0;0
CView CMyView
m
e
CCmdTarget CWnd CFrameWnd CMyFrameWnd
s
; ; ; ; ; ; ; ; ; ;
s
0;0;0;0;0;0 0;0;0;0;0;0 a
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ; ; ; ; g
0;0;0;0;0;0 0;0;0;0;0;0 0;0;0;0;0;0 WM_MAND e
0;0;0;0;0;0
CDocument CMyDocument
当CMyFrameWnd 收到WM_MAND ,
消息唧筒尝试数种绕行路线,使命令消息有
; ; ; ; ; ; ; ; ; ; 机会经过任何一个类别。图中的
0;0;0;0;0;0 0;0;0;0;0;0 即绕行的优先次序(请参考图9…4 )。
图9…5 FrameWnd 窗口收到命令消息后的四个尝试路径。第 3 章曾经以一
个简单的DOS 程序仿真出这样的绕行路线。
OnCmdMsg 是各类别专门用来对付命令消息的函数。每一个「可接受命令消息之对象」
(mand Target )在处理命令消息时都会(都应该)遵循一个游戏规则:调用另一个
目标类别的OnCmdMsg 。这才能够将命令消息传送下去。如果说AfxWndProc 是消息流
动的「唧筒」,各类别的OnCmdMsg 就是消息流动的「转辙器」。
以下我举一个具体例子。假设命令消息从Scribble 的【Edit/Clear All 】发出,其处理常
式位在CScribbleDoc,下面是这个命令消息的流浪过程:
577
…………………………………………………………Page 640……………………………………………………………
第篇 深入 MFC 程式設計
1。 MDI 主窗口( CMDIFrameWnd ) 收到命令消息WM_MAND, 其ID 为
ID_EDIT_CLEAR_ALL 。
2。 MDI 主窗口把命令消息交给目前作用中的MDI 子窗口(CMDIChildWnd)。
3。 MDI 子窗口给它自己的子窗口(也就是View )一个机会。
4。 View 检查自己的Message Map 。
5。 View 发现没有任何处理例程可以处理此命令消息,只好把它传给Document 。
6。 Document 检查自己的Message Map ,它发现了一个吻合项:
BEGIN_MESSAGE_MAP(CScribbleDoc; CDocument)
ON_MAND(ID_EDIT_CLEAR_ALL; OnEditClearAll)
。。。
END_MESSAGE_MAP()
于是调用该函数,命令消息的流动路线也告终止。
如果上述的步骤6 仍没有找到处理函数,那么就:
7。 Document 把这个命令消息再送到Document Template 对象去。
8。 还是没被处理,于是命令消息回到View 。
9。 View 没有处理,于是又回给MDI 子窗口本身。
10。 传给CWinApp 对象…无主消息的终极归属。
图9…6 是构成「消息邦浦」之各个函数的调用次序。此图可以对前面所列之各个
源代码组织出一个大局观来。
578
…………………………………………………………Page 641……………………………………………………………
第9章 訊息映射與命令繞行
AfxWndProc
AfxWndProc
message
AfxCallWndProc
AfxCallWndProc
CWnd::WindowProc
CWnd::WindowProc
CWnd::OnWndMsg
CWnd::OnWndMsg ::DefWindowProc
CWnd::DefWindowProc ::DefWindowProc
CWnd::DefWindowProc
AfxFindMessageEntry
WM_MAND regular window message AfxFindMessageEntry
CFrameWnd::Onmand
CFrameWnd::Onmand
msg handler
CWnd::Onmand
CWnd::Onmand
CFrameWnd::OnCmdMsg
CFrameWnd::OnCmdMsg
CView::OnCmdMsg
CView::OnCmdMsg CWnd::OnCmdMsg
CWnd::OnCmdMsg
(CCmdTarget::OnCmdMsg)
(CCmdTarget::OnCmdMsg)
CWnd::OnCmdMsg CDocument::OnCmdMsg
CWnd::OnCmdMsg CDocument::OnCmdMsg CWinApp::OnCmdMsg
CWinApp::OnCmdMsg
(CCmdTarget::OnCmdMsg)
(CCmdTarget::OnCmdMsg) (CCmdTarget::OnCmdMag)
(CCmdTarget::OnCmdMag)
CCmdTarget::OnCmdMsg
CCmdTarget::OnCmdMsg
DispatchCmdMsg
DispatchCmdMsg
DispatchCmdMsg DispatchCmdMsg
DispatchCmdMsg DispatchCmdMsg
DispatchCmdMsg
DispatchCmdMsg
msg handler FALSE FALSE FALSE
FALSE msg handler msg handler
msg handler
图9…6 构成 「消息邦浦」之各个函数的调用次序
579
…………………………………………………………Page 642……………………………………………………………
第篇