文檔視圖結構中命令的處理流程
(以MDI文檔視圖結構為例)
在應用程序的界面上,包含菜單、工具條等元素,當選取這些元素后,將發(fā)送一個命令給程序。同時,還有命令發(fā)送的其它形式,例如快捷鍵等等。
在文檔視圖結構中,程序包括一個主框架窗口,而具體打開的文件則包括其數(shù)據(jù)對象(CDocument) 表現(xiàn)形式(CView),和窗口容器(CFrameWnd)等幾個相關對象。命令發(fā)送后,將按照一定的流向傳達給指定的對象,由對象內成員函數(shù)響應解決。
一 命令的發(fā)送
在菜單或工具條上按下某項,(或按了對應的熱鍵)將向窗口發(fā)送一個WM_COMMAND消息
WM_COMMAND 參數(shù)包括3部分:wNotifyCode = HIWORD(wParam); // 來源類型 wID = LOWORD(wParam); // 命令IDhwndCtl = (HWND) lParam; // 來源窗口其中最重要的就是wID,它就是具體的命令。數(shù)值就是菜單項、工具按鈕、或按鍵組合的ID_?????。
在CWnd對象中,WM_COMMAND由OnCmdMsg()響應處理。
在MFC程序框架中,OnCmdMsg()當前將命令按特定流程發(fā)送給特定的對象處理。
二 命令ID
通常,命令ID 的數(shù)值范圍為:0x8000 -> 0xDFFF
// 8000 -> DFFF : user commands// E000 -> EFFF : AFX commands and other things// F000 -> FFFF : standard windows commands and other things etc// E000 -> E7FF standard commands// E800 -> E8FF control bars (first 32 are special)// E900 -> EEFF standard window controls/components// EF00 -> EFFF SC_ menu help// F000 -> FFFF standard strings
三 命令的流向
命令發(fā)送之初,是作為WM_COMMAND消息的參數(shù)傳給當前窗口。
如果沒有打開文件,則WM_COMMAND發(fā)送給父窗口(CMDIFrameWnd)
如果有文件打開過,則WM_COMMAND發(fā)送給激活的子框架窗口CMDIChildWnd)
另外CView,CWinApp,CDocument都是從CCmdTarget派生,都能響應命令,但它們不響應一般的窗口消息。
在CMDIFrameWnd和CMDIChildWnd中的OnCmdMsg()將根據(jù)需要轉發(fā)給CWinApp、CView或CDocument。
在這些類的基類CCmdTarget中OnCmdMsg將查找該類各層次的消息映射項,查找處理函數(shù)。
(1)若沒有文件打開,即只有主框架
概要: 在主框架內查命令處理,若未找到,交由應用程序類處理。
命令流向:主框架->應用程序類。
具體流程:
①調用CMDIFrameWnd::OnCmdMsg
{if(有子框架){交給子框架處理;CMDIChildWnd::OnCmdMsgreturn;}CFrameWnd::OnCmdMsgreturn;}②CFrameWnd::OnCmdMsg為:
{....由基類的OnCmdMsg處理,若框架中有該命令的處理函數(shù),函數(shù)將返回if(CWnd::OnCmdMsg)return;//如果在框架中沒有處理,就交給應用程序類處理命令CWinApp::OnCmdMsg}③若在框架中沒有處理該命令,轉交CWinApp處理。
CWinApp::OnCmdMsg
(2)有打開的文檔,存在子框架、視圖對象,文檔對象
命令流向:子框架接收到命令->視圖對象處理->文檔對象處理->文檔模板處理->子框架處理->應用程序對象處理
若在某一級被處理,則流程跳出。
具體流程:
WM_COMMAND 發(fā)送到子框架,在CMDIChildWnd::OnCmdMsg中包含下面步驟:
①先讓子框架上激活的視圖對象處理
執(zhí)行CView::OnCmdMsg
調用基類的OnCmdMsg,查找并執(zhí)行命令處理,
若未找到,交給文檔對象來處理命令
②執(zhí)行CDocument::OnCmdMsg
在文檔對象中查找命令處理函數(shù)。
若未找到,交由文檔模板處理。
③執(zhí)行CDocTemplate::OnCmdMsg
若命令未處理,返回到子框架,子框架處理
④子框架基類::OnCmdMsg執(zhí)行
若命令未處理,交由應用程序對象處理
⑤執(zhí)行CWinApp::OnCmdMsg
(#)