下面是從MSDN上copy過來的命令消息路由表:(很詳細哦)
MDI frame window (CMDIFrameWnd) |
|
Document frame window (CFrameWnd, CMDIChildWnd) |
|
View |
|
Document |
|
Dialog box |
|
下面就以單文檔中的菜單命令爲例,闡述一下命令消息的路由。
有過菜單編程經驗的,想必都知道如何響應菜單命令。就是直接在視類中添加處理就可以了,
但有些情況下我們可能想在主框架中實現對菜單命令的捕捉,怎麼辦呢???
當然我們可以在主框架中添加菜單命令處理函數,但是如果我們再在視類中也添加了處理函數
會發生什麼??
主框架中的菜單命令處理函數沒有被調用!!??
爲什麼?因爲視類已對該菜單命令做了處理,消息路由已經結束了,不會再往下傳遞了。
那爲什麼是視類先處理,而不是主框架先處理呢?
這就涉及到了命令消息的路由了,命令消息的首先接收着者是主框架(有點矛盾啊,既然它先接收
爲什麼還是視類先處理呢??有疑問的看後文吧)
雖然主框架先接收,但是主框架不先處理(就像領導接到上級的一個命令,它會讓自己的下級先
處理,下級處理不了的或不願處理的自己纔會處理),而是傳給了視類讓視類先處理,如果視類
也沒有處理,它就會讓文檔類來處理,如果文檔類也沒有處理,就會將命令退回到視類,視類
再退回到框架類,框架類一看,沒轍了,就只有自己處理啦,但萬一自己也不好處理,就會傳
給應用程序類。
當有些情況下我們希望,有些菜單命令只有主框架纔有處理權,其他類不管用什麼辦法也沒轍。
那我們就得重載OnCommand,它是命令消息的第一站(相對而言暫且這麼說吧,當然前面還
又WndProc,OnWndMsg等等的傳遞幫手啦),那麼我們就可以在這裏攔劫特殊的消息:
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
UINT testID = LOWORD( wParam );
if( testID == IDM_TEST )//攔劫菜單項ID爲DM_TEST的消息
{
MessageBox( "Click in MainFrame" );
return TRUE;//此消息已處理不再向下傳遞
}
return CFrameWnd::OnCommand(wParam, lParam);//其它命令消息可以繼續由此傳遞下去
}