MFC Tabbed Documents - how to enable middle-mouse button to close document?
Asked Answered
B

1

6

If you create a new MFC application (with MFC Feature Pack), and using all the defaults, click Finish. It creates an MDI application with the new "Tabbed Documents" style.

alt text

I think these are great except it really annoys me that I can't close a Tabbed Document window by middle-clicking on the tab.

This is possible in Firefox, IE, Chrome and more importantly VS2008. But clicking the middle-button on a tab doesn't do anything.

I cannot figure out how to override the tab bar to allow me to handle the ON_WM_MBUTTONDOWN message. Any ideas?

Edit: Guessing I need to subclass the CMFCTabCtrl returned from CMDIFrameWndEx::GetMDITabs...

Brittani answered 5/8, 2009 at 16:5 Comment(0)
B
4

No subclassing needed (phew). Managed to get it working by hijacking the PreTranslateMessage of the mainframe. If the current message is a middle-mouse-button message, I check the location of the click. If it was on a tab then I close that tab.

BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
    switch (pMsg->message)
    {
        case WM_MBUTTONDBLCLK:
        case WM_MBUTTONDOWN:
        {
            //clicked middle button somewhere in the mainframe.
            //was it on a tab group of the MDI tab area?
            CWnd* pWnd = FromHandle(pMsg->hwnd);
            CMFCTabCtrl* tabGroup = dynamic_cast<CMFCTabCtrl*>(pWnd);
            if (tabGroup)
            {
                //clicked middle button on a tab group.
                //was it on a tab?
                CPoint clickLocation = pMsg->pt;
                tabGroup->ScreenToClient(&clickLocation);
                int tabIndex = tabGroup->GetTabFromPoint(clickLocation);
                if (tabIndex != -1)
                {
                    //clicked middle button on a tab.
                    //send a WM_CLOSE message to it
                    CWnd* pTab = tabGroup->GetTabWnd(tabIndex);
                    if (pTab)
                    {
                        pTab->SendMessage(WM_CLOSE, 0, 0);
                    }
                }
            }
            break;
        }
        default:
        {
            break;
        }
    }
    return CMDIFrameWndEx::PreTranslateMessage(pMsg);
}
Brittani answered 6/8, 2009 at 13:20 Comment(1)
After SendMessage(..) should return TRUE; Otherwise MFC might get confused.Arratoon

© 2022 - 2024 — McMap. All rights reserved.