弄了一个上午,终于对Tab Control这个控件有了一点了解。对于初学者来说,在想用Tab Contro这个控件的时候,一般都会去网上找资料。但是在找到相关资料的时候,都会出现一个CTabSheet的类。我原来以为是MFC的类,但是实际上不是的。CTabSheet类是需要自己写的。
写这个的目的也是为了自己以后好找。
具体操作:
第一步:新建一个自己的类CTabSheet继承CTabCtrl.
第二步:定义有用的成员变量
在头文件中定义
#define MAXPAGE 16
class CTabSheet : public CTabCtrl
{
// Construction
public:
CTabSheet();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTabSheet)
//}}AFX_VIRTUAL
// Implementation
public:
int GetCurSel();
int SetCurSel(int nItem);
void Show();
void SetRect();
BOOL AddPage(LPCTSTR title, CDialog *pDialog, UINT ID);
virtual ~CTabSheet();
// Generated message map functions
protected:
int m_nCurrentPage;
int m_nNumOfPages;
CDialog* m_pPages[MAXPAGE];
UINT m_IDD[MAXPAGE];
LPCTSTR m_Title[MAXPAGE];
//{{AFX_MSG(CTabSheet)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
第三步:添加成员函数
1、添加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方法来真正生成标签和子对话框。
2、添加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);
HighlightItem(m_nCurrentPage,TRUE);//高亮1.6
for( i=1; i < m_nNumOfPages; i++)
m_pPages[i]->ShowWindow(SW_HIDE);
// m_pPages[3]->ShowWindow(SW_SHOW);
// m_nCurrentPage=3;
SetRect();
}
生成好标签和子对话框后,调用CTabSheet::SetRect来计算并调整属性页的大小。
3、添加SetRect方法
void CTabSheet::SetRect()
{
CRect tabRect, itemRect;
int nX, nY, nXc, nYc;
//得到Tab Control的大小
GetClientRect(&tabRect);
GetItemRect(0, &itemRect);
//计算出各子对话框的相对于Tab Control的位置和大小
nX=itemRect.left-5;
nY=itemRect.bottom+1;
nXc=tabRect.right-itemRect.left+10;//modify 1.2
nYc=tabRect.bottom-nY;//modify 1.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消息。
4、添加OnLButtonDown方法
void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CTabCtrl::OnLButtonDown(nFlags, point);
//判断是否单击了其他标签
if(m_nCurrentPage != GetCurFocus())
{
//将原先的子对话框隐藏
m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
HighlightItem(m_nCurrentPage,FALSE);
m_nCurrentPage=GetCurFocus();
//显示当前标签对应的子对话框
m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
HighlightItem(m_nCurrentPage,TRUE);
}
}
这样利用CTabSheet这个类就可以轻松地在对话框上放置自己的属性页了,并且控件都分散在各子对话框类中,符合对象封装的思想。而且用这个方法来制作属性页就可以利用ClassWizard来轻松地生成消息映射处理Tab Control的消息了
第四步 添加对话框类,并为其定义变量
比如:CDlgKey m_DlgKey
第五步 在对话框资源中加入CTabCtl控件并为其关联CTabSheet变量
CTabSheet m_TerminalData;
DDX_Control(pDX, IDC_TAB_PBOC, m_TerminalData);
第六步 在对话框.cpp初始化(::OnInitDialog())中加入
m_TerminalData.AddPage("Key",&m_DlgKey,IDD_DIALOG_KEY);
m_TerminalData.Show();