CMFCTabCtrl控件创建在对话框窗口上
使用m_wndTabs.EnableActiveTabCloseButton();显示关闭按钮
但是点击关闭却没反应,该如何实现关闭功能?

解决方案 »

  1.   

    还在用VS2003,没用过 CMFCTabCtrl
      

  2.   

    VS2008+SP1就有,我试过关闭不了
    于是又下了个VS2010,还是不行
      

  3.   

    难道只有用在frame结构才可以关闭?
      

  4.   

    哎呀,这个bug修改难度很大啊,2010也有,楼主怎么搞定的,诚心求教啊转:
    CMFCTabCtrl::EnableActiveTabCloseButton
    用于在CMFCTabCtrl的Tab页显示一个关闭按钮,看看关闭按钮怎么实现:void  CMFCBaseTabCtrl::OnLButtonDown(UINT nFlags, CPoint point)
    {
     m_bWindowPosChanged = FALSE;
     CWnd::OnLButtonDown(nFlags, point);
      if  (m_rectCloseButton.PtInRect(point))
     {
      m_bTabCloseButtonPressed = TRUE;
      RedrawWindow(m_rectCloseButton);
       return ;
     }
    ...
      void  CMFCBaseTabCtrl::OnLButtonUp(UINT nFlags, CPoint point)
    {
      if  (m_bTabCloseButtonPressed)
     {
      m_bTabCloseButtonPressed = FALSE;
      m_bTabCloseButtonHighlighted = FALSE;
      RedrawWindow(m_rectCloseButton);
       if  (m_rectCloseButton.PtInRect(point))
      {
       CWnd* pWndActive = GetActiveWnd();
        if  (pWndActive != NULL)
       {
        pWndActive->SendMessage(WM_CLOSE);
       }
        return ;
      }
     }
    ...
    应该就这些了。在例子TabbedView中添加这个功能:int  CTabbedViewView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
      if  (CTabView::OnCreate(lpCreateStruct) == -1)
       return  -1;
     AddView (RUNTIME_CLASS (CView1), _T( "Simple" ), 100);
     AddView (RUNTIME_CLASS (CView2), _T( "List" ), 101);
     AddView (RUNTIME_CLASS (CView3), _T( "Form" ), 102);
     AddView (RUNTIME_CLASS (CView4), _T( "ScrollView" ), 102);
     m_wndTabs.EnableActiveTabCloseButton();
      return  0;
    }
    然后点击一个页面上的关闭按钮,会发现这个tab页并没有消失,而切换到其他页面,程序就中断了,问题出在:BOOL  CMFCTabCtrl::SetActiveTab( int  iTab)
    {
    ...
      if  (m_iActiveTab != -1 && m_bHideInactiveWnd)
     {
       //--------------------
       // Hide active window:
       //--------------------
      CWnd* pWndActive = GetActiveWnd();
       if  (pWndActive != NULL)
      {
       pWndActive->ShowWindow(SW_HIDE);
      }
     }
    由于窗口已经销毁,而该Tab页仍然存在,所以m_iActiveTab就是被销毁的窗口所在页面,pWndActive是已经被销毁的窗口,自然调用其ShowWindow方法就出错了。
    个人感觉,他找到的错误还不全,在点击了关闭按钮后,执行:
    void CMFCBaseTabCtrl::OnLButtonDown(UINT nFlags, CPoint point)
    {
    m_bWindowPosChanged = FALSE; CWnd::OnLButtonDown(nFlags, point); if (m_rectCloseButton.PtInRect(point))
    {
    m_bTabCloseButtonPressed = TRUE;               //改变了这个标志位
    RedrawWindow(m_rectCloseButton);               
    return;                                        //然后return掉

    }到这里:void CMFCTabCtrl::OnLButtonDown(UINT nFlags, CPoint point)
    {
    ... ...
    CMFCBaseTabCtrl::OnLButtonDown(nFlags, point); if (!m_bReadyToDetach)
    {
    CWnd* pWndTarget = FindTargetWnd(point);
    if (pWndTarget != NULL)
    {
    ASSERT_VALID(pWndTarget); MapWindowPoints(pWndTarget, &point, 1);
    pWndTarget->SendMessage(WM_LBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
    }
    }
    }应该进入if语句,结果pWndTarget == null,进不去,这个功能就无法实现了...
      

  5.   

      if (m_rectCloseButton.PtInRect(point))
      {
      CWnd* pWndActive = GetActiveWnd();
      if (pWndActive != NULL)
      {
      pWndActive->SendMessage(WM_CLOSE);
      }
      return ;
      }
     }
    关键代码在这里   看到 pWndActive->SendMessage(WM_CLOSE);了么?实际上就是调用了 要关闭页面的WM_CLose 消息
      

  6.   

    BOOL CMyMFCTabCtrl::OnCommand(WPARAM wParam, LPARAM lParam)
    {
            // TODO: 在此添加专用代码和/或调用基类
            if ((HWND)lParam == m_btnClose.GetSafeHwnd())
            {
                    {
                            int nTab = GetActiveTab();
                            if (nTab >= 0)
                            {
                                    CWnd* pWnd = GetTabWnd (nTab);
                            pWnd->DestroyWindow ();
                            delete pWnd;
                                    RemoveTab(nTab);
                            }
                            return true;
                    }
            }
            return CMFCTabCtrl::OnCommand(wParam, lParam);
    }最近怎么老有人问,这是从别的帖子里找过来的,希望有用。
    换工作很久了,改Android了,原来的代码都丢了。给不了更多的消息了,抱歉啊
      

  7.   

    我解决了void CMyMFCTabCtrl::OnLButtonDown(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    bool bClose = true;
    int nTab = GetTabFromPoint(point);
    if (nTab >= 0 && nTab != GetActiveTab())
    bClose = false; // 切换则不关闭 // 先执行基类操作,否则会丢失窗口焦点
    CMFCTabCtrl::OnLButtonDown(nFlags, point); if (bClose)
    CloseTab(point);
    }void CMyMFCTabCtrl::CloseTab(CPoint point)
    {
    if (m_rectCloseButton.PtInRect(point))
    {
    int nTab = GetActiveTab();
    if (nTab >= 0)
    {
    if (nTab > 0)
    SetActiveTab(nTab - 1);
    RemoveTab(nTab);
    }
    }
    }