一个可视化框架(视图、标签页和分割器)






4.96/5 (65投票s)
2000年1月6日

843393

17979
创建带有分割器和标签页窗口的 SDI/MDI 应用程序
在创建具有复杂视图布局的应用程序时,MFC 中缺少一些功能。首先,每种类型的视图布局的创建方式不同(简单视图 vs. 分割器 vs. 嵌套分割器)。简单视图布局不需要任何额外的代码(MFC 会处理创建)。分割器布局需要 CSplitterWnd 和手动创建每个窗格。嵌套分割器则更为复杂。其次,MFC 不支持标签页窗口,而这在几乎所有商业应用程序中都能找到,并且非常有利于更好的 UI 组织。
去年,我阅读了 Daniel Harth 关于标签页视图的文章(在 CodeGuru 上)。它并不完全符合我的需求,所以我修改了它,结果我得到了一个标签页窗口类,它可以包含在分割器窗口内,也可以包含分割器窗口。然而,它并非一个框架。创建用户界面散布在整个代码中,因为(对于复杂的布局)一部分代码在 OnCreateClient 中完成,而其他部分则在一个或多个派生的标签页窗口类中完成。本文提出的可视化框架是完全重新设计的。
最新更新
2000.01.14 - Frederic Gullet
Frederic 指出了如何为标签页项添加图标。根据他对文章的评论,我更新了代码和演示项目。为标签页添加图标(16x16 像素)是可选的。如果您需要它,则执行 TVisualObject::SetIcon()
(参见下面的示例和上面的图片)。为非标签页的可视化对象添加图标不会产生任何错误,也没有任何效果。之前的函数从应用程序资源加载图标并将其传递给标签页窗口。
注意:所有更新都用 [NEW] 标记,以便于搜索。
引言
可视化框架支持 SDI 和 MDI 应用程序,以及任何 CView 派生类、CSplitterWnd 和 TTabWnd 派生窗口的组合。它非常易于使用。这是创建图 1 所示框架的代码片段。
BOOL CSplitterTabFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext) { // m_Framework is a member of CSplitterTabFrame class (derived from CMDIChildWnd) // Splitter (1 row, 2 columns). Second column is a tab with 2 panes TVisualObject *pSplitter = new TVisualObject(1, "", 1, 2, pContext); TVisualObject *pView1 = new TVisualObject(2, 0,0,pContext, RUNTIME_CLASS(CDummyTree), CSize(150,0)); TVisualObject *pTab = new TVisualObject(3, 0,1,pContext, RUNTIME_CLASS(TTabWnd), CSize(0,0)); TVisualObject *pTabView1 = new TVisualObject(4, "Cars",pContext, RUNTIME_CLASS(CDummyList)); TVisualObject *pTabView2 = new TVisualObject(5, "Fruits", pContext, RUNTIME_CLASS(CDummyTree)); // Define tab icons [NEW] pTabView1->SetIcon(IDI_ICON_A); pTabView2->SetIcon(IDI_ICON_A); // Add all visual objects to the framework m_Framework.Add(pSplitter); m_Framework.Add(pSplitter, pView1); m_Framework.Add(pSplitter, pTab); m_Framework.Add(pTab, pTabView1); m_Framework.Add(pTab, pTabView2); // Create the framework and all windows return m_Framework.Create(this); }
以下是支持的功能列表
- 支持 MDI 和 SDI 应用程序。
- 视图、多个分割器和标签页窗口的任意组合。
- 支持嵌套分割器。
- 支持基于 CView 的简单应用程序。
- 支持热键(例如,ALT+3)来选择活动窗格。
- 支持 Ctrl+Tab 切换标签页。
- 支持枚举。
- 标签页可以位于标签页窗口的顶部或底部。
完整的实现包含在 2 个文件中(VisualFx.cpp 和 VisualFx.h)。这些文件实现了以下类
- TVisualFramework 类。此类派生自 CCmdTarget。它实现了完整的框架。
- TVisualObject 类。此类表示可视化对象(视图、分割器或标签页窗口)。
- TVisualFrameworkIterator 类。此类用于枚举框架中的可视化对象。
- TTabWnd 类。此类派生自 CWnd,表示标签页窗口。
- TTabItem 类。此类表示标签页窗口中的一个标签页。
- TVisualFormView 类。派生自 CFormView。它处理 form view 的 SetFont() 和 EnableWindow()。
术语
为了澄清本文档中使用术语的任何混淆,下图解释了典型框架的各个部分
使用可视化框架
可视化框架设计得易于使用。它还提供了一致的界面,无论您创建哪种类型的应用程序(简单视图、分割器、带嵌套分割器的分割器或更复杂的带标签页窗口的应用程序),该界面都是相同的。因此,修改用户界面(视图布局)很简单,并且仅限于一个函数(OnCreateClient()
)。
框架创建后,您可以使用框架对象(以可视化对象为参数)或直接使用可视化对象(无参数)来执行许多任务(设置字体、更改活动窗格、更改活动标签页、获取活动窗格、获取活动标签页等)。
步骤 1:创建可视化对象
首先,您必须为所需的每个窗口创建 TVisualObject
对象(使用适当的构造函数)。由于 TVisualObject
类有一个私有的默认构造函数,此类对象必须使用 new 创建(框架将删除这些指针)。TVisualObject
对象的指针非常适合访问框架创建的窗口。您不得删除这些指针,因为它们在框架内部使用。例如,
// Creating a simple view TVisualObject *pView = new TVisualObject(1,pContext, RUNTIME_CLASS(CDummyList)); // Creating a splitter window with 2 views TVisualObject *pSplitter = new TVisualObject(1,"", 1, 2, pContext); TVisualObject *pView1 = new TVisualObject(2,0,0,pContext, RUNTIME_CLASS(CDummyTree), CSize(150,0)); TVisualObject *pView2 = new TVisualObject(3,0,1,pContext, RUNTIME_CLASS(CDummyEdit), CSize(0,0)); // Creating a tab window with 2 panes TVisualObject *pTab = new TVisualObject(1,"",pContext, RUNTIME_CLASS(TTabWnd)); TVisualObject *pTabPane1 = new TVisualObject(2,"Cars",pContext, RUNTIME_CLASS(CDummyList)); TVisualObject *pTabPane2 = new TVisualObject(3,"Fruits", pContext, RUNTIME_CLASS(CDummyTree));
步骤 2(可选):添加热键、描述和图标
如果您需要热键支持(通过 Alt+3 等组合键设置活动窗格),则需要添加以下内容(请注意,为无法获得焦点的窗口定义热键没有意义 - 分割器和标签页窗口)
// Define hotkey for panes
pTabPane1->SetHotKey('1'); pTabPane2->SetHotKey('2');
如果您的应用程序枚举框架窗口,您还可以为每个窗口定义描述。例如,
// Define description
pTabPane1->SetDescription("Pane with car list"); pTabPane2->SetDescription("Pane with fruit list");
[NEW] 如果您需要在标签页上显示图标,请执行以下操作
pTabPane1->SetIcon(IDI_ICON_A);其中 IDI_ICON_A 是应用程序资源中的一个 16x16 像素的图标。
步骤 3:声明框架对象
框架由 TVisualFramework
对象表示,该对象是 CFrameWnd
派生类的一个成员。对于 SDI 应用程序,它是派生自 CFrameWnd
的类;对于 MDI 应用程序,它是派生自 CMDIChildWnd
的类。
// Framework object
TVisualFramework m_Framework;
步骤 4:将对象添加到框架
创建所有可视化对象后,您必须将它们添加到可视化框架中。可视化框架只支持一个根可视化对象(视图、分割器或标签页窗口)。所有其他可视化对象通过指定其父对象添加到框架中。框架将检查(在调试版本中)执行操作的有效性(例如,您不能将标签页窗口添加到视图中)。例如,
m_Framework.Add(pTab); // Root level object m_Framework.Add(pTab, pTabPane1); // Add first pane to tab m_Framework.Add(pTab, pTabPane2); // Add second pane to tab
步骤 5:创建框架
最后,调用框架的 Create 方法来实际创建框架和所有定义的窗口。提供的父窗口指针必须指向派生自 CFrameWnd
的窗口。由于完整的框架定义和创建是在派生自 CFrameWnd
或 CMDIChildWnd
(派生自 CFrameWnd
)的窗口的 OnCreateClient()
函数内部完成的,因此应提供此指针。
// Create the framework m_Framework.Create(this);
框架创建后,每个 TVisualObject
实例都包含一个指向已创建且有效的窗口的指针。
步骤 6:销毁框架
另一个重要的事情是框架的销毁。要销毁框架,请在派生自 CFrameWnd
的窗口的 OnDestroy()
函数中调用 Destroy()
成员函数。
// Destroy the framework
m_Framework.Destroy();
框架不能在 TVisualFramework
对象的析构函数中销毁。如果您忘记按照上述说明调用 Destroy()
,您将在应用程序的调试版本中收到一个 ASSERT。
步骤 7(可选):添加对 Ctrl+Tab 和热键的支持
如果您需要热键支持(参见步骤 2),则需要重写 CWinApp
派生类的 PreTranslateMessage
函数并添加以下代码(此示例适用于 SDI 应用程序)
BOOL CTabWndApp::PreTranslateMessage(MSG* pMsg) { CMainFrame *pFrame = (CMainFrame*)::AfxGetMainWnd(); if (pFrame) { if(pFrame->m_Framework.ProcessMessage(pMsg)) return TRUE; } return CWinApp::PreTranslateMessage(pMsg); }
这使得框架可以检查应用程序队列中的每条消息并处理 Ctrl+Tab 组合键或热键(例如 Alt+2)。
实现
框架中的所有数据结构都使用 STL 实现。STL 容器存储对象的指针。框架中的可视化对象层次结构使用列表容器实现,其中容器内的每个可视化对象都包含另一个子可视化对象的列表。此层次结构用于使用私有的递归函数创建和销毁对象(窗口)。在创建可视化对象时,框架从上到下扫描层次结构。另一方面,在框架销毁过程中,框架从下到上进行扫描。
除了对象层次结构之外,框架还包含一个所有可视化对象的映射,其中键是用户为每个 TVisualObject
构造函数提供的 DWORD。如果此键在框架中不是唯一的,则 Add()
函数(参见步骤 4)将失败(调试版本中为 ASSERT)。此键用于任何与可视化对象相关的操作,以及从框架获取可视化对象的指针。
TTabWnd
类实现了标签页窗口。它派生自 CWnd,并且仅用作框架的一部分。标签页窗口类包含一个 TTabItem
对象列表。每个 TTabItem
对象代表一个标签页,并包含一个指向与标签页关联的窗口(标签页窗格)的指针。标签页标题是一个 CStatic
对象。TTabWnd
负责在活动标签页窗格更改时更新框架窗口。更改活动标签页窗格时,TTabWnd
会调用 2 个具有默认实现的虚拟函数:CanSetActivePane()
和 OnSetActivePane()
。派生自 TTabWnd
的类有机会使用第一个函数阻止更改活动窗格,并有机会在第二个函数中执行附加活动。
演示项目
有一个 SDI 和 MDI 应用程序的演示项目。SDI 应用程序包含几种不同用户界面视图布局的代码。为了测试它们,请更改 #define ...
位于派生自 CFrameWnd 的窗口的 OnCreateClient()
的开头,然后重新构建项目。MDI 应用程序定义了几种不同的模板。选择文件 | 新建以创建具有不同视图布局的窗口。
类参考
类
- TVisualObject
- TVisualFramework
- TVisualFrameworkIterator
- TTabWnd
成员函数
- TVisualObject
- TVisualObject
- TObjectStyle
- CanFocus
- SetHotKey
- SetDescription
- SetIcon [NEW]
- SetActivePane
- SetActiveTab
- 启用
- EnableTab
- ShowTab
- IsEnabled
- IsTabEnabled
- IsTabVisible
- IsTabPane
- IsTabWindow
- IsSplitterPane
- IsSplitterWindow
- IsView
- GetID
- GetWnd
- GetSafeWnd
- GetTitle
- GetDescription
- GetParentWnd
- GetFramework
- GetOwner
- TVisualFramework
- TVisualFramework
- Add
- Create
- Destroy
- GetWnd
- GetSafeWnd
- GetObject
- Get
- IsTabPane
- IsTabWindow
- IsSplitterPane
- IsSplitterWindow
- IsView
- GetCount
- GetActiveTab
- SetActiveTab
- SetActivePane
- GetActivePane
- 启用
- EnableTab
- ShowTab
- IsEnabled
- IsTabEnabled
- IsTabVisible
- SetFont
- EnableCtrlTab
- CreateSplitter
- ProcessMessage
- TVisualFrameworkIterator
- TVisualFrameworkIterator
- operator->
- Get
- End
- operator++
- TTabWnd
- HitTest
- SetActivePane
- CanSetActivePane
- OnSetActivePane
类 TVisualObject
TVisualObject(DWORD dwId, CCreateContext *pContext, CRuntimeClass *pClass) TVisualObject(DWORD dwId, LPCTSTR szTitle, CCreateContext *pContext, CRuntimeClass *pClass, DWORD dwStyle = 0) TVisualObject(DWORD dwId, LPCTSTR szTitle, int nRows, int nCols, CCreateContext *pContext, DWORD dwStyle = 0) TVisualObject(DWORD dwId, int nRow, int nCol, CCreateContext *pContext, CRuntimeClass *pClass, CSize size, DWORD dwStyle = 0) TVisualObject(DWORD dwId, int nRow, int nCol, int nRows, int nCols, CCreateContext *pContext, DWORD dwStyle = 0)
构造可视化对象。
DWORD dwId 是此可视化对象的唯一 ID(用户定义)。
CRuntimeClass *pClass
是与此可视化对象关联的窗口的运行时类。它可以指示派生自 CView
或 TTabWnd
的类。派生自 CSplitterWnd
的类不能在运行时创建。请检查 TVisualFramework::CreateSplitter()
虚拟函数。
LPCTSTR szTitle
是父标签页窗口的标签页标题。
int nRows, nCols 是分割器窗口的行数和列数。
int nRow, nCol 是分割器窗口内窗格的行和列。
CSize size 是分割器窗格的初始大小。
DWORD dwStyle
是 TObjectStyle 枚举中样式的按位或组合。
第一个构造函数创建一个普通视图。提供的 pClass 参数必须指示派生自 CView
的类。
第二个构造函数根据 CRuntimeClass pClass 参数创建标签页窗口或标签页内的窗格。如果 pClass 指示派生自 TTabWnd 的类,则此构造函数创建标签页窗口。如果 pClass 指示派生自 CView 的类,则此构造函数创建标签页内的窗格。
第三个构造函数创建静态分割器窗口。由于 CSplitterWnd 不支持运行时创建对象,因此需要创建 CSplitterWnd 派生类的应用程序必须派生自 TVisualFramework 并重写虚拟函数 CreateSplitter。
第四个构造函数创建分割器窗口内的窗格。pClass 必须指示派生自 CView 或 TTabWnd 的类。
第五个构造函数创建嵌套分割器窗口。它位于父分割器窗口的 nRow 行和 nCol 列。由于 CSplitterWnd 不支持运行时创建对象,因此需要创建 CSplitterWnd 派生类的应用程序必须派生自 TVisualFramework 并重写虚拟函数 CreateSplitter。
enum TObjectStyle
此枚举定义了可视化对象的样式。默认样式为无样式。可能的样式为
- TOS_TABTOP
- TOS_TABBOTTOM
- TOS_SELECTED
TOS_TABTOP 仅对标签页窗口对象有效。它表示标签页位于窗口的顶部(在标签页窗格之上)。
TOS_TABBOTTOM 仅对标签页窗口对象有效。它表示标签页位于窗口的底部(在标签页窗格之下)。
TOS_SELECTED 仅对标签页窗格有效。它指示父标签页窗口中哪个标签页窗格被选中。
BOOL CanFocus(void)
如果此可视化对象可以获得焦点(是 CView 或派生自 CView),则返回 TRUE。如果此对象派生自 TTabWnd 或 CSplitterWnd,则返回 FALSE。
void SetHotKey(CHAR cHotKey)
为此可视化对象设置热键。为无法获得焦点的可视化对象定义热键没有意义。热键应为数字,因为框架在 WM_SYSKEYDOWN Windows 消息上检查热键。
void SetDescription(LPCTSTR szDesc)
可选。此函数设置可视化对象的描述。框架不使用描述,但应用程序可能会使用它。
BOOL SetActivePane(void)
将此可视化对象代表的窗格设置为框架中的活动窗格。如果可视化对象无法获得焦点(CanFocus() 返回 FALSE)或可视化对象代表的窗口被禁用,则返回代码为 FALSE。框架窗口会更新,以便 CFrameWnd::GetActiveView() 返回与此可视化对象关联的窗口。活动窗格具有键盘和鼠标焦点。
BOOL SetActiveTab(void)
如果此可视化对象的父对象是标签页窗口,则此函数将父标签页窗口的活动标签页窗格设置为此可视化对象。与此可视化对象关联的窗口未激活。但是,会调用虚拟函数 TTabWnd::CanSetActivePane() 和 TTabWnd::OnSetActivePane()。如果活动标签页已更改,则返回代码为 TRUE。在任何其他情况下,返回代码为 FALSE。
BOOL Enable(BOOL bEnable)
根据提供的参数启用或禁用与此可视化对象关联的窗口。如果父对象是标签页窗口,则标签页也会被启用/禁用。禁用的标签页标题显示为灰色,无法选择。如果此可视化对象与非 CView 派生类关联,则返回 FALSE。
BOOL EnableTab(BOOL bEnable)
仅启用或禁用父标签页窗口的标签页。与标签页关联的窗口未修改。如果调用的是当前活动的标签页,则函数失败。
BOOL ShowTab(BOOL bShow)
显示或隐藏父标签页窗口的标签页。如果标签页当前处于活动状态,则在调试版本中会触发 ASSERT。
BOOL IsEnabled(BOOL& bEnabled)
如果这是对此可视化对象的有效操作,则返回 TRUE。在这种情况下,bEnabled 指示与此可视化对象关联的窗口是否已启用。
BOOL IsTabEnabled(BOOL& bEnabled)
如果这是对此可视化对象的有效操作,则返回 TRUE。在这种情况下,bEnabled 指示父标签页窗口的标签页是否已启用。
BOOL IsTabVisible(BOOL& bVisible)
如果这是对此可视化对象的有效操作,则返回 TRUE。在这种情况下,bVisible 指示父标签页窗口的标签页是否可见。
BOOL IsTabPane(void)
如果与此可视化对象关联的窗口的父对象是标签页窗口,则返回 TRUE。
BOOL IsTabWindow(void)
如果与此可视化对象关联的窗口是标签页窗口,则返回 TRUE。
BOOL IsSplitterPane(void)
如果与此可视化对象关联的窗口的父对象是分割器窗口,则返回 TRUE。
BOOL IsSplitterWindow(void)
如果与此可视化对象关联的窗口是分割器窗口,则返回 TRUE。
BOOL IsView(void)
如果与此可视化对象关联的窗口派生自 CView,则返回 TRUE。
DWORD GetID(void)
返回此可视化对象的唯一 ID。
CWnd *GetWnd(void)
返回与此可视化对象关联的窗口的指针。
CWnd *GetSafeWnd(void)
返回与此可视化对象关联的窗口的安全指针。如果窗口句柄无效,则指针为 NULL。
CString GetTitle(void)
返回此可视化对象的标题。对于不是父标签页窗口的标签页的可视化对象,标题可能为空。
CString GetDescription(void)
返回此可视化对象的描述。如果未通过 SetDescription 定义,则描述为空。
CWnd *GetParentWnd(void)
返回与此可视化对象关联的窗口的父窗口的指针。
TVisualFramework *GetFramework(void)
返回框架的指针。当可视化对象添加到框架时定义此指针。
TVisualObject *GetOwner(void)
返回父可视化对象的指针。对于根级别可视化对象,它为 NULL。
类 TVisualFramework
TVisualFramework()
构造可视化框架对象。SDI 应用程序必须只有一个框架对象。MDI 应用程序应为每个 MDI 子框架有一个框架对象。
BOOL Add(TVisualObject *pObject)
BOOL Add(TVisualObject *pOwner, TVisualObject *pObject)
第一个函数将提供的可视化对象添加到框架中。提供的可视化对象是根级别对象。如果执行多次,应用程序将在调试版本中触发 ASSERT。如果对象已添加到框架中,则返回 TRUE。如果对象没有唯一的 ID,则返回 FALSE。
第二个函数将一个可视化对象(pObject)添加到其父对象(pOwner)中。此函数将检查(在调试版本中)要添加对象的有效性。如果对象已添加到其父对象中,则返回 TRUE。如果对象没有唯一的 ID,则返回 FALSE。
virtual BOOL Create(CWnd *pWnd = NULL)
创建框架和可视化对象层次结构中的所有窗口。提供的指针不能为空,并且必须指向派生自 CFrameWnd 的窗口。在创建可视化对象窗口时,框架从上到下扫描可视化对象层次结构。创建所有窗口后,框架将找到第一个可以获得焦点的窗口并调用 SetActivePane()。
virtual void Destroy(void)
销毁框架。必须在主框架窗口的 OnDestroy() 函数中调用。如果不这样做,应用程序将在调试版本中触发 ASSERT。框架通过从下到上扫描可视化对象层次结构来销毁。通过调用 DestroyWindow() 来销毁每个 CSplitterWnd 或 TTabWnd 派生类。视图未被销毁,因为应用程序的框架窗口负责此操作。
CWnd *GetWnd(void)
返回 Create() 中提供的框架窗口的指针。
CWnd *GetSafeWnd(void)
返回 Create() 中提供的框架窗口的安全指针。如果窗口句柄无效,则返回 NULL。
CWnd *GetObject(DWORD dwId) DWORD GetObject(CWnd *pWnd)
第一个函数返回与具有 dwId 唯一 ID 的可视化对象关联的窗口。
第二个函数返回与提供的窗口关联的可视化对象的唯一 ID。
TVisualObject *Get(DWORD dwId) TVisualObject *Get(CWnd *pWnd)
第一个函数返回具有指定唯一 ID 的可视化对象的指针。请勿删除此指针。
第二个函数返回与指定窗口关联的可视化对象的指针。请勿删除此指针。
BOOL IsTabPane(TVisualObject *pObject)
如果提供的可视化对象是父标签页窗口的标签页窗格,则返回 TRUE。
BOOL IsTabWindow(TVisualObject *pObject)
如果提供的可视化对象是标签页窗口,则返回 TRUE。
BOOL IsSplitterPane(TVisualObject *pObject)
如果提供的可视化对象是父分割器窗口的分割器窗格,则返回 TRUE。
BOOL IsSplitterWindow(TVisualObject *pObject)
如果提供的可视化对象是分割器窗口,则返回 TRUE。
BOOL IsView(TVisualObject *pObject)
如果提供的可视化对象是视图,则返回 TRUE。
int GetCount(void)
返回框架中的可视化对象数量。
TVisualObject *GetActiveTab(TVisualObject *pObject)
返回表示可视化对象 pObject 所代表的标签页窗口中当前活动标签页的可视化对象指针。如果 pObject 不是标签页窗口,则返回 NULL。
BOOL SetActiveTab(TVisualObject *pObject)
设置可视化对象 pObject 所代表的父标签页窗口的活动标签页。如果 pObject 的父对象不是标签页窗口,则返回 FALSE。活动标签页不具有键盘和鼠标焦点。
BOOL SetActivePane(TVisualObject *pObject)
将键盘和鼠标焦点设置到提供的可视化对象窗口。如果与提供的 pObject 可视化对象关联的窗口无法获得焦点或被禁用,则函数将返回 FALSE。函数将通过调用 SetActiveView() 来更新框架窗口。
TVisualObject *GetActivePane(void)
返回表示当前活动窗格的可视化对象指针。
BOOL Enable(TVisualObject *pObject, BOOL bEnable)
启用或禁用由 pObject 表示的视图。如果 pObject 未与视图关联,则返回代码为 FALSE。
BOOL EnableTab(TVisualObject *pObject, BOOL bEnable)
启用或禁用与 pObject 关联的标签页。如果 pObject 的父对象不是标签页窗口或 pObject 标签页当前处于活动状态,则返回 FALSE。
BOOL ShowTab(TVisualObject *pObject, BOOL bEnable)
显示或隐藏与 pObject 关联的标签页。如果 pObject 的父对象不是标签页窗口或 pObject 标签页当前处于活动状态,则返回 FALSE。
BOOL IsEnabled(TVisualObject *pObject, BOOL& bEnabled)
如果此操作有效,则返回 TRUE。在这种情况下,bEnabled 指示可视化对象窗口是已启用还是已禁用。
BOOL IsTabEnabled(TVisualObject *pObject, BOOL& bEnabled)
如果此操作有效(pObject 父对象是标签页窗口),则返回 TRUE。在这种情况下,bEnabled 指示可视化对象窗口是已启用还是已禁用。
BOOL IsTabVisible(TVisualObject *pObject, BOOL& bVisible)
如果此操作有效(pObject 父对象是标签页窗口),则返回 TRUE。在这种情况下,bVisible 指示可视化对象窗口是可见还是不可见。
void SetFont(CFont *pFont)
为框架中的所有可视化对象设置字体。它还将更改所有标签页标题的字体。如果可视化对象层次结构包含派生自 TVisualFormView 的对象,则所有 form view 控件的字体也将被更改。
void EnableCtrlTab(BOOL bEnable)
如果在 SDI 应用程序中使用此框架,则默认启用 Ctrl+Tab 处理。但是,MDI 应用程序使用 Ctrl+Tab 在所有打开的子框架之间切换。在这种情况下,框架的 Ctrl+Tab 处理将被禁用。您可以使用此函数启用它。
virtual CSplitterWnd *CreateSplitter(DWORD dwId)
由于 CSplitterWnd 不支持使用 CRuntimeClass 进行对象创建,因此此虚拟函数提供了一种返回 CSplitterWnd 派生类对象的指针的可能性。为了做到这一点,您必须派生自 TVisualFramework 并重写此函数。不要调用基类函数。需要 CSplitterWnd 或 CSplitterWnd 派生类对象指针的可视化对象由其唯一 ID dwId 标识。
virtual BOOL ProcessMessage(MSG *pMsg)
为了处理热键和 Ctrl+Tab,您必须实现应用程序的 CWinApp 派生类的 PreTranslateMessage() 函数并调用框架的 ProcessMessage() 函数。如果此函数返回 TRUE,则它已处理提供的消息,并且不应调用 CWinApp::PreTranslateMessage()。参见步骤 7。
类 TVisualFrameworkIterator
此类用于遍历可视化对象。典型的用法通过以下代码进行说明
TVisualFrameworkIterator iterator(m_Framework); while (!iterator.End()) { TVisualObject *pObject = iterator.Get(); // ... iterator ++; }
TVisualFrameworkIterator(TVisualFramework& obj) TVisualFrameworkIterator(TVisualObject& obj)
创建迭代器对象。
第一个构造函数创建一个迭代器,该迭代器遍历框架中的所有可视化对象。此迭代器扫描框架的内部可视化对象映射。返回的可视化对象的顺序取决于可视化对象的唯一 ID。
第二个构造函数创建一个迭代器,该迭代器遍历指定父可视化对象的所有子可视化对象。
TVisualObject*operator->()
重载的运算符,返回可视化对象指针。
TVisualObject *Get(void)
返回可视化对象指针。
int End(void)
如果还有更多可视化对象,则返回非零值。
int operator++(int)
重载的运算符,用于移至下一个可视化对象。
类 TTabWnd
由于 TTabWnd 类仅用作框架的一部分,因此此处是相关函数的文档。
virtual int HitTest(int x, int y) virtual int HitTest(CPoint& point)
返回与给定点对应的标签页的索引。索引从 0 开始。x、y 和 point 是客户端坐标。
BOOL SetActivePane(int nIndex, BOOL bActivate = TRUE)
更改活动标签页。如果选项卡已更改,则返回 TRUE。如果 bActivate 为 TRUE,则更新框架窗口,并且与选项卡关联的选项卡窗格将获得鼠标和键盘焦点。
virtual BOOL CanSetActivePane(CWnd *pOldPane, CWnd *pNewPane)
通过从此函数返回 FALSE,派生类有机会阻止更改活动标签页。
virtual void OnSetActivePane(CWnd *pOldPane, CWnd *pNewPane);
在活动窗格更改后调用此函数。