MFC 文檔/視圖架構提供七種視圖基類,針對不同應用場景封裝專用功能。本文系統對比所有視圖類核心能力、適用場景、關鍵接口及選型決策樹,助力架構設計快速決策。
CObject
└── CCmdTarget
└── CWnd
└── CView (基類)
├── CScrollView // 滾動支持
├── CFormView // 對話框式佈局
├── CTreeView // 樹形控件封裝
├── CListView // 列表控件封裝
├── CEditView // 編輯控件封裝
└── CRichEditView // 富文本編輯封裝
| 視圖類 | 核心封裝 | 關鍵獲取接口 | 適用場景 | 特殊能力 |
|---|---|---|---|---|
CView | 無 (純虛繪製) | - | 自定義繪圖、遊戲畫面、圖表渲染 | 完全控制 OnDraw,打印/預覽自動遞送 DC |
CScrollView | 滾動邏輯 | - | 大畫布、文檔瀏覽、地圖編輯器 | SetScrollSizes() 設置邏輯尺寸/映射模式/頁面行大小 |
CFormView | 對話框模板 | - | 數據錄入表單、屬性頁、配置向導 | DDX/DDV 數據交換,UpdateData() 雙向綁定 |
CTreeView | CTreeCtrl | GetTreeCtrl() | 文件系統、組織架構、導航面板 | 自動創建樹控件填充客戶區 |
CListView | CListCtrl | GetListCtrl() | 數據表格、文件列表、郵件清單 | 報表模式多列、圖標列表切換 |
CEditView | CEdit | GetEditCtrl() | 純文本編輯器、日誌查看器、代碼編輯 | 完整編輯功能,SetPrinterFont() 打印字體 |
CRichEditView | CRichEditCtrl | GetRichEditCtrl() | Word 風格編輯器、RTF 文檔、郵件撰寫 | 字體/顏色/段落/圖片/表格/UNDO/打印排版 |
void SetScrollSizes(int nMapMode, SIZE sizeTotal,
const SIZE& sizePage = sizeDefault,
const SIZE& sizeLine = sizeDefault);
nMapMode:映射模式 (MM_TEXT/MM_HIMETRIC/MM_ANISOTROPIC 等)sizeTotal:文檔總邏輯尺寸 (決定滾動範圍)sizePage:頁面滾動增量 (通常 = 視口尺寸 * 0.9)sizeLine:行滾動增量 (通常 = 字體高度或固定值)// DoDataExchange 中綁定
DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
DDX_Check(pDX, IDC_CHECK_ACTIVE, m_bActive);
DDX_Control(pDX, IDC_COMBO_TYPE, m_comboType);
// 雙向同步
UpdateData(TRUE); // UI → 變量 (保存/驗證前)
UpdateData(FALSE); // 變量 → UI (初始化/刷新後)
// CTreeView
CTreeCtrl& tree = GetTreeCtrl();
tree.InsertItem(_T("Root"));
// CListView
CListCtrl& list = GetListCtrl();
list.InsertColumn(0, _T("Name"), LVCFMT_LEFT, 200);
// CEditView
CEdit& edit = GetEditCtrl();
edit.SetWindowText(_T("Content"));
// CRichEditView
CRichEditCtrl& rich = GetRichEditCtrl();
rich.SetSelectionCharFormat(cf);
需要何種核心交互?
├── 純自定義繪圖 (圖表/遊戲/圖形編輯) → CView
├── 大畫布需滾動 (地圖/長文檔/時間軸) → CScrollView
├── 表單式數據錄入 (對話框風格/綁定變量) → CFormView
├── 層級樹狀導航 (目錄/組織/分類) → CTreeView
├── 表格/列表數據展示 (多列/圖標/選擇) → CListView
├── 純文本編輯 (代碼/日誌/筆記) → CEditView
└── 富文本編輯 (字體/圖片/表格/排版/打印) → CRichEditView
// CSplitterWnd 在 CFrameWnd 中創建
m_wndSplitter.CreateStatic(this, 1, 2); // 1行2列
m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CTreeView), size, pContext); // 左側導航樹
m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CListView), size, pContext); // 右側列表
// 文檔模板註冊多視圖
CSingleDocTemplate* pTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CMyView)); // 主視圖
// 運行時動態創建第二視圖
CView* pView2 = pTemplate->CreateNewView(pDoc);
// 在框架中切換視圖
CView* pOld = GetActiveView();
CView* pNew = (CView*)RUNTIME_CLASS(CAnotherView)->CreateObject();
pNew->Create(NULL, NULL, WS_CHILD|WS_VISIBLE, rect, this, AFX_IDW_PANE_FIRST, pContext);
SetActiveView(pNew);
pOld->DestroyWindow();
核心優勢:所有視圖類統一通過 OnDraw(CDC* pDC) 繪製:
pDC = 顯示 DCpDC = CPreviewDC (模擬打印機分辨率)pDC = 打印機 DC一次編寫 OnDraw,三端同步輸出 (WYSIWYG)。
OnPrepareDC 或 DPtoLPOnDestroy 中釋放資源CScrollView 設置映射模式後,OnDraw 內繪圖代碼必須使用邏輯座標本文整理自 MFC 經典技術文檔,適用於 VC6~VS2022 所有版本。