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

VC++ 分割視圖通用創建框架設計詳解

     編輯:關於VC++

背景與意義

分割視圖技術可在單一框架視窗同時呈現多個視圖,顯著提升資訊密度與操作友好度,是 MFC 應用開發常見需求。本文提出一套可擴充、可複用的分割視圖創建框架,解決標準 CSplitterWnd 客製化受限的問題。

框架架構設計

1. 核心類別繼承體系

為賦予分割視窗自定義行為(如禁止拖曳調整大小),必須從 CSplitterWnd 衍生專屬類別:

class CFixSplitterWnd : public CSplitterWnd {
    // 重寫滑鼠移動處理,禁止分割條拖曳
    void OnMouseMove(UINT nFlags, CPoint point) {
        CWnd::OnMouseMove(nFlags, point); // 防止出現拖曳游標
        // CSplitterWnd::OnMouseMove(nFlags, point); // 原版會顯示拖曳狀態
    }
};

2. 主框架雙層分割實現

在 CMainFrame 中宣告兩個分割器成員,於 OnCreateClient 建立巢狀分割結構:

// 成員變數
CFixSplitterWnd m_wndSplitterH; // 水平分割(上下)
CFixSplitterWnd m_wndSplitterV; // 垂直分割(左右)
BOOL m_bCreateSplitter;

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {
    // 第一層:主框架左右分割(1行2列)
    BOOL bResult = m_wndSplitterV.CreateStatic(this, 1, 2);
    ASSERT(bResult);
    
    // 第二層:右側窗格再上下分割(4行1列)
    m_wndSplitterH.CreateStatic(&m_wndSplitterV, 4, 1, 
        WS_CHILD | WS_VISIBLE, m_wndSplitterV.IdFromRowCol(0, 1));
    
    // 建立各視圖
    m_wndSplitterV.CreateView(0, 0, RUNTIME_CLASS(CSceneView), CSize(600, 600), pContext);
    m_wndSplitterH.CreateView(0, 0, RUNTIME_CLASS(CPitchView), CSize(100, 100), pContext);
    m_wndSplitterH.CreateView(1, 0, RUNTIME_CLASS(CYawView), CSize(100, 100), pContext);
    m_wndSplitterH.CreateView(2, 0, RUNTIME_CLASS(CRollView), CSize(100, 100), pContext);
    m_wndSplitterH.CreateView(3, 0, RUNTIME_CLASS(CControlView), CSize(100, 100), pContext);
    
    // 設定初始行高比例
    m_wndSplitterV.SetRowInfo(0, IDEAL_RAWHEIGHT, 0);
    m_bCreateSplitter = TRUE;
    
    // 啟用主場景視圖接收命令訊息
    m_wndSplitterV.SetActivePane(0, 0, NULL);
    return bResult;
}

3. 動態調整佈局

覆寫 OnSize 回應視窗縮放,按比例分配寬高:

void CMainFrame::OnSize(UINT nType, int cx, int cy) {
    CMDIFrameWnd::OnSize(nType, cx, cy);
    CRect rect; GetClientRect(rect);
    if (m_bCreateSplitter) {
        // 左側佔 3/4,右側佔 1/4
        m_wndSplitterV.SetColumnInfo(0, rect.Width() * 3 / 4, 10);
        m_wndSplitterV.SetColumnInfo(1, rect.Width() / 4, 10);
        // 右側四行平均分配,最後一行佔 1/2
        m_wndSplitterH.SetRowInfo(0, rect.Height() / 6, 10);
        m_wndSplitterH.SetRowInfo(1, rect.Height() / 6, 10);
        m_wndSplitterH.SetRowInfo(2, rect.Height() / 6, 10);
        m_wndSplitterH.SetRowInfo(3, rect.Height() / 2, 10);
    }
    m_wndSplitterV.RecalcLayout();
    m_wndSplitterH.RecalcLayout();
}

訊息路由與焦點管理

分割視圖下的命令路由遵循:View → Document → Frame → App。多視圖切換會改變焦點,影響選單命令啟用狀態。例如「開始」命令僅在 CSceneView 擁有焦點時啟用,實作方式:

void CMainFrame::OnUpdateStartCmd(CCmdUI* pCmdUI) {
    CWnd* pActive = m_wndSplitterV.GetActivePane(0, 0);
    pCmdUI->Enable(pActive && pActive->IsKindOf(RUNTIME_CLASS(CSceneView)));
}

總結

本框架通過 CFixSplitterWnd 封裝固定分割邏輯,結合巢狀 CreateStatic/CreateView 實現複雜佈局,並示範動態佈局與命令路由控制。開發者可據此快速構建專業級多視圖應用,並輕鬆擴展自定義分割行為(如鎖定比例、最小尺寸限制等)。

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