使用Tab Control,並且從CTabCtrl控制項類繼承自己的類(CTabSheet)來處理。
首先我先介紹一下如何使用CTabSheet。
先要製作子對話方塊類,這次的子對話方塊類不要從CPropertyPage繼承,而是直接從CDialog繼承。並且各個子對話方塊資源的屬性應設定為:Style為Child, Border為None。
在主對話方塊資源中,加入一個Tab Control,並且適當調整位置和大小。利用ClassWizard來為這個Tab Control建立一個CTabSheet的控制項變數。
步驟/方法
- 在主對話方塊的OnInitDialog()加入:
m_sheet.AddPage("tab1", &m_page1, IDD_DIALOG1);
m_sheet.AddPage("tab2", &m_page2, IDD_DIALOG2);
m_sheet.Show();
就這樣就可以在對話方塊上製作出一個完美的屬性頁面了。效果和完全一樣。
下面我就來講講CTabSheet類的細節內容。
CTabSheet是從CTabCtrl繼承來的,用於Tab Control的控制項類。在類中有一個成員變數用來記錄各子對話方塊的指標CDialog* m_pPages[MAXPAGE]; MAXPAGE是該類所能載入的標籤的最大值。
類中有一個AddPage方法,用於記錄子對話方塊的指標和所使用對話方塊資源的ID號。
BOOL CTabSheet::AddPage(LPCTSTR title, CDialog *pDialog,UINT ID)
{
if( MAXPAGE == m_nNumOfPages )
return FALSE;
//儲存目前總的子對話方塊數
m_nNumOfPages++;
//記錄子對話方塊的指標、資源ID、要在標籤上顯示的文字
m_pPages[m_nNumOfPages-1] = pDialog;
m_IDD[m_nNumOfPages-1] = ID;
m_Title[m_nNumOfPages-1] = title;
return TRUE;
}
- 在使用AddPage加入了若干子對話方塊後,必須調用CTabSheet的Show方法來真正產生標籤和子對話方塊。
void CTabSheet::Show()
{
//利用CDialog::Create來建立子對話方塊,並且使用CTabCtrl::InsertItem來加上相應的標籤
for( int i=0; i < m_nNumOfPages; i++ )
{
m_pPages[i]->Create( m_IDD[i], this );
InsertItem( i, m_Title[i] );
}
//由於對話方塊顯示時預設的是第一個標籤被選中,所以應該讓第一個子對話方塊顯示,其他子對話方塊隱藏
m_pPages[0]->ShowWindow(SW_SHOW);
for( i=1; i < m_nNumOfPages; i++)
m_pPages[i]->ShowWindow(SW_HIDE);
SetRect();
}
- 產生好標籤和子對話方塊後,調用CTabSheet::SetRect來計算並調整屬性頁面的大小。
void CTabSheet::SetRect()
{
CRect tabRect, itemRect;
int nX, nY, nXc, nYc;
//得到Tab Control的大小
GetClientRect(&tabRect);
GetItemRect(0, &itemRect);
//計算出各子對話方塊的相對於Tab Control的位置和大小
nX=itemRect.left;
nY=itemRect.bottom+1;
nXc=tabRect.right-itemRect.left-2;
nYc=tabRect.bottom-nY-2;
//利用計算出的資料對各子對話方塊進行調整
m_pPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
for( int nCount=1; nCount < m_nNumOfPages; nCount++ )
m_pPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);
}
在單擊標籤欄後,應該是相應的子對話方塊顯示,正在顯示的子對話方塊應該隱藏。因此利用ClassWizard來處理WM_LBUTTONDOWN訊息。
void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point)
{
CTabCtrl::OnLButtonDown(nFlags, point);
//判斷是否單擊了其他標籤
if(m_nCurrentPage != GetCurFocus())
{
//將原先的子對話方塊隱藏
m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
m_nCurrentPage=GetCurFocus();
//顯示當前標籤所對應的子對話方塊
m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
}
}
這樣利用CTabSheet這個類就可以輕鬆地在對話方塊上放置自己的屬性頁面了,並且控制項都分散在各子對話方塊類中,符合對象封裝的思想。而且用這個方法來製作屬性頁面就可以利用ClassWizard來輕鬆地產生訊息映射處理Tab Control的訊息了。例如:可以處理TCN_SELCHANGE訊息來對切換了標籤時進行一些動作。