本文主要介绍使用CTabCtrl的封装类CTabSheet来操纵TabCtrl控件,内容来自VC++驿站的SYC老师,如果你想添加自己想要的功能,可以进行封装的不断完善。
下面先贴出封装类的 TabSheet.h文件和TabSheet.cpp文件,如下:
下面是TabSheet.h文件:
#pragma once
// CTabSheet
#define MAX_PAGES 10
class CTabSheet : public CTabCtrl
{
DECLARE_DYNAMIC(CTabSheet)
public:
CTabSheet();
virtual ~CTabSheet();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult);
BOOL AddPage(CString szTitle, CDialog * pDialog, UINT ID,int nImg=-1);
void Show(UINT nIdx = 0);
void SetRect(UINT nIdx);
public:
UINT m_nNumOfPages;
CDialog *m_pPages[MAX_PAGES];
UINT m_IDD[MAX_PAGES];
CString m_Title[MAX_PAGES];
int m_Img[MAX_PAGES];
UINT m_nCurrentPage;
};
下面是TabSheet.cpp文件:
#include "stdafx.h"
#include "TabSheet.h"
// CTabSheet
IMPLEMENT_DYNAMIC(CTabSheet, CTabCtrl)
CTabSheet::CTabSheet()
{
m_nNumOfPages = 0;
m_nCurrentPage = 0;
}
CTabSheet::~CTabSheet()
{
}
BEGIN_MESSAGE_MAP(CTabSheet, CTabCtrl)
ON_NOTIFY_REFLECT(TCN_SELCHANGE, &CTabSheet::OnTcnSelchange)
END_MESSAGE_MAP()
// CTabSheet message handlers
BOOL CTabSheet::AddPage(CString szTitle, CDialog * pDialog, UINT ID,int nImg)
{
if (MAX_PAGES == m_nNumOfPages){
return FALSE;
}
m_nNumOfPages++;
m_pPages[m_nNumOfPages-1] = pDialog;
m_IDD[m_nNumOfPages-1] = ID;
m_Title[m_nNumOfPages-1] = szTitle;
m_Img[m_nNumOfPages-1] = nImg;
return TRUE;
}
void CTabSheet::Show(UINT nIdx)
{
ASSERT(nIdx < m_nNumOfPages);
UINT idx = 0;
for (idx = 0; idx < m_nNumOfPages; idx++){
m_pPages[idx]->Create(m_IDD[idx], this);
if (m_Img[idx]==-1)
{
InsertItem(idx, m_Title[idx]);
}
else
{
InsertItem(idx, m_Title[idx],m_Img[idx]);
}
}
SetRect(nIdx);
SetCurFocus(nIdx);
}
void CTabSheet::SetRect(UINT nIdx)
{
CRect tabRect, itemRect;
int nX = 0, nY = 0, nXc = 0, nYc = 0;
UINT nCount = 0;
GetClientRect(&tabRect);
GetItemRect(0, &itemRect);
nX = itemRect.left;
nY = itemRect.bottom + 1;
nXc = tabRect.right - itemRect.left - 2;
nYc = tabRect.bottom - nY - 2;
for (nCount = 0; nCount < m_nNumOfPages; nCount++){
if ( nCount == nIdx ) {
m_pPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
}else{
m_pPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);
}
}
}
void CTabSheet::OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult)
{
if (m_nCurrentPage != GetCurFocus()){
m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
m_nCurrentPage = GetCurFocus();
m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
}
*pResult = 0;
}
CTabSheet封装类有了,下面就是介绍如何使用这个封装类:
1、在工程中加入CTabSheet类的两个文件;
2、在工程中加入你想加入Tab页的Dialog对话框资源,属性设置如下:
Border:None
Style:Child
Title Bar:False
资源ID例如为:IDD_DIALOG1,IDD_DIALOG2,IDD_DIALOG3……并添加关联相应的子类, 如:CPage1,CPage2,CPage3...派生于CDialog;
3、在工程的主对话框资源中添加一个 Tab Control 标签, 调整其大小并绑定一个CTabSheet类型的控件变量;
4.在XXXDlg.h文件中的 CXXXDlg类中加入相应的成员变量,如:
public:
CTabSheet m_Sheet;
CPage1 m_page1;
CPage2 m_page2;
CPage3 m_page3;
...
5.在XXXDlg.cpp文件中的OnInitDialog()初始化函数中加入初始化标签页代码:
m_Sheet.AddPage(_T("标签1"), &m_page1, IDD_DIALOG1);
m_Sheet.AddPage(_T("标签2"), &m_page2, IDD_DIALOG2);
m_Sheet.AddPage(_T("标签3"), &m_page3, IDD_DIALOG3);
...
m_Sheet.Show();
AddPage()中的最后一个参数默认值是-1,Tab页中不添加图像,如果你想添加图像,其参数应设定为CImageList对象所包含图标的序号,序号从0开始。
以上只是对标签控件 TabCtrl 的常用操作讲解,如果大家想要更为详细的操作说明或者实现特定的功能请查阅MSDN等相关方面的文档。
举例说明:添加两个带图标的标签页
添加对话框资源、关联类、向工程中添加图标等操作比较简单,这里自己不介绍了。下面直接介绍实现代码:
void CDiskMgrDlg::AddTabCtrl()
{
/***TabCtrl控件和CImageList控件的关联***/
m_ImageTab.Create(16,16,ILC_COLOR24|ILC_MASK,1,0);
m_ImageTab.Add(LoadIcon(AfxGetResourceHandle(),MAKEINTRESOURCE(IDI_FILE_VIEW)));
m_ImageTab.Add(LoadIcon(AfxGetResourceHandle(),MAKEINTRESOURCE(IDI_FILE_TRANS)));
m_Tab.SetImageList(&m_ImageTab);
/***TabCtrl控件的添加***/
m_Tab.AddPage(_T("文件查看"), &m_FielView, IDD_FILE_VIEW,0);
m_Tab.AddPage(_T("文件传输"), &m_FileTrans,IDD_FILE_TRANS,1);
m_Tab.Show();
}
运行结果: