首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

MFC 靜態分割視圖:在 CMainFrame::OnCreateClient 中正確創建分割窗口

     編輯:程式設計綜合問答

MFC 靜態分割視圖(CSplitterWnd)必須在 CMainFrame::OnCreateClient 中創建,而非 OnCreate 或其他位置。pContext 未知通常是因在錯誤位置調用 CreateStatic/CreateView 導致文檔模板上下文未就緒。

正確實現模式

1. MainFrm.h 聲明


class CMainFrame : public CMDIFrameWnd
{
    // ...
protected:
    CSplitterWnd m_wndSplitter; // 成員變量,非指針
    // ...
    virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
};

2. MainFrm.cpp 實現


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

常見錯誤與修正

錯誤 1:在 OnCreate 中創建


// 錯誤
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
    if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
    m_wndSplitter.CreateStatic(this, 1, 2); // pContext 此時無效!
    // ...
}

修正: 移至 OnCreateClient。

錯誤 2:CreateView 未傳 pContext


// 錯誤
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。

錯誤 3:視圖類未聲明動態創建


// LeftView.h
class CLeftView : public CView
{
    DECLARE_DYNCREATE(CLeftView) // 必須
    // ...
};

// LeftView.cpp
IMPLEMENT_DYNCREATE(CLeftView, CView) // 必須

動態分割對比

若需運行時動態分割/合併,使用 CSplitterWnd 但調用 CreateView 時不指定靜態行列,或使用 CWnd::SplitWindow。靜態分割適合固定佈局(如資源管理器雙欄)。

調試技巧

  • 在 OnCreateClient 斷點確認 pContext 非 NULL
  • 檢查 CreateView 返回值,失敗時輸出 TRACE 信息
  • 視圖創建後,m_wndSplitter.GetPane(row, col) 應返回有效 CView*

總結

MFC 靜態分割視圖:**唯一正確位置是 CMainFrame::OnCreateClient**,必須傳遞 pContext 給 CreateView,視圖類需支持動態創建。遵循此模式即可避免 pContext 未知、視圖無文檔等經典問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved