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

VC++ TabCtrl 控件分組顯示最佳實踐:CTabContainer 類別封裝方案

     編輯:VC 教學

前言:TabCtrl 分組顯示的痛點

使用 CTabCtrl 實現多頁面控件切換時,傳統做法需在 OnSelchange 中手動 ShowWindow 每個控件,程式碼冗長、難維護、易出錯。本文提出CTabContainer 容器類別,以鏈表管理各分頁控件 ID,一行程式碼完成切換。

核心設計思路

  1. 初始化時指定分頁數量 (nTabs)。
  2. 每個分頁對應一個 CList 鏈表,儲存該分頁隸屬的控件 ID。
  3. 提供 AddCtrlId/Delete 管理 ID,Show(nTab) 一鍵切換顯示/隱藏。

CTabContainer 類別完整實作

// TabContainer.h
class CTabContainer
{
public:
    CTabContainer();
    virtual ~CTabContainer();

    BOOL Init(int nTabs, CWnd* pParent);           // 初始化:分頁數、父視窗
    BOOL AddCtrlId(int nTab, int nID);             // 將控件 ID 加入指定分頁
    BOOL Delete(int nTab, int nID);                // 移除控件 ID
    void Show(int nTab);                           // 顯示指定分頁,隱藏其他
    void Clear();                                  // 釋放資源

protected:
    typedef CList CIntList;
    CIntList* m_pIDGroups;   // 鏈表陣列,大小 = nTabs
    int m_nLCount;           // 分頁數
    CWnd* m_pParent;         // 父視窗指標 (用於 GetDlgItem)
};

// TabContainer.cpp
CTabContainer::CTabContainer() : m_pParent(NULL), m_pIDGroups(NULL), m_nLCount(0) {}

CTabContainer::~CTabContainer() { Clear(); }

BOOL CTabContainer::Init(int nTabs, CWnd* pParent)
{
    ASSERT(nTabs > 0 && pParent != NULL);
    Clear();
    m_nLCount = nTabs;
    m_pParent = pParent;
    m_pIDGroups = new CIntList[nTabs];
    return (m_pIDGroups != NULL);
}

BOOL CTabContainer::AddCtrlId(int nTab, int nID)
{
    ASSERT(nTab < m_nLCount);
    m_pIDGroups[nTab].AddTail(nID);
    return TRUE;
}

BOOL CTabContainer::Delete(int nTab, int nID)
{
    ASSERT(nTab < m_nLCount);
    POSITION pos = m_pIDGroups[nTab].Find(nID);
    if (pos) m_pIDGroups[nTab].RemoveAt(pos);
    return TRUE;
}

void CTabContainer::Show(int nTab)
{
    ASSERT(nTab < m_nLCount);
    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 CTabContainer::Clear()
{
    if (m_pIDGroups) {
        delete[] m_pIDGroups;
        m_pIDGroups = NULL;
        m_nLCount = 0;
    }
}

使用範例

// 對話框成員
CTabContainer* m_pTabContainer;
CTabCtrl m_tab;

// OnInitDialog
m_pTabContainer = new CTabContainer;
m_pTabContainer->Init(3, this);  // 3 個分頁

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 頁

// TabCtrl 切換事件
void CMyDialog::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
{
    m_pTabContainer->Show(m_tab.GetCurSel());
    *pResult = 0;
}

// 記得在 OnDestroy 釋放
void CMyDialog::OnDestroy()
{
    delete m_pTabContainer;
    CDialog::OnDestroy();
}

優勢總結

傳統寫法CTabContainer 方案
OnSelchange 中硬編碼每個控件 Show/Hide資料驅動,ID 列表集中管理
新增控件需修改多處 Switch/If僅需一行 AddCtrlId
控件 ID 分散在程式碼各處初始化時集中宣告,一目了然
難以動態增減分頁控件支援運行時 Add/Delete

結語

CTabContainer 將「分頁-控件」對應關係資料化,以最小程式碼解決 TabCtrl 分組顯示的維護難題。專案中可直接複製使用,或依需求擴充(如支援巢狀 Tab、動態建立控件等)。

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