對話框包含多組控件,需配合 CTabCtrl 分頁顯示。傳統做法:在 OnSelchange 中手寫大量 ShowWindow(SW_HIDE/SHOW),代碼冗長、易漏、難維護。
nTabs,內部維護 nTabs 個 CList<int, int>,每個鏈表存儲該分頁下的控件 ID。AddCtrlId(tabIndex, ctrlId) 註冊映射關係。Show(curSel) 根據當前選中分頁,遍歷所有鏈表批量顯示/隱藏。class CTabContainer {
public:
CTabContainer() : m_pIDGroups(NULL), m_nLCount(0), m_pParent(NULL) {}
~CTabContainer() { Clear(); }
BOOL Init(int nTabs, CWnd* pParent) {
ASSERT(nTabs > 0 && pParent);
Clear();
m_nLCount = nTabs;
m_pParent = pParent;
m_pIDGroups = new CList[nTabs];
return m_pIDGroups != NULL;
}
BOOL AddCtrlId(int nTab, int nID) {
if (nTab < 0 || nTab >= m_nLCount) return FALSE;
m_pIDGroups[nTab].AddTail(nID);
return TRUE;
}
BOOL Delete(int nTab, int nID) {
if (nTab < 0 || nTab >= m_nLCount) return FALSE;
POSITION pos = m_pIDGroups[nTab].Find(nID);
if (pos) { m_pIDGroups[nTab].RemoveAt(pos); return TRUE; }
return FALSE;
}
void Show(int nTab) {
if (nTab < 0 || nTab >= m_nLCount) return;
for (int i = 0; i < m_nLCount; i++) {
POSITION pos = m_pIDGroups[i].GetHeadPosition();
while (pos) {
int nID = m_pIDGroups[i].GetNext(pos);
m_pParent->GetDlgItem(nID)->ShowWindow(i == nTab ? SW_SHOW : SW_HIDE);
}
}
}
void Clear() {
if (m_pIDGroups) { delete[] m_pIDGroups; m_pIDGroups = NULL; m_nLCount = 0; }
}
protected:
CList* m_pIDGroups;
int m_nLCount;
CWnd* m_pParent;
};
// 對話框成員
CTabContainer* m_pTabContainer = new CTabContainer;
CTabCtrl m_tab;
BOOL CMyDlg::OnInitDialog() {
CDialog::OnInitDialog();
m_pTabContainer->Init(3, this); // 3 個分頁
// 註冊控件 ID 到對應分頁
m_pTabContainer->AddCtrlId(0, IDC_BUTTON1);
m_pTabContainer->AddCtrlId(0, IDC_BUTTON4);
m_pTabContainer->AddCtrlId(0, IDC_BUTTON5);
m_pTabContainer->AddCtrlId(1, IDC_BUTTON2);
m_pTabContainer->AddCtrlId(1, IDC_BUTTON6);
m_pTabContainer->AddCtrlId(2, IDC_BUTTON3);
m_pTabContainer->AddCtrlId(2, IDC_BUTTON7);
m_pTabContainer->AddCtrlId(2, IDC_BUTTON8);
m_pTabContainer->Show(0); // 默認顯示第 0 頁
return TRUE;
}
void CMyDlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) {
m_pTabContainer->Show(m_tab.GetCurSel()); // 一行搞定切換
*pResult = 0;
}
void CMyDlg::OnDestroy() {
delete m_pTabContainer;
CDialog::OnDestroy();
}
OnInitDialog 註冊,邏輯清晰。Show(),無論多少控件、多少分頁,調用一行。AddCtrlId/Delete 調整分頁內容。