I've made a simple split-window application using Visual Studio 2013. There are two views, one view is made of default-view-class and the other view is made of custom-view-class derived from CScrollView
.
/////////////////////////
// MainFrm.cpp
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,CCreateContext* pContext)
{
split_wnd.CreateStatic(this,1,2);
CRect cr;
GetClientRect(&cr);
split_wnd.CreateView(0,0,RUNTIME_CLASS(CProjectMainView),CSize(cr.Width()/2,cr.Height()),pContext);
split_wnd.CreateView(0,1,RUNTIME_CLASS(CMyCustomView),CSize(cr.Width()/2,cr.Height()),pContext);
return true;
}
This splitter works fine.
The problem occurs when I tried to add a ON_COMMAND
handler to one of menu items. If I put the ON_COMMAND
handler in the default-view-class there is no issue. Menu item clicks well and handler works.
But if I put the ON_COMMAND
handler in the custom-view-class, the menu item does not get enabled at all.
I believe I've done everything to implement message-map properly in my custom-view-class.
/////////////////////////
// CMyCustomView.h
class CMyCustomView:public CScrollView
{
public:
DECLARE_DYNCREATE(CMyCustomView)
CMyCustomView();
~CMyCustomView();
virtual void OnDraw(CDC* /*pDC*/);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void OnInitialUpdate();
public:
DECLARE_MESSAGE_MAP()
afx_msg void OnMenuIdTestMessageMap();
};
The DECLARE_MESSAGE_MAP()
is definitely there in MyCustomView.h
And of course, I've added BEGIN_MESSAGE_MAP
, END_MESSAGE_MAP()
pair in MyCustomView.cpp file.
/////////////////////////
// CMyCustomView.cpp
BEGIN_MESSAGE_MAP(CMyCustomView,CScrollView)
ON_COMMAND(MENU_ID_TEST_MESSAGE_MAP,&CMyCustomView::OnMenuIdTestMessageMap)
END_MESSAGE_MAP()
void CMyCaptureView::OnMenuIdTestMessageMap()
{
// TODO: Add your command handler code here
}
But still, the menu item won't get enabled at all. It just stay grayed.
I've googled as far as I can, but it seems that nobody's had this experience up to now. Is it impossible to add ON_COMMAND
handler to custom-view-class, in the first place ? I hope not.
Please give some advice to me. Thank you.
The reason is very simple. The Command Routing follows this rule:
There is no routing to a different view in a splitter window.
If you want a different behaviour, create a OnCmdMsg handler in your frame that host the splitter windows. Call first OnCmdMsg to the active splitter view and than (if not handled) reroute it to the second embedded view.
See TN021