关于Tab contro的使用 我按照网上的方法,制作多属性页(具体的在1楼),但是当我把Tab contol的标签垂直放的时候,显示不正常。不知道为什么我想要做的是把tab control垂直放,并且每个tab项需要能下都可以加载背景,每个属性页也没有凸出的框框不知道怎么实现,哪位知道帮帮我谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 vc中的tab control控件可以实现分页显示在很多程序里面有很多用处,但编程却需要用一定的方法,网上已经有这种控件使用方法的总结链接如:http://www.vckbase.com/document/viewdoc/?id=398,最后一种方法是最优的,我们就介绍最后一种再在上面改进达到自己想要的效果,因为图显示不了就不插图了。 就是上面的属性页可以随着按键而变化。先介绍这种方法: 要使用Tab Control,并且从CTabCtrl控件类继承自己的类(CTabSheet)来处理。(此方法来自CodeGuru的一篇文章,本人稍做修改使其使用更简便) 首先我先介绍一下如何使用CTabSheet。 先要制作子对话框类,这次的子对话框类不要从CPropertyPage继承,而是直接从CDialog继承。并且各个子对话框资源的属性应设置为:Style为Child, Border为None。 在主对话框资源中,加入一个Tab Control,并且适当调整位置和大小。利用ClassWizard来为这个Tab Control创建一个CTabSheet的控件变量,只有在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); } } 当然还要在构造函数里加入初始化语句: m_nNumOfPages = 0;m_nCurrentPage = 0;否则会出错的。 这样利用CTabSheet这个类就可以轻松地在对话框上放置自己的属性页了,并且控件都分散在各子对话框类中,符合对象封装的思想。而且用这个方法来制作属性页就可以利用ClassWizard来轻松地生成消息映射处理Tab Control的消息了。例如:可以处理TCN_SELCHANGE消息来对切换了标签时进行一些动作。 关于MSComm控件中接收缓冲区数据的BYTE数组的一点疑惑 32bit的windows进程,到底支持2G内存空间还是4G,可以设置么? VC程序左上角的图标能做成长方形的么? VC2005自定义消息问题 数据库备份问题! 求教!!怎样对ListCtrl控件进行颜色设置??? 有关于C++标准库list的排序的问题? 用CFileDialog打开多个文件的错误 怎样将内存DC(以及其中GDIOBJECT对象)归档呢?(真是菜鸟问题...) 我的COM为什么在VB中“ActiveX无法创建对象“。Com可真难学啊。 进制转换 FD_WRITE并不能表明连接建立成功
就这样就可以在对话框上制作出一个完美的属性页了。下面我就来讲讲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); } }
当然还要在构造函数里加入初始化语句: m_nNumOfPages = 0;m_nCurrentPage = 0;否则会出错的。 这样利用CTabSheet这个类就可以轻松地在对话框上放置自己的属性页了,并且控件都分散在各子对话框类中,符合对象封装的思想。而且用这个方法来制作属性页就可以利用ClassWizard来轻松地生成消息映射处理Tab Control的消息了。例如:可以处理TCN_SELCHANGE消息来对切换了标签时进行一些动作。