首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ SDI 動態切換多視圖與分割視窗實作分析

     編輯:VC 教學

場景

單文檔介面 (SDI) 需在分割視窗 (CSplitterWnd) 中動態替換視圖類別,支援多種視圖切換。

核心類別與變數

class CMainFrame : public CFrameWnd {
    CSplitterWnd m_wndSplitter; // 成員分割視窗
    // ...
};

帶分割視窗切換視圖 (OnSwitchView1)

void CMainFrame::OnSwitchView1() {
    CRect cr; GetClientRect(&cr);
    CSize paneSize(cr.Width() * 3 / 4, cr.Height()); // 新視圖大小

    CCreateContext context;
    context.m_pNewViewClass = RUNTIME_CLASS(CSwitchView1);
    context.m_pCurrentDoc = ((CMyApp*)AfxGetApp())->m_pDoc; // 共享文檔
    context.m_pCurrentFrame = this;
    context.m_pNewDocTemplate = context.m_pCurrentDoc->GetDocTemplate();
    context.m_pLastView = (CView*)m_wndSplitter.GetPane(0, 0); // 參考現有視圖

    m_wndSplitter.DeleteView(0, 1); // 刪除第 0 行第 1 列舊視圖
    m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CSwitchView1), paneSize, &context); // 建立新視圖

    CView* pNewView = (CView*)m_wndSplitter.GetPane(0, 1);
    pNewView->GetParentFrame()->RecalcLayout();
    m_wndSplitter.RecalcLayout();
    pNewView->OnInitialUpdate();
    m_wndSplitter.SetActivePane(0, 1); // 激活新窗格
}

無分割視窗切換視圖 (SwitchToView)

void CMainFrame::SwitchToView(int nFormID) {
    CView* pOldView = GetActiveView();
    CView* pNewView = (CView*)GetDlgItem(nFormID); // 嘗試取得現有子視窗

    if (!pNewView) { // 不存在則動態建立
        switch (nFormID) {
        case IDD_FORM1: pNewView = new CFormView1; break;
        case IDD_FORM2: pNewView = new CFormView2; break;
        }
        CCreateContext ctx;
        ctx.m_pCurrentDoc = pOldView->GetDocument();
        pNewView->Create(NULL, NULL, WS_CHILD | WS_BORDER, rectDefault, this, nFormID, &ctx);
        pNewView->OnInitialUpdate();
    }

    SetActiveView(pNewView);
    pNewView->ShowWindow(SW_SHOW);
    pOldView->ShowWindow(SW_HIDE);

    // 交換控制項 ID 以便下次 GetDlgItem 找到舊視圖
    if (pOldView->IsKindOf(RUNTIME_CLASS(CFormView1))) pOldView->SetDlgCtrlID(IDD_FORM1);
    else if (pOldView->IsKindOf(RUNTIME_CLASS(CFormView2))) pOldView->SetDlgCtrlID(IDD_FORM2);
    pNewView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);

    delete pOldView; // 釋放舊視圖
    RecalcLayout();
}

關鍵差異對比

特性分割視窗模式無分割模式
核心物件CSplitterWnd 管理窗格框架直接管理視圖
建立/刪除CreateView/DeleteViewCreate/Delete + SetActiveView
文檔共享透過 CCreateContext 傳遞同一文檔指標同樣透過 Context 傳遞
版面更新m_wndSplitter.RecalcLayout()RecalcLayout()

簡化版分割切換 (僅替換類別、大小固定)

void CMainFrame::OnSwitchViewSimple() {
    m_wndSplitter.DeleteView(1, 0); // 刪除指定窗格
    m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CNewView), CSize(0,0), NULL);
    m_wndSplitter.RecalcLayout();
}

適用於視圖大小由分割條自動管理、無特殊初始化需求的情況。

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