使用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;
}
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnauATNlJWYyQmZ5QGM4IDMhR2YiNmZmZzMlVDZyITYwEWMfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.jpg)
在使用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消息來對切換了标簽時進行一些動作。