使用 MFC CTabCtrl 實現類似屬性頁的多子對話方塊動態切換,核心技巧:子對話方塊建立為 Child/無邊框,父視窗設為 Tab 控制項,配合 ShowWindow 切換可見性。
IDC_TAB1CTabCtrl m_tabCtrlBOOL CMyTabDlg::OnInitDialog() {
CDialog::OnInitDialog();
m_tabCtrl.InsertItem(0, _T("頁面一"));
m_tabCtrl.InsertItem(1, _T("頁面二"));
// 更多頁面...
return TRUE;
}
IDD_PAGE1、IDD_PAGE2CPage1 : public CDialog、CPage2 : public CDialogclass CMyTabDlg : public CDialog {
CTabCtrl m_tabCtrl;
CPage1 m_page1;
CPage2 m_page2;
// ...
};
BOOL CMyTabDlg::OnInitDialog() {
CDialog::OnInitDialog();
// 1. 建立子對話方塊,父視窗指定為 Tab 控制項
m_page1.Create(IDD_PAGE1, &m_tabCtrl);
m_page2.Create(IDD_PAGE2, &m_tabCtrl);
// 2. 獲取 Tab 客戶區矩形,計算子對話方塊顯示區域
CRect rc;
m_tabCtrl.GetClientRect(&rc);
// 調整留出 Tab 標籤高度 (約 20-25 像素) 與邊距
rc.top += 22;
rc.bottom -= 4;
rc.left += 2;
rc.right -= 2;
// 3. 移動子對話方塊至計算區域
m_page1.MoveWindow(&rc);
m_page2.MoveWindow(&rc);
// 4. 初始顯示第一頁,隱藏其餘
m_page1.ShowWindow(SW_SHOW);
m_page2.ShowWindow(SW_HIDE);
// 5. 設定預設選中項
m_tabCtrl.SetCurSel(0);
return TRUE;
}
void CMyTabDlg::OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) {
int nSel = m_tabCtrl.GetCurSel();
switch (nSel) {
case 0:
m_page1.ShowWindow(SW_SHOW);
m_page2.ShowWindow(SW_HIDE);
break;
case 1:
m_page1.ShowWindow(SW_HIDE);
m_page2.ShowWindow(SW_SHOW);
break;
// 更多頁面...
}
*pResult = 0;
}
類別向導添加訊息映射:ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTab1)
OnTcnSelchange 中首次切換到該頁才 Create,減少啟動開銷std::vector<CDialog*> 管理任意數量頁面,配合 InsertItem 索引對應UpdateData(TRUE) 保存當前頁資料,切換後 UpdateData(FALSE) 載入新頁資料SetItem 結合 TCITEM 設定圖示、字體、顏色| 屬性 | 子對話方塊資源 | Tab Control |
|---|---|---|
| Style | Child (WS_CHILD) | - |
| Border | None | - |
| Visible | False (程式控制) | True |
| 父視窗 | Tab Control (m_tabCtrl) | 主對話方塊 |
此模式輕量、無 CPropertySheet 框架開銷,完全掌控佈局與切換邏輯,是 MFC 多頁面 UI 經典實作。