MFC之拆分窗口


7.3.1 多視圖
許多文檔只要求單個視圖,但每個文檔可支持一個以上的視圖。為了幫助編程人員實現多個視圖,文檔對象保留它的視圖列表、為添加和移去視圖提供成員函數,例如,提供的UpdateAllViews成員函數可使多個視圖知道文檔數據何時已被更改。
MFC支持在同一文檔上使用多個視圖的3種通用模式,這些模式是:
(1) 在各自MDI文檔窗口中包含同一個視圖類的多個視圖對象。用戶有時需要應用程序能為同一個文檔打開另一個文檔窗口,以便能同時使用兩個文檔窗口來查看文檔的不同部分內容。用MFC AppWizard創建的多文檔應用程序支持這種模式,當用戶選擇“窗口”菜單的“新建窗口”命令時,系統就會為第一個文檔窗口創建一個副本。
(2) 在同一個文檔窗口中包含同一個視圖類的多個視圖對象。這種模式實際上是使用“切分窗口”機制使SDI應用程序具有多視的特征。
(3) 在單獨一個文檔窗口中包含不同視圖類的多個視圖對象。在該模式下,多個視圖共享同一個文檔窗口。它有點象“切分窗口”,但由於視圖可由不同的視圖類構造,所以同一個文檔可以有不同的顯示方法。例如,同一個文檔可同時有文字顯示方式及圖形顯示方式的視圖。
7.3.2 窗口的切分
1、 靜態切分和動態切分
對於“靜態切分”窗口來說,當窗口第一次被創建時,窗格就已經被切分好了,窗格的次序和數目不能再被改變,但用戶可以移動切分條來調整窗格的大小。每個窗格通常是不同的視圖類。
對於“動態切分”窗口來說,它允許用戶在任何時候對窗口進行切分,用戶既可以通過選擇菜單項來對窗口進行切分,也可以通過拖動滾動條中的切分塊對窗口進行切分。動態切分窗口中的窗格通常使用的是同一個視圖類。當切分窗口被創建時,左上窗格通常被初始化成一個特殊的視圖。當視圖沿着某個方向被切分時,另一個新添加的視圖對象被動態創建;當視圖沿着兩個方向被切分時,新添加的三個視圖對象則被動態創建。當用戶取消切分時,所有新添加的視圖對象被刪除,但最先的視圖仍被保留,直到切分窗口本身消失為止。
無論是靜態切分還是動態切分,在創建時都要指定切分窗口中行和列的窗格最大數目。對於靜態切分,窗格在初始時就按用戶指定的最大數目划分好了;而對於動態切分窗口,當窗口構造時,第一個窗格就被自動創建。動態切分窗口允許的最大窗格數目是2 x 2,而靜態切分允許的最大窗格數目為16 x 16。
2、 切分窗口的CSplitterWnd類操作
在MFC中,CSplitterWnd類封裝了窗口切分過程中所需的功能函數,其中成員函數Create和CreateStatic分別用來創建“動態切分”和“靜態切分”的文檔窗口,函數原型如下:
BOOL Create( CWnd* pParentWnd, int nMaxRows, int nMaxCols, SIZE sizeMin,
CCreateContext*pContext, DWORD dwStyle = WS_CHILD | WS_VISIBLE
|WS_HSCROLL| WS_VSCROLL | SPLS_DYNAMIC_SPLIT,
UINT nID = AFX_IDW_PANE_FIRST );
BOOL CreateStatic( CWnd* pParentWnd, int nRows, int nCols,
DWORD dwStyle = WS_CHILD | WS_VISIBLE,
UINT nID = AFX_IDW_PANE_FIRST );
其中,參數pParentWnd表示切分窗口的父框架窗口。nMaxRows表示窗口動態切分的最大行數(不能超過2)。nMaxCols表示窗口動態切分的最大列數(不能超過2)。nRows表示窗口靜態切分的行數(不能超過16)。nCols表示窗口靜態切分的列數(不能超過16)。sizeMin表示動態切分時允許的窗格最小尺寸。
CSplitterWnd類成員函數CreateView用來為靜態窗格指定一個視圖類,並創建視圖窗口,其函數原型如下:
BOOL CreateView( int row, int col, CRuntimeClass* pViewClass,
SIZE sizeInit, CCreateContext* pContext );
其中,row和col用來指定具體的靜態窗格,pViewClass用來指定與靜態窗格相關聯的視圖類,sizeInit表示視圖窗口初始大小,pContext用來指定一個“創建上下文”指針。“創建上下文”結構CCreateContext包含當前文檔視圖框架結構。
3、 靜態切分窗口實現
利用CSplitterWnd成員函數,用戶可以在文檔應用程序的文檔窗口中添加動態或靜態切分功能。
4、示例程序——將單文檔應用程序中的文檔窗口靜態分成3 x 2個窗格
(1) 用MFC AppWizard創建一個默認的單文檔應用程序Ex_SplitSDI。
(2) 打開框架窗口類MainFrm.h頭文件,為CMainFrame類添加一個保護型的切分窗口的數據成員,如下面的定義:
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CSplitterWnd m_wndSplitter;
(3) 用MFC類向導創建一個新的視圖類CDemoView(基類為CView)用於與靜態切分的窗格相關聯,如圖7-13所示。
(4) 重寫CMainFrame類的OnCreateClient函數(當主框架窗口客戶區創建的時候
自動調用該函數),並添加下列代碼:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,
CCreateContext* pContext) {
CRect rc;
GetClientRect(rc); // 獲取客戶區大小
// 計算每個窗格的平均尺寸
CSize paneSize(rc.Width()/2-16,rc.Height()/3-16);
m_wndSplitter.CreateStatic(this,3,2); // 創建3 x 2個靜態窗格
m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CDemoView),paneSize,
pContext); // 為相應的窗格指定視圖類
m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CDemoView),paneSize,
pContext);
m_wndSplitter.CreateView(1,0,RUNTIME_CLASS(CDemoView),paneSize,
pContext);
m_wndSplitter.CreateView(1,1,RUNTIME_CLASS(CDemoView),
paneSize,pContext);
m_wndSplitter.CreateView(2,0,RUNTIME_CLASS(CDemoView),
paneSize,pContext);
m_wndSplitter.CreateView(2,1,RUNTIME_CLASS(CDemoView),
paneSize,pContext);
return TRUE;
}
(5) 在MainFrm.cpp 源文件的開始處,添加視圖類CDemoView 的包含文件:
#include "DemoView.h"
(6) 編譯並運行,結果如圖7-14 所示。

7.3.3 多視圖編程示例
下面的示例是在一個多文檔應用程序Ex_Rect 中為同一個文檔數據提供兩種不同的顯示和編輯方式,如圖7-15 所示。在左邊的窗格中,用戶可以調整小方塊在右邊窗格的坐標位置。而若在右邊窗格中任意單擊鼠標,相應的小方塊會移動到當前鼠標位置處,且左邊窗格的編輯框內容也隨之發生改變。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM