您的位置:首页 > 其它

不同视图类之间的命令消息传递

2008-04-30 12:32 435 查看
我们先看看VC课上学的命令消息传递的路线:

命令消息接收者的类型处理次序
Frame窗口1.View
2.Frame窗口本身
3.CWinApp对象

View1.View本身
2.Document
Document1.Document本身
2.Document Template
前几天在我的科技创新项目中遇到了这样的问题:用资源编辑器在菜单栏中添加了一个菜单项,并在一个右视图类中添加了消息响应,但是程序运行时,那个菜单项不可用;而在另外一个左视图类中添加消息响应时没有出现问题。

我的界面设计成静态切分窗口,左视图派生自CTreeView,右视图派生自CFormView;右视图类是在AppWizard中添加的,左视图类是我自己在创建切分窗口的代码中添加的:

if (!m_wndSplitter.CreateStatic(this, 1, 2))

return FALSE;

if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CWellTreeView), CSize(150, 100), pContext) ||

!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CWellFormView), CSize(200, 100), pContext))

{

m_wndSplitter.DestroyWindow();

return FALSE;

}

return TRUE;

我原本以为在AppWizard中添加的类会首先接收到命令消息,但结果却不是那样,因此我判断第一个被创建的视图首先接受到命令消息,也就是说本该CWellFormView接收的命令消息被CWellTreeView “拦截”了,类似于Frame窗口接收的命令消息被View“拦截”。View“拦截”Frame的消息是怎么实现的呢?让我们看看MFC原始码:

BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
CPushRoutingFrame push(this);

// pump through current view FIRST
CView* pView = GetActiveView();
if (pView != NULL && pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;

// then pump through frame
if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;

// last but not least, pump through app
CWinApp* pApp = AfxGetApp();
if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;

return FALSE;
}

这样,我遇到的问题就迎刃而解了,我们可以向MFC学习,在CWellTreeView中重写虚函数OnCmdMsg,添加很简单的一段代码即可:

BOOL CWellTreeView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
// TODO: Add your specialized code here and/or call the base class
CWellListView* listview=(CWellListView*)GetView(RUNTIME_CLASS(CWellListView));
if(listview!=NULL && listview->OnCmdMsg(nID,nCode,pExtra,pHandlerInfo))
return TRUE;

return CTreeView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

接下来,CWellListView就可以响应命令消息了。嘿嘿,有点成就感!

要注意的是这两个View是不同的类,如果你做一个切分窗口两个VIew相同,就不存在视图之间的命令消息传递了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: