MFC中使用Tab Control从CTabCtrl控件类继承自己的类(CTabSheet)来处理。

使用Tab Control,并且从CTabCtrl控件类继承自己的类(CTabSheet)来处理。
  首先我先介绍一下如何使用CTabSheet。
  先要制作子对话框类,这次的子对话框类不要从CPropertyPage继承,而是直接从CDialog继承。并且各个子对话框资源的属性应设置为:Style为Child, Border为None。
  在主对话框资源中,加入一个Tab Control,并且适当调整位置和大小。利用ClassWizard来为这个Tab Control创建一个CTabSheet的控件变量。

步骤/方法

  1.   在主对话框的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;
      }

  2.   在使用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();
      }

  3.   生成好标签和子对话框后,调用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消息来对切换了标签时进行一些动作。

时间: 2024-10-22 13:51:35

MFC中使用Tab Control从CTabCtrl控件类继承自己的类(CTabSheet)来处理。的相关文章

MFC中使用skin++后出现的控件失效问题

问题描述 MFC中使用skin++后出现的控件失效问题 我用了skin++后,发现slider控件不能用,就用了skin ++自带的skinppSetNoSkinHwnd()函数,使控件不用皮肤,但是这样会导致debug版本的最后出现断言错误. 我在SkinPPWTL.h这个文件中也发现,作者是有考虑这个情况的,他是这么写的: **//是对SetNoSkinHwnd的进一步处理,可以解决使用SetNoSkinHwnd引起的Debug版的断言错 #define SETNOSKINHWND(x) {

.net firamework 框架里面的控件的继承关系。

       记得当初学习VB6.0的时候,入门的书,一上来就是控件的介绍,控件的属性.事件的使用,拖拽一个文本框.一个按钮,然后再双击按钮,在按钮的事件里面给文本框的Text 设置一个"hello word",第一步就OK了.这就是传说中的 Hello Word.        但是在学习Delphi的时候,书里面写的是控件的继承关系,按钮控件是继承的那个类,文本框又是继承的那个类,这些类又是继承的哪些类.会弄出来一个"树"出来.不知道.net方面的书有没有这样的

在VC++中使用Tab Control控件

系统环境:Windows 7软件环境:Visual Studio 2008 SP1本次目的:在模态或非模态对话框中使用Tab Control控件,及引申在单/多文档中使用   查阅MSDN文档,对于创建Tab Control控件,MSDN上说明如下: To use CTabCtrl directly in a dialog box 1.     In the dialog editor, add a Tab Control to your dialog template resource. Sp

MFC 动修改里面所有项目中所有的对话框上的控件tab顺序

问题描述 MFC 动修改里面所有项目中所有的对话框上的控件tab顺序 现在要求写一个程序,可以选择指定的SLN文件,自动修改里面所有项目中所有的对话框上的控件tab顺序.具体要求为把所有控件按左上角的点字典序排序.

控件-在MFC中使用List Control做表格

问题描述 在MFC中使用List Control做表格 在基于对话框的MFC中添加了一个List Control控件,属性设置为report,显示栅格GridLines,用它来做一个4行10列的表格,现在是显示的10列,但行数是自动显示了很多行,要怎样设置才能让它只显示4行呢? 解决方案 MFC如何使用 List ControlMFC list control 的使用MFC List Control滚动条 解决方案二: 默认的网格就是这么绘制的.你要没有数据的地方不绘制网格,可以换别的控件,或者

MFC在登陆页面中 加一个显示验证码的控件应该加哪个?图片从一个网页中加载出来的

问题描述 MFC在登陆页面中 加一个显示验证码的控件应该加哪个?图片从一个网页中加载出来的 http://202.200.144.63/(gac14yvwcsjrzj45cx1fq4ed)/CheckCode.aspx 我想把这网页里的图片显示在登陆界面作为验证码,请问我该在对话框中加什么控件,我用的是下边的方法 CHtmlView* pView= (CHtmlView*)m_wndSplit.GetPane(0,1); pView->Navigate("http://hao.201201

mfc对话框-在MFC对话框中添加自己编写的OCX控件时出错

问题描述 在MFC对话框中添加自己编写的OCX控件时出错 在MFC工具箱中添加自己编写的OCX然后把控件拖拽到对话框中添加,弹出错误信息提示: Debug Assertion Failed!Program:...les(x86)Microsoft Visual Studio10.0Common7IDEdevenv/.exeFile:fddvctoolsvc7libsshipatlmfcsrcmfcwinocc.cppLine:307 然后点忽略,后运行时可以出现OCX但是这个错误是怎么回事呢 解

分享一段“在.net的多线程中更新任意为Control类型的控件”解决窗体假死问题,调用极其简洁和方便~~~

问题描述 众所周知,在.net的多线程中更新界面时很容易假死,如果界面上有100个控件,那代码量又是相当的复杂,现提供一段简单的代码,可以用于线程代码的任意位置,而界面又不会假死.总之是一行代码,解决了一个复杂而又麻烦的大问题,让你完全不用考虑多线程下对控件的处理,直接调用就好了.1.适用范围:任意Control类型的控件.2.调用this.Label1.InvokeEx(e=>e.Text=DateTime.Now); 3.代码publicstaticvoidInvokeEx<T>(t

MFC父窗口控制子窗口CListCtrl控件刷新的问题

问题描述 MFC父窗口控制子窗口CListCtrl控件刷新的问题 目标:父窗口单击按钮,向子窗口发送一个消息:子窗口的消息处理函数中,调用列表显示函数来刷新列表数据. 我的代码: // 父窗口void CDlg4::OnButtonClick(){ CDlg43 *dlg = new CDlg43(); dlg->Create(IDD_DIALOG_43this); if (NULL == dlg) { AfxMessageBox(""failed""); d