MFC 选项卡式文档 - 如何启用鼠标中键来关闭文档?

发布于 2024-07-30 01:09:18 字数 525 浏览 7 评论 0原文

如果创建新的 MFC 应用程序(带有 MFC 功能包)并使用所有默认值,请单击“完成”。 它使用新的“选项卡式文档”样式创建 MDI 应用程序。

替代文本

我认为这些都很棒,但令我烦恼的是我无法通过中键单击选项卡来关闭选项卡式文档窗口。

这在 Firefox、IE、Chrome 以及更重要的 VS2008 中都是可能的。 但是单击选项卡上的中间按钮不会执行任何操作。

我不知道如何覆盖选项卡栏以允许我处理 ON_WM_MBUTTONDOWN 消息。 有任何想法吗?

编辑:猜测我需要子类化从 CMDIFrameWndEx::GetMDITabs 返回的 CMFCTabCtrl...

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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绾颜 2024-08-06 01:09:18

不需要子类化(唷)。 通过劫持主机的 PreTranslateMessage 使其正常工作。 如果当前消息是鼠标中键消息,我会检查单击的位置。 如果它在选项卡上,那么我会关闭该选项卡。

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);
}

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文