Menu item keeps disabled even after ON_COMMAND handler is added

137 views Asked by At

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.

1

There are 1 answers

3
xMRi On

The reason is very simple. The Command Routing follows this rule:

  1. Frame
  2. Active View
  3. Document
  4. DocTemplate
  5. Application

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