Elamir Ohana
Elamir Ohana

Reputation: 292

How to add a document menu in MFC application?

when you click right click on any tab in visual studio a menu will appear containing some options like(Save, Close all but this, Copy full path, Open containing folder, ....). How to add a menu like that in MFC(doc/view) tabbed application? Thanks in advance.

Upvotes: 0

Views: 935

Answers (2)

Elamir Ohana
Elamir Ohana

Reputation: 292

I've handled the message WM_RBUTTONUP on the function PreTranslateMessage as following:

BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
  if( WM_RBUTTONUP == pMsg->message)
  {
    //check that the right click is on MDI tab area.
    CWnd* pWnd = FromHandle(pMsg->hwnd);
    CMFCTabCtrl* tabGroup = dynamic_cast<CMFCTabCtrl*>(pWnd);
    if (tabGroup)
    {
      CPoint clickLocation = pMsg->pt;
      tabGroup->ScreenToClient(&clickLocation);
      int tabIndex = tabGroup->GetTabFromPoint(clickLocation);
      if (tabIndex != -1)
      {
        CWnd* pTab = tabGroup->GetTabWnd(tabIndex);
        if (pTab)
        {
          CPoint point = pMsg->pt;
          ClientToScreen (&point);
          ShowPopupTabOptions(point);
        }
      }
    }
  }

  return CMDIFrameWndEx::PreTranslateMessage(pMsg);
}

Upvotes: 0

Barmak Shemirani
Barmak Shemirani

Reputation: 31599

You should have more than one menu. IDR_MAINFRAME is usually used when no documents are opened, that's not the one you want.

Resource editor should show another main menu (not a popup menu) whose ID is something like IDR_MyAppTYPE. This menu ID should already be in your CWinAppEx class:

BOOL CMyApp::InitInstance()
{
    ...
    pDocTemplate = new CMultiDocTemplate(IDR_MyAppTYPE, ...);
    ...
}

This is your document menu.

Edit this menu using the resource editor. Add the command "Close all but this" and the id for menu command would be something like ID_WINDOW_CLOSEALL_BUT_THIS

You have to handle this command in CView derived class. Example:

BEGIN_MESSAGE_MAP(CMyView, CView)
    ON_COMMAND(ID_WINDOW_CLOSEALL_BUT_THIS, OnCloseAllButThis)
    ...
END_MESSAGE_MAP()

void CMyView::OnCloseAllButThis()
{
    POSITION p1 = AfxGetApp()->GetFirstDocTemplatePosition();
    while(p1)
    {
        CDocTemplate *doctempl = AfxGetApp()->GetNextDocTemplate(p1);
        POSITION p2 = doctempl->GetFirstDocPosition();
        while(p2)
        {
            CDocument* doc = doctempl->GetNextDoc(p2);
            POSITION p3 = doc->GetFirstViewPosition();
            while(p3)
            {
                CView* view = doc->GetNextView(p3);
                if(view && view->GetParentFrame() && view != this)
                    view->GetParentFrame()->SendMessage(WM_CLOSE);
            }
        }
    }
}

Upvotes: 1

Related Questions