下面就谈谈命令消息WM_COMMAND的路由吧,作为一次学习笔记吧
下面是从MSDN上copy过来的命令消息路由表:(很详细哦)
下面就以单文档中的菜单命令为例,阐述一下命令消息的路由。
有过菜单编程经验的,想必都知道如何响应菜单命令。就是直接在视类中添加处理就可以了,
但有些情况下我们可能想在主框架中实现对菜单命令的捕捉,怎么办呢???
当然我们可以在主框架中添加菜单命令处理函数,但是如果我们再在视类中也添加了处理函数
会发生什么??
主框架中的菜单命令处理函数没有被调用!!??
为什么?因为视类已对该菜单命令做了处理,消息路由已经结束了,不会再往下传递了。
那为什么是视类先处理,而不是主框架先处理呢?
这就涉及到了命令消息的路由了,命令消息的首先接收着者是主框架(有点矛盾啊,既然它先接收
为什么还是视类先处理呢??有疑问的看后文吧)
虽然主框架先接收,但是主框架不先处理(就像领导接到上级的一个命令,它会让自己的下级先
处理,下级处理不了的或不愿处理的自己才会处理),而是传给了视类让视类先处理,如果视类
也没有处理,它就会让文档类来处理,如果文档类也没有处理,就会将命令退回到视类,视类
再退回到框架类,框架类一看,没辙了,就只有自己处理啦,但万一自己也不好处理,就会传
给应用程序类。
当有些情况下我们希望,有些菜单命令只有主框架才有处理权,其他类不管用什么办法也没辙。
那我们就得重载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);//其它命令消息可以继续由此传递下去
}
下面是从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);//其它命令消息可以继续由此传递下去
}