上一節中雞啄米講了文檔、視圖和框架結構中各對象之間的關系,本節主要講講在MFC中如何分割窗口。

      分割窗口概述

      分割窗口,顧名思義,就是將一個窗口分割成多個窗格,在每個窗格中都包含有視圖,或者是同一類型的視圖,或者是不同類型的視圖。

       MFC分割窗口的方式有兩種,動態分割和靜態分割。

       動態分割窗口通常用于創建同一個文檔對應的多個視圖,而且這些視圖一般都是同一類型的視圖,能夠在用戶編輯文檔的不同部分時提供方便。

       大家看下Word里的動態分割窗口就很明白了,以Word 2007文檔為例,在菜單中點擊“視圖”->“拆分”,就可以看到一條隨鼠標移動的分隔條,當我們在文檔中某個位置按下鼠標左鍵時,分割條就固定了下來,生成了上下兩個分割窗格,通過滾動每個窗格中的垂直滾動條可以看到,兩個窗格中的內容相同,這就是所說的對應同一個文檔的同一類視圖。

       動態分割窗口最多可以有兩行兩列。

       靜態分割窗口比較常見。我們經常能看到某個軟件打開后,界面窗口默認被分割成了幾個窗格,這就是靜態分割窗口。

       靜態分割窗口指在窗口創建時,分割的窗格就已經生成了,而且用戶不能改變窗格的數量和順序。靜態分割窗口最多支持16行16列。通常靜態分割窗口的每個窗格中包含不同類的視圖,當然也可以是同一類的視圖。

       CSplitterWnd類

       MFC中的分割窗口類-CSplitterWnd類提供了分割窗口的功能。CSplitterWnd類中包含一個分割器窗口,該分割器窗口就是一個包含多個窗格的窗口。我們分割窗口時就是直接在此分割器窗口中分割的。

       雞啄米下面介紹三個最常用的成員函數:

C++代碼
  1. virtual BOOL Create(   
  2.    CWnd* pParentWnd,   
  3.    int nMaxRows,   
  4.    int nMaxCols,   
  5.    SIZE sizeMin,   
  6.    CCreateContext* pContext,   
  7.    DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | SPLS_DYNAMIC_SPLIT,   
  8.    UINT nID = AFX_IDW_PANE_FIRST    
  9. );  

       創建動態分割窗口。參數pParentWnd為分割器窗口的父框架窗口;參數nMaxRows為分割器窗口的最大行數,不能超過2;參數nMaxCols為分割器窗口的最大列數,也不能超過2;參數sizeMin為窗格能顯示的最小尺寸,如果窗格尺寸小于sizeMin則不顯示;參數pContext為指向CCreateContext結構的指針,大多數情況下可以賦值為父框架窗口的pContext;參數dwStyle指定窗口風格;參數nID為分割窗口的ID,除非分割器窗口嵌入到另一個分割器窗口中,否則可以取值AFX_IDW_PANE_FIRST。

C++代碼
  1. virtual BOOL CreateStatic(   
  2.    CWnd* pParentWnd,   
  3.    int nRows,   
  4.    int nCols,   
  5.    DWORD dwStyle = WS_CHILD | WS_VISIBLE,   
  6.    UINT nID = AFX_IDW_PANE_FIRST    
  7. );  

       創建靜態分割窗口。參數pParentWnd、dwStyle和nID同上;參數nRows為行數,不能超過16;參數nCols為列數,同樣不能超過16。

C++代碼
  1. virtual BOOL CreateView(   
  2.    int row,   
  3.    int col,   
  4.    CRuntimeClass* pViewClass,   
  5.    SIZE sizeInit,   
  6.    CCreateContext* pContext    
  7. );  

       為靜態分割窗口創建窗格視圖。參數row指定分割器窗口中放置新視圖的行;參數col指定放置新視圖的列;參數pViewClass指定新視圖的CRuntimeClass對象;參數sizeInit指定新視圖的初始大??;參數pContext為指向CCreateContext結構的指針,通??梢再x值為傳遞給父框架窗口的重載函數CFrameWnd::OnCreateClient的pContext參數值。

       動態分割窗口

       創建動態分割窗口的步驟為:

       1. 在父框架類中定義一個CSplitterWnd類型的成員對象。

       2. 重載父框架類的CFrameWnd::OnCreateClient成員函數。

       3. 在重載的CFrameWnd::OnCreateClient函數中調用CSplitterWnd成員對象的Create函數。

       下面雞啄米給大家一個實例。同樣以VS2010/MFC編程入門之三十四(菜單:VS2010菜單資源詳解)中創建Example34工程為例,我們要實現在主框架窗口的客戶區中創建兩行兩列的動態分割窗口。以下是創建動態分割窗口的具體步驟:

       1. 在MainFrm.h文件中為CMainFrame類添加成員對象:CSplitterWnd m_wndSplitter;。

       2. 在Class View類視圖中找到CMainFrame類,右鍵點擊,在右鍵菜單中選擇Properties,就會顯示屬性頁,然后在屬性頁的工具欄上點擊Tip為Overrides的按鈕,下面的列表中就列出了能夠重載的函數,找到OnCreateClient生成重載函數。

       3. 在MainFrm.cpp文件中找到剛重載的OnCreateClient函數修改如下:

C++代碼
  1. BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)   
  2. {   
  3.  // TODO: Add your specialized code here and/or call the base class   
  4.  // 創建動態分割窗口,兩行兩列   
  5.  return m_wndSplitter.Create(this,2, 2, CSize(10, 10), pContext);   
  6.   
  7.  //return CFrameWndEx::OnCreateClient(lpcs, pContext);   
  8. }  

       4. 在Resource View資源視圖中,打開Menu下的IDR_MAINFRAME菜單,在View下添加一個菜單項,Caption設為Splitter Window,ID設為(一定要設為)ID_WINDOW_SPLIT。這樣在運行結果界面中點擊此菜單項時MFC會執行一些操作顯示動態分割窗口。

       5. 運行程序,點擊菜單中的View->Splitter Window菜單項,創建動態分割窗口后效果如下:

 動態分割窗口

       靜態分割窗口

       創建靜態分割窗口的步驟為:

       1. 在父框架類中定義一個CSplitterWnd類型的成員對象。

       2. 重載父框架類的CFrameWnd::OnCreateClient成員函數。

       3. 在重載的CFrameWnd::OnCreateClient函數中調用CSplitterWnd成員對象的CreateStatic成員函數,然后可以調用CSplitterWnd成員對象的CreateView成員函數為每個窗格創建視圖。 

       雞啄米仍通過Example34工程給大家一個實例,目的是在主框架窗口中的客戶區創建一個兩行一列的靜態分割窗口。如果已經試驗過動態分割窗口的創建,那么麻煩撤銷那些修改吧。創建靜態分割窗口的具體步驟如下:

       1. 在MainFrm.h文件中為CMainFrame類添加成員對象:CSplitterWnd m_wndSplitter;。

       2. 在Class View類視圖中找到CMainFrame類,右鍵點擊,在右鍵菜單中選擇Properties,就會顯示屬性頁,然后在屬性頁的工具欄上點擊Tip為Overrides的按鈕,下面的列表中就列出了能夠重載的函數,找到OnCreateClient生成重載函數。

       3. 在MainFrm.cpp文件中找到剛重載的OnCreateClient函數進行修改。因為雞啄米沒有新建其他視圖類,所以上下兩個窗格的視圖都是CExample34View。為了能識別CExample34View類,還需在MainFrm.cpp文件中添加#include "Example34View.h",在Example34View.h文件中添加#include "Example34Doc.h"。最終OnCreateClient函數修改如下:

C++代碼
  1. BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)   
  2. {   
  3.     // TODO: Add your specialized code here and/or call the base class   
  4.     CRect rc;   
  5.   
  6.     // 獲取框架窗口客戶區的CRect對象   
  7.     GetClientRect(&rc);   
  8.   
  9.     // 創建靜態分割窗口,兩行一列   
  10.     if (!m_wndSplitter.CreateStatic(this, 2, 1))   
  11.         return FALSE;   
  12.   
  13.     // 創建上面窗格中的視圖   
  14.     if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CExample34View), CSize(rc.Width(), rc.Height()/2), pContext))   
  15.         return FALSE;   
  16.   
  17.     // 創建下面窗格中的視圖   
  18.     if (!m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CExample34View), CSize(rc.Width(), rc.Height()/2), pContext))   
  19.         return FALSE;   
  20.   
  21.     return TRUE;   
  22.   
  23.     //return CFrameWndEx::OnCreateClient(lpcs, pContext);   
  24. }  

       4. 運行程序,在結果界面中關掉其他面板后效果如下:

 靜態分割窗口

       如果大家想創建在其中某個窗格中再嵌套分割窗口,那么就需要再定義一個CSplitterWnd對象,以父窗格所在的CSplitterWnd對象為父框架窗口創建分割窗口即可。

       分割窗口的內容就講到這里了。雞啄米依然謝謝大家的支持。

除非特別注明,雞啄米文章均為原創
轉載請標明本文地址:http://www.9385095.live/software/226.html
2012年8月24日
作者:雞啄米 分類:軟件開發 瀏覽: 評論:15