CDockablePane 关闭的问题

显示或者隐藏

  当点击CDockablePane上的关闭按钮时,并不能将其关闭,知识将其隐藏了起来,如果需要重新显示或隐藏,则相关命令的响应函数如下:

  1. if(m_Panes.GetSafeHwnd())
  2. {
  3.      BOOL flag = !m_Panes.IsVisible();
  4.      m_Panes.ShowPane(flag,FALSE,flag);
  5. }

关闭按钮的响应函数

  当点击CDockablePane上的关闭按钮时,主框架会进行响应

  1. //关闭停靠窗口事件,事实上是隐藏窗体,还是占用资源的
  2. BOOL CMainFrame::OnCloseDockingPane(CDockablePane* pWnd) ;
  3. //关闭悬浮窗口事件,事实上液是隐藏窗体,还是占用资源的
  4. BOOL CMainFrame::OnCloseMiniFrame(CPaneFrameWnd* pWnd)

  因此,如果仅仅是重写这两个消息,没做什么处理,那么内存还是消不下去,经过调试,获知如下方式可以真正销毁关闭该Dock窗体:

  //停靠窗体关闭
  BOOL CMainFrame::OnCloseDockingPane(CDockablePane* pWnd)
  {
    //处理关闭事件
      if(pWnd->IsKindOf(RUNTIME_CLASS(CTabbedPane)))

     { //多个窗口
           CTabbedPane* tabpane = (CTabbedPane *)pWnd;
           CMFCBaseTabCtrl* pTabWnd = tabpane->GetUnderlyingWindow();
           int num = pTabWnd->GetActiveTab();
           if(num >= 0)

        {   //这里仅仅关闭活动的面板
               CDockablePane* pBar = DYNAMIC_DOWNCAST(CDockablePane, pTabWnd->GetTabWnd(num));
                 if (pBar != NULL)
                 {
                     ASSERT_VALID(pBar);
                    //将关闭消息加入该DockPane队列,等待完成本函数后关闭
                     ::PostMessageA(pBar->m_hWnd ,WM_CLOSE, 0 , 0);
                 }
           }
      }
     else

    {

      //单个窗口
         CDockablePane* pane = (CDockablePane*)pWnd;
         if(pane->IsKindOf(RUNTIME_CLASS(CDockablePane)) ||  pane->IsKindOf(RUNTIME_CLASS(CPane))

      && !pane>IsKindOf(RUNTIME_CLASS(CMFCToolBar)))

      {
                //将关闭消息加入该DockPane队列,等待完成本函数后关闭
                ::PostMessageA(pane->m_hWnd ,WM_CLOSE, 0 , 0);
           }
      }
      return TRUE;
  }

//关闭悬浮窗体
  BOOL CMainFrame::OnCloseMiniFrame(CPaneFrameWnd* pWnd)
  {
     //处理关闭事件
      CWnd* pwnd = pWnd->GetPane();
      if(pwnd->IsKindOf(RUNTIME_CLASS(CTabbedPane)))

     {

       //多个窗口
          CTabbedPane* tabpane = (CTabbedPane *)pwnd;
          CMFCBaseTabCtrl* pTabWnd = tabpane->GetUnderlyingWindow();
           //关闭所有的面板
           for(int i=0;i<pTabWnd->GetTabsNum();i++)
           {
                CDockablePane* pBar = DYNAMIC_DOWNCAST(CDockablePane, pTabWnd->GetTabWnd(i));
                if (pBar != NULL)
                {
                     ASSERT_VALID(pBar);
                    //将关闭消息加入该DockPane队列,等待完成本函数后关闭
                     ::PostMessageA(pBar->m_hWnd ,WM_CLOSE, 0 , 0);
                }
          }
      }
      else

     {

       //单个窗口
          CDockablePane* pane = (CDockablePane *)pwnd;
         if(pane->IsKindOf(RUNTIME_CLASS(CDockablePane)) || pane->IsKindOf(RUNTIME_CLASS(CPane))

        && pane->IsKindOf(RUNTIME_CLASS(CPaneFrameWnd)))

      {
           //将关闭消息加入该DockPane队列,等待完成本函数后关闭
             ::PostMessageA(pWnd->GetPane()->m_hWnd ,WM_CLOSE, 0 , 0);
          }
      }
    return TRUE;
}

//关闭后,如视图需要重新打开,用这句:
  if(m_wndClassView.GetSafeHwnd())
  {
      m_wndClassView.ShowPane(TRUE,FALSE,TRUE);
      return ;
  }
  else

  {
      UINT Dockstyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT |CBRS_FLOAT_MULTI;

        BOOL bNameValid;
        CString strClassView;
        bNameValid = strClassView.LoadString(IDS_CLASS_VIEW);
        ASSERT(bNameValid);

        if (!m_wndClassView.Create(strClassView, this, CRect(0, 0, 200, 200),

                TRUE, ID_VIEW_ONLINE_CLIENT_TERR_PANE,

                Dockstyle ,AFX_CBRS_OUTLOOK_TABS))
        {
            TRACE("未能创建%s窗口 " ,strClassView);
            return ;
        }
        m_wndClassView.EnableDocking(CBRS_ALIGN_ANY);
        DockPane(&m_wndClassView);

   }

原文地址:https://www.cnblogs.com/canger/p/4156531.html