MFC 靜態分割視圖(CSplitterWnd)必須在 CMainFrame::OnCreateClient 中創建,而非 OnCreate 或其他位置。pContext 未知通常是因在錯誤位置調用 CreateStatic/CreateView 導致文檔模板上下文未就緒。
class CMainFrame : public CMDIFrameWnd
{
// ...
protected:
CSplitterWnd m_wndSplitter; // 成員變量,非指針
// ...
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
};
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// 1. 創建靜態分割:1行2列
if (!m_wndSplitter.CreateStatic(this, 1, 2))
return FALSE;
// 2. 創建左視圖 (第0行第0列)
if (!m_wndSplitter.CreateView(0, 0,
RUNTIME_CLASS(CLeftView),
CSize(200, 0), pContext))
return FALSE;
// 3. 創建右視圖 (第0行第1列)
if (!m_wndSplitter.CreateView(0, 1,
RUNTIME_CLASS(CRightView),
CSize(0, 0), pContext))
return FALSE;
// 4. 設置活動視圖(可選)
SetActiveView((CView*)m_wndSplitter.GetPane(0, 1));
return TRUE;
}
| 參數/步驟 | 說明 |
|---|---|
OnCreateClient | 框架窗口創建客戶區的標準覆寫點,此時 pContext 有效 |
CreateStatic(this, rows, cols) | 創建靜態分割器,父窗口為 this (CMainFrame) |
CreateView(row, col, RUNTIME_CLASS, size, pContext) | 創建視圖,**必須傳遞 pContext** 以關聯文檔模板 |
CSize(200, 0) | 初始尺寸:寬 200 像素,高 0 表示填滿 |
RUNTIME_CLASS(CLeftView) | 動態創建視圖類,需聲明 DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE |
// 錯誤
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
m_wndSplitter.CreateStatic(this, 1, 2); // pContext 此時無效!
// ...
}
修正: 移至 OnCreateClient。
// 錯誤
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(200,0), NULL);
// 正確
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(200,0), pContext);
缺少 pContext 導致視圖無法關聯文檔,GetDocument() 返回 NULL。
// LeftView.h
class CLeftView : public CView
{
DECLARE_DYNCREATE(CLeftView) // 必須
// ...
};
// LeftView.cpp
IMPLEMENT_DYNCREATE(CLeftView, CView) // 必須
若需運行時動態分割/合併,使用 CSplitterWnd 但調用 CreateView 時不指定靜態行列,或使用 CWnd::SplitWindow。靜態分割適合固定佈局(如資源管理器雙欄)。
OnCreateClient 斷點確認 pContext 非 NULLCreateView 返回值,失敗時輸出 TRACE 信息m_wndSplitter.GetPane(row, col) 應返回有效 CView*MFC 靜態分割視圖:**唯一正確位置是 CMainFrame::OnCreateClient**,必須傳遞 pContext 給 CreateView,視圖類需支持動態創建。遵循此模式即可避免 pContext 未知、視圖無文檔等經典問題。