65.9K
CodeProject 正在变化。 阅读更多。
Home

CTabCtrlSSL - 一个易于使用、灵活的扩展标签控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (79投票s)

2001年9月21日

CPOL

10分钟阅读

viewsIcon

1238576

downloadIcon

18024

一个扩展标签控件,允许从对话框资源添加标签页

Sample Image - CTabCtrlSSL.gif

引言

本文已更新,详情请参见“更新”部分。

一点点病痛在家也能激发生产力,这真是太神奇了!我病了好几天,结果又一个扩展控件诞生了。这次我盯上了标签控件。在我看来,现如今人们更喜欢属性表和页面,所以标签控件似乎有点过时了。嗯,我尝试过使用它们,但没有得到我想要的结果。我需要在标签区域上方放置一些控件(有点像演示一样,但要多放几个控件),而使用属性表和页面我做不到。

标准标签控件的问题在于,要将其中的页面插入到控件中需要大量的精力。查阅MSDN时,我找到一个Jeff Prosise的例子,他实现了一个标签视图,CTabView,允许将标签指定为对话框资源。好吧,说到代码,我就像一个十岁的孩子玩手表一样:我必须弄弄清楚它是如何工作的,并思考如何能做得更好。

第一个问题是Jeff的解决方案是针对视图类的,而我需要一个控件。这之间的转换很容易,因为视图只是封装了控件。我遇到的第二个问题是,它在标签页的灵活性方面做得不够。我问自己:“我如何处理页面中的事件?”答案是允许客户端继承标签页类,并允许将标签页对象添加到控件中,而不仅仅是对话框资源。

为什么解决方案总是带来新问题?通过允许这种方法,我引入了一个棘手的释放标签页的场景。内部的标签控件在堆上创建标签页,并维护一个已添加页面的列表。当控件被销毁时,`delete`会依次对每个页面进行调用。如果页面是在标签控件外部创建并传入的,这显然会导致问题。在这种情况下,标签控件会销毁外部创建的页面,然后父对话框会尝试做同样的事情!!

经过在Visual C++论坛上与Tomasz Sowinski的长时间讨论,我们找到了答案。标签控件有一个受保护的函数用于向控件添加页面,而公共函数调用它。实际上传递给受保护函数的是一个包含指向标签页的指针和一个指示标签控件是否应销毁它的标志的结构。这样,如果传入标签页,则标志设置为false,但如果标签控件创建标签页,则标志设置为true。在销毁时,只有标志设置为true的页面才会被标签控件销毁。其他页面就是别人的问题了。

如何使用

  1. 创建一个对话框资源和用于该对话框的类,以便在该对话框上添加标签控件。
  2. 从工具箱中向对话框资源添加一个标签控件。
  3. 为标签控件创建一个成员变量,并将其类型更改为CTabCtrlSSL
  4. 在对话框类的OnInitDialog处理程序中,创建并添加您想在标签控件上显示的任何页面。
BOOL CCTabCtrlSSL_demoDlg::OnInitDialog () {
	CDialog::OnInitDialog ();
   
   // Setup the tab control
   int nPageID = 0;
   m_tabDemo.AddSSLPage (_T("Basic Tab"), nPageID++, IDD_TAB_BASIC);
   m_advancedTab.Create (IDD_TAB_ADVANCED, this);
   m_tabDemo.AddSSLPage (_T("Advanced Page"), nPageID++, &m_advancedTab);
   m_aboutTab.Create (IDD_TAB_ABOUT, this);
   m_tabDemo.AddSSLPage (_T("About"), nPageID++, &m_aboutTab);
   
   return TRUE; // return TRUE unless you set the focus to a control
}

从上面的代码示例(取自演示)可以看出,要添加一个基本的标签,请调用AddSSLPage并仅传入对话框资源的资源ID。对于高级标签,创建对话框资源,设置窗口样式为Child,边框样式为None,然后调用AddSSLPage并传入指向您派生的CTabPageSSL对象的指针。

为了延续我与CButtonSSL开始的风格,这里是类的文档。

概述 | 类成员 | 已知问题

CTabCtrlSSL

“标签控件”类似于笔记本中的分隔符或文件柜中的标签。通过使用标签控件,应用程序可以在同一窗口或对话框区域定义多个页面。每个页面包含一组信息或一组控件,应用程序会在用户选择相应标签时显示它们。CTabCtrlSSL通过提供一个接口来扩展标准标签控件,该接口用于向控件添加以对话框资源定义的标签。这些标签在内部被定义为CTabPageSSL对象。还有一个用于将此类对象添加到标签控件的接口,允许通过继承CTabPageSSL来定义自定义对象。

CTabCtrlSSL创建的任何标签页(通过传入对话框资源ID添加的标签页)都会被CTabCtrlSSL销毁。客户端有责任销毁任何传递给CTabCtrlSSLCTabPageSSL派生对象。

#include "TabCtrlSSL.h"

概述 | 类成员 | 已知问题

类成员

然后,当你开始迭代 2(这是构建迭代的开始)时,你可能想要复制测试用例并将它们重新分类到迭代 2。这还允许对测试用例进行粒度跟踪,并允许你说某个测试用例在一个迭代中是准备好的,但在另一个迭代中不是。同样,如何做到这一点取决于你以及你希望如何报告。 “场景”部分提供了更多细节。

CTabCtrlSSL 构造一个CTabCtrlSSL对象。

页面函数

AddSSLPage 向控件添加一个标签。
RemoveSSLPage 从控件中移除一个标签。
GetSSLPageCount 返回添加到控件中的标签数量。
GetSSLPageTitle 返回特定标签页的标签。
SetSSLPageTitle 设置特定标签页的标签。
GetSSLPageID 返回指定标签页的页面ID。
SetSSLPageID 设置指定标签页的页面ID。
ActivateSSLPage 使指定的标签页成为活动的。
GetSSLActivePage 获取当前活动的标签页。
GetSSLPageIndex 返回指定标签页的页面索引。

可重写函数

OnInitPage 在派生类中重写以初始化页面。
OnActivatePage 在派生类中重写以响应页面激活。
OnDeactivatePage 在派生类中重写以响应页面停用。
OnDestroyPage 在派生类中重写以释放资源。

概述 | 类成员 | 已知问题

CTabCtrlSSL::CTabCtrlSSL

CTabCtrlSSL ();

备注

构造一个CTabCtrlSSL对象。

概述 | 类成员 | 已知问题

CTabCtrlSSL::AddSSLPage

int AddSSLPage (LPCTSTR pszTitle, int nPageID, int nTemplateID);

int AddSSLPage (LPCTSTR pszTitle, int nPageID, LPCTSTR pszTemplateName);

int AddSSLPage (LPCTSTR pszTitle, int nPageID, CTabPageSSL* pTabPage);

返回值

成功时返回新标签的零基索引,否则返回–1。

参数

pszTitle

指向包含标签文本的以null结尾的字符串的地址。

nPageID

用于引用要添加的页面的零基数字ID。

nTemplateID

指定标签页的资源ID。

pszTemplateName

指向包含要加载的对话框资源名称的以null结尾的字符串。

pTabPage

指向要添加的CTabPageSSL对象的指针。

备注

调用此函数以在现有标签控件中插入新标签。

概述 | 类成员 | 已知问题

参见 CTabCtrlSSL::RemoveSSLPage, CTabCtrlSSL::GetSSLPage

CTabCtrlSSL::RemoveSSLPage

BOOL RemoveSSLPage (int nIndex);

返回值

成功则为非零,否则为 0。

参数

nIndex

要删除的项目的零基值。

备注

调用此函数以从标签控件中移除指定的项目。

概述 | 类成员 | 已知问题

参见 CTabCtrlSSL::AddSSLPage, CTabCtrlSSL::GetSSLPage

CTabCtrlSSL::GetSSLPageCount

int GetSSLPageCount ();

返回值

标签控件中的项目数。

备注

调用此函数以检索标签控件中的标签数。

概述 | 类成员 | 已知问题

CTabCtrlSSL::GetSSLPageTitle

BOOL GetSSLPageTitle (int nIndex, CString& strTitle);

返回值

成功则为非零,否则为 0。

参数

nIndex

相关标签页的零基值。

strTitle

用于接收标签页标题的CString引用。

备注

调用此函数以检索标签控件中指定项目的标题。

概述 | 类成员 | 已知问题

参见 CTabCtrlSSL::SetSSLPageTitle

CTabCtrlSSL::SetSSLPageTitle

BOOL SetSSLPageTitle (int nIndex, LPCTSTR pszTitle);

返回值

成功则为非零,否则为 0。

参数

nIndex
相关标签页的零基值。

pszTitle

指向包含要为指定标签页设置的标题的以null结尾的字符串。

备注

调用此函数以设置标签控件中指定项目的标题。

概述 | 类成员 | 已知问题

参见 CTabCtrlSSL::GetSSLPageTitle

CTabCtrlSSL::GetSSLPageID

int GetSSLPageID (int nIndex);

返回值

成功时返回零基页面标识符,否则返回-1。

参数

nIndex

相关标签页的零基索引。

备注

调用此函数以检索标签控件中指定项目的页面标识符(在添加标签时指定)。页面标识符也可以使用SetSSLPageID函数进行修改。

概述 | 类成员 | 已知问题

参见 CTabCtrlSSL::SetSSLPageID

CTabCtrlSSL::SetSSLPageID

int SetSSLPageID (int nIndex, int nPageID);

返回值

成功时返回之前的零基页面标识符,否则返回-1。

参数

nIndex

相关标签页的零基索引。

nPageID

要设置的新零基页面标识符。

备注

调用此函数以更改指定标签页的页面标识符。

概述 | 类成员 | 已知问题

参见 CTabCtrlSSL::GetSSLPageID

CTabCtrlSSL::ActivateSSLPage

BOOL ActivateSSLPage (int nIndex);

返回值

成功则为非零,否则为 0。

参数

nIndex

要激活的标签页的零基索引。

备注

调用此函数以更改活动标签。

概述 | 类成员 | 已知问题

参见 CTabCtrlSSL::GetSSLActivePage

CTabCtrlSSL::GetSSLActivePage

int GetSSLACtivePage ();

返回值

成功时返回选定标签的零基索引,如果没有选定标签则返回–1。

备注

调用此函数以检索标签控件中当前选定的标签。

参见 CTabCtrlSSL::ActivateSSLPage

概述 | 类成员 | 已知问题

CTabCtrlSSL::GetSSLPage

CWnd* GetSSLPage (int nIndex);

返回值

成功时返回请求的标签页的指针,否则返回NULL

参数

nIndex

要获取的标签页的零基索引。

备注

调用此函数以获取标签控件中的特定标签。

概述 | 类成员 | 已知问题

CTabCtrlSSL::GetSSLPageIndex

int GetSSLPageIndex (int nPageID);

返回值

成功时返回指定标签的零基索引,否则返回-1。

参数

nPageID

相关标签页的零基页面标识符。

备注

调用此函数以检索标签控件中标签页的零基索引。

概述 | 类成员 | 已知问题

CTabCtrlSSL::OnInitPage

BOOL OnInitPage (int nIndex, int nPageID);

返回值

成功则为非零,否则为 0。

参数

nIndex

正在初始化的标签页的零基索引。

nPageID

正在初始化的页面的零基页面标识符。

备注

在派生类中重写以初始化页面。

概述 | 类成员 | 已知问题

CTabCtrlSSL::OnActivatePage

void OnActivatePage (int nIndex, int nPageID);

参数

nIndex

正在激活的标签页的零基索引。

nPageID

正在激活的页面的零基页面标识符。

备注

在派生类中重写以响应页面激活。

概述 | 类成员 | 已知问题

CTabCtrlSSL::OnDeactivatePage

void OnDeactivatePage (int nIndex, int nPageID);

参数

nIndex

正在激活的标签页的零基索引。

nPageID

正在激活的页面的零基页面标识符。

备注

在派生类中重写以响应页面停用。

概述 | 类成员 | 已知问题

CTabCtrlSSL::OnDestroyPage

void OnDestroyPage (int nIndex, int nPageID);

参数

nIndex

正在激活的标签页的零基索引。

nPageID

正在激活的页面的零基页面标识符。

备注

在派生类中重写以释放资源。

概述 | 类成员 | 已知问题

已知问题

据我所知,没有,但是高级标签部分还没有经过太多测试。如果你发现了任何问题,请告诉我。

更新

  • 2003年10月1日

    关于CTabCtrlSSL我收到的最常见的问题是关于某个x、y或z控件无法接收消息。

    我已经向许多人反复解释过这个问题和解决方案,现在,多亏了John A Johnson,我有一个真正有效的解决方案,可以应用于所有人的源代码。

    问题在于WM_COMMANDWM_NOTIFYWM_CMDMSG被传递给了标签页的父窗口,即标签控件,然后标签控件又将它们传递给它的父窗口(通常是对话框),以便父对话框可以处理标签页的通知等。不幸的是,这意味着任何派生的标签页都不会有机会处理自己的控件通知,除非您在CTabPageSSL中移除OnCommandOnNotifyOnCmdMsg处理程序。

    真正的解决方案是默认关闭此命令路由,因为大多数人希望直接在拥有它们的类中处理控件通知,但允许人们选择重新打开命令路由,如果他们希望父对话框来处理它们。这导致在CTabPageSSL中增加了一些方法。但是,如果您只想在派生的标签页中处理命令/通知,您根本不需要更改代码,只需将新的*TabPageSSL.h*和*TabPageSSL.cpp*文件插入即可。

© . All rights reserved.