带模板的分割视图






4.61/5 (9投票s)
2003年10月9日
3分钟阅读

76396

2226
如何为分割视图使用模板
引言
这个项目的想法来源于我尝试使用大量拆分器视图来实现一个项目。我想要使我的拆分器视图具有通用性,但问题是在使用动态创建时,无法将参数传递给类的构造函数。更准确地说,在我的上下文中,我使用 CSplitterWnd::CreateView()
来创建和替换视图。此方法使用视图的运行时类来动态实例化视图对象,因此无法将参数传递给其构造函数。这阻止了实现一个通用的拆分器类,该类创建带有视图(或视图的运行时类)作为参数传递给其构造函数的拆分器视图。为了克服这个问题,我使用了模板。
Using the Code
在解释代码之前,我想指出我已经将其简化到最低限度。这个示例是使用模板的展示,而不是一个完整的解决方案。在 *mysplitterview.h* 中声明的 CMySplitterView
是负责创建具有 2 个视图的拆分器视图的主要模板类。模板参数 TView1
和 TView2
是要在拆分器视图中显示的视图,而 TSplitterType
是创建的拆分器视图的类型。
template<class TView1, class TView2, class TSplitterType>
class CMySplitterView : public CView
该类型定义了拆分器视图的布局:水平或垂直。两个策略类定义了行为
class CHSplitterType : public CObject
class CVSplitterType : public CObject
每个类都定义了 CreateSplitterView()
方法,该方法由 CMySplitterView::OnCreate()
调用,以使用特定布局创建拆分器视图。此外,它们还定义了 OnSize()
,该方法由 CMySplitterView::OnSize()
调用,以设置视图的默认大小。代码的这一部分可以得到很大的改进。例如,模板拆分器类使用的视图可以公开一个由 OnSize()
调用的方法,以获取其所需的默认大小。
现在,为了使其工作,需要定义代码中使用的 splitter
类。在示例中,我使用了两个 splitter
视图:一个用于右侧的水平 splitter
视图,一个用于全局垂直 splitter
视图(所有视图都是 CSplitterView
)。
template class CMySplitterView<CSplitterView, CSplitterView, CHSplitterType>;
template class CMySplitterView<CSplitterView, tclRightView, CVSplitterType>;
这里,tclRightView
是右侧水平 splitter
视图 CMySplitterView<CSplitterView, CSplitterView, CHSplitterType>
的类型定义。
对于主视图的创建,我将 tclDefaultView
(CMySplitterView<CSplitterView, tclRightView, CVSplitterType>
的类型定义)传递给构造函数 CSingleDocTemplate()
。使用类型定义,可以想象任何可能的 2 视图 splitter
视图组合。
关注点
现在是示例中一个有点棘手的部分。当然,您需要为您的 splitter
视图使用 IMPLEMENT_DYNCREATE
和 BEGIN_MESSAGE_MAP
。 Microsoft 提供了用于具有一个或两个模板的类的宏(IMPLEMENT_DYNCREATE_T
、IMPLEMENT_DYNCREATE_T2
…)。不幸的是,这些宏是有缺陷的,并且没有用于具有 3 个模板的类的宏。我已经将它们包含在 *mysplitterview.cpp* 中:M_IMPLEMENT_DYNCREATE_T3
和 M_BEGIN_MESSAGE_MAP_T3
以及辅助宏 M_IMPLEMENT_RUNTIMECLASS_T3
和 M_RUNTIME_CLASS_T3
。它们适用于具有 3 个模板的类。这是如何使用它们
M_IMPLEMENT_DYNCREATE_T3( CMySplitterView, CSplitterView,
CSplitterView, CHSplitterType, CView )
M_BEGIN_MESSAGE_MAP_T3( CMySplitterView, CSplitterView,
CSplitterView, CHSplitterType, CView )
ON_WM_SIZE()
ON_WM_CREATE()
END_MESSAGE_MAP()
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。