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

TabCtrl 分頁控件管理神器:CTabContainer 一行代碼控制顯隱

     編輯:VC++

痛點場景

對話框包含多組控件,需配合 CTabCtrl 分頁顯示。傳統做法:在 OnSelchange 中手寫大量 ShowWindow(SW_HIDE/SHOW),代碼冗長、易漏、難維護。

CTabContainer 設計思路

  • 構造時指定分頁數 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 調整分頁內容。
  • 內存安全:析構函數自動釋放鏈表數組。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved