1. 程式人生 > >拆分視窗類CSplitterWnd在對話方塊中的應用及拆分子視窗間的通訊

拆分視窗類CSplitterWnd在對話方塊中的應用及拆分子視窗間的通訊

當你在GOOGLE或者百度鍵入"如何在對話方塊中使用CSplitterWnd“時,搜尋出來的帖子大多千篇一律,鮮有真正是基於對話方塊的CSplitterWnd應用,大多是基於單文件框架的說明。至於具有參考價值的一篇博文,請參見Codeguru

本文將告訴你如何在對話方塊中使用CSplitterWnd將主視窗拆分成兩個子視窗,並且只與檢視類有關,不涉及文件類。過載OnSize(), 使得視窗的大小可隨主視窗的變化而改變。

步驟如下:

1,在主視窗類(某對話方塊)標頭檔案中分別宣告一個框架類以及一個CSplitterWnd拆分視窗類的指標型別成員變數

  1. private:  
  2.     CFrameWnd*      m_pFrameSplit;    // 分隔視窗
  3.     CSplitterWnd    m_wndSpliter;     // 左右分隔

2,在主視窗類實現檔案中的OnInitDialog()方法事件中進行初始化工作,註冊框架類及初始CSplitterWnd
  1. // 取得主視窗區域
  2. CRect rc;  
  3. GetDlgItem(IDC_CHILDWND)->GetWindowRect(rc);  //IDC_CHILDWND是一個PictureBox的ID,表示要拆分的區域
  4. ScreenToClient(&rc);  
  5. // 註冊框架類
  6. CString sClass = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW,  
  7.     ::LoadCursor(NULL, IDC_ARROW), (HBRUSH)::GetStockObject(WHITE_BRUSH),  
  8.     ::LoadIcon(NULL, IDI_APPLICATION));  
  9. // 建立分隔視窗框架
  10. m_pFrameSplit = new CFrameWnd;  
  11. m_pFrameSplit->Create(sClass, _T(""), WS_CHILD, CRect(0,0,0,0), this);  
  12. m_pFrameSplit->MoveWindow(rc);  
  13. m_pFrameSplit->ShowWindow(SW_SHOW);  
  14. // 建立分割視窗
  15. m_wndSpliter.CreateStatic(m_pFrameSplit, 1, 2);  
  16. m_wndSpliter.CreateView(0, 0, RUNTIME_CLASS(CEditView), CSize((int)(rc.Width() * 0.265), 0), NULL);   // 左視窗所佔比例26.5%
  17. m_wndSpliter.CreateView(0, 1, RUNTIME_CLASS(CEditView), CSize(0,0), NULL);  
  18. m_wndSpliter.MoveWindow(0, 0, rc.Width(), rc.Height());  
  19. m_wndSpliter.ShowWindow(SW_SHOW);  

注意倒數第三、四行。這裡是要拆分的兩個視窗對應的檢視類,為了方便演示CSplitterWnd類拆分的效果,可以先直接用CEditView代替。

執行結果,主視窗的PictureBox區域被拆分成兩個EditBox,中間有可移動的分隔欄用以調節大小。

3.過載OnSize(),使得視窗及控制元件自適應大小。傳控制元件指標或ID兩種方式均可。

  1. void CMainWndDlg::OnSize(UINT nType, int cx, int cy)  
  2. {  
  3.     CDialog::OnSize(nType, cx, cy);  
  4.     staticint nLastCx = 0;  
  5.     staticint nLastCy = 0;  
  6.     int nWidth  = cx - nLastCx;  
  7.     int nHeight = cy - nLastCy;  
  8.     AdjustDlgItem(m_pFrameSplit, 0, 0, nWidth, nHeight);  
  9.     nLastCx = cx;  
  10.     nLastCy = cy;  
  11. }  
  12. // 移動控制元件 以實現視窗自適應
  13. void CMainWndDlg::AdjustDlgItem(UINT nId, int nLeft, int nTop,int nRight, int nBottom)  
  14. {  
  15.     AdjustDlgItem(GetDlgItem(nId), nLeft, nTop, nRight, nBottom);  
  16. }  
  17. // 移動控制元件 以實現視窗自適應
  18. void CMainWndDlg::AdjustDlgItem(CWnd* pItem, int nLeft, int nTop,int nRight, int nBottom)  
  19. {  
  20.     if(NULL == pItem)  
  21.         return;  
  22.     if(!IsWindow(pItem->GetSafeHwnd()))  
  23.         return;  
  24.     // 取得控制元件區域
  25.     CRect rcWnd;  
  26.     pItem->GetWindowRect(&rcWnd);  
  27.     ScreenToClient(&rcWnd);  
  28.     // 重新計算區域
  29.     rcWnd.top += nTop;  
  30.     rcWnd.bottom += nBottom;  
  31.     rcWnd.left += nLeft;  
  32.     rcWnd.right += nRight;  
  33.     // 移動控制元件
  34.     pItem->MoveWindow(rcWnd.left, rcWnd.top, rcWnd.Width(), rcWnd.Height());  
  35. }  

為分割窗新增一些自己需要的功能