在 SDI (Single Document Interface) 應用程式中,常需將主視圖區域分割為上下兩個獨立視圖,分別顯示不同內容(如:上方列表、下方詳情)。MFC 提供 CSplitterWnd 支援靜態/動態分割,本文示範靜態建立上下兩行、各一列的分割視窗。
CMainFrame 宣告 CSplitterWnd m_SplitterWnd;。OnCreateClient:此虛函數在文檔/視圖建立前被呼叫,是建立分割視窗的最佳時機。BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// 1. 建立靜態分割視窗:2 行、1 列
if (!m_SplitterWnd.CreateStatic(this, 2, 1))
return FALSE;
// 2. 取得客戶區尺寸,計算上方視圖初始高度
CRect rect; GetClientRect(&rect);
int upperHeight = rect.Height() / 2 - 10; // 留 10 像素給分割條
// 3. 建立上方視圖 (第 0 列、第 0 行)
if (!m_SplitterWnd.CreateView(0, 0, RUNTIME_CLASS(CTestDownView), CSize(0, upperHeight), pContext))
return FALSE;
// 4. 建立下方視圖 (第 1 列、第 0 行),高度 0 表示佔滿剩餘空間
if (!m_SplitterWnd.CreateView(1, 0, RUNTIME_CLASS(CContainerView), CSize(0, 0), pContext))
return FALSE;
return TRUE;
}
| 參數 | 說明 |
|---|---|
CreateStatic(this, 2, 1) | 父視窗、列數、行數。靜態分割建立後不可動態增減面板。 |
CreateView(row, col, RUNTIME_CLASS(...), size, pContext) | 指定面板位置、視圖類別 (需 DECLARE_DYNCREATE)、初始大小、建立上下文。 |
CSize(0, upperHeight) | 寬度 0 表示自動填滿;高度指定初始像素。 |
CSize(0, 0) | 最後一個面板通常傳 (0,0) 佔據所有剩餘空間。 |
DECLARE_DYNCREATE(CMyView),CPP 加 IMPLEMENT_DYNCREATE(CMyView, CView)。OnCreateClient 後呼叫 m_SplitterWnd.SetColumnInfo(0, 0, 0) 隱藏垂直分割條 (單列時)。CreateView 搭配 WS_THICKFRAME 樣式,或直接用 CSplitterWnd::CreateStatic 即可支援拖曳調整比例。CView* pView = (CView*)m_SplitterWnd.GetPane(row, col); 取得指標進行跨視圖通訊。同理可構建「左右分割 + 右側再上下分割」等複雜佈局:外層 CSplitterWnd 2 列,右側面板再嵌入一個子 CSplitterWnd 2 行。注意巢狀分割時父視窗參數傳遞與 pContext 正確透傳。