TN029:拆分窗口

此说明介绍 MFC CSplitterWnd 类,该类提供窗口拆分和管理其他窗格窗口的大小调整。

拆分样式

A CSplitterWnd 支持两种不同的拆分窗口样式。

在“静态拆分器”中,当拆分器窗口创建时,它就创建窗格。 窗格的顺序和数量永远不会更改。 拆分条用于调整不同窗格的大小。 可以使用此样式在每个窗格中显示不同的视图类。 Visual C++图形编辑器和 Windows 文件管理器是使用此拆分器样式的程序的示例。 此拆分器窗口样式不使用拆分器框。

在“动态拆分器”中,当用户拆分和取消拆分新视图时,会创建并销毁其他窗格。 这种拆分以单个视图开始,并提供拆分框供用户启动拆分。 拆分器窗口在视图按一个方向拆分时动态创建一个新的视图对象。 此新视图对象表示新窗格。 如果使用键盘界面将视图拆分为两个方向,则拆分器窗口将为三个新窗格创建三个新视图对象。 拆分处于活动状态时,Windows 会将拆分框显示为窗格之间的拆分条。 当用户删除拆分时,Windows 会销毁其他视图对象,但原始视图将一直保留,直到拆分器窗口本身被销毁。 Microsoft Excel 和 Microsoft Word 是使用动态拆分器样式的应用程序的示例。

创建任一类型的拆分器窗口时,必须指定拆分器将管理的最大行数和列数。 静态拆分器将创建用于填充所有行和列的窗格。 当创建 CSplitterWnd 时,动态拆分器将仅创建第一个窗格。

可以为静态拆分器指定的窗格的最大数目为16行乘16列。 建议的配置包括:

  • 1 行 x 2 列:窗格通常不同

  • 2 行 x 1 列:窗格通常不同

  • 2 行 x 2 列:通常具有类似的窗格

可以为动态拆分器指定的窗格的最大数目是 2 行到 2 列。 建议的配置包括:

  • 1 行 x 2 列:用于列数据

  • 2 行 x 1 列:对于文本或其他数据

  • 2 行 x 2 列:适用于面向网格或表的数据

拆分器示例

许多 MFC 示例程序直接或间接使用拆分器窗口。 MFC 常规示例 VIEWEX 说明了静态拆分器的多种用法,包括如何将拆分器放置在拆分器中。

还可以使用 ClassWizard 创建新的包含拆分窗口的多个文档界面 (MDI) 子框架窗口类。 有关拆分窗口的详细信息,请参阅 多个文档类型、视图和框架窗口

实现使用的术语

下面是特定于拆分窗口的术语列表:

CSplitterWnd:一个窗口,它提供在一行或一列上的所有窗格之间共享的窗格拆分控件和滚动条。 使用从零开始的数字指定行和列(第一个窗格为行 = 0,列 = 0)。

窗格:CSplitterWnd 管理的特定于应用程序的窗口。 窗格通常是派生自 CView 类的对象,但可以是具有相应子窗口 ID 的任何 CWnd 对象。

若要使用 CWnd派生对象,请像使用 CreateView派生类一样将对象的 RUNTIME_CLASS 传递给 CView 函数。 你的类必须使用DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE,因为框架在运行时使用动态创建。 尽管 CSplitterWnd 中有很多代码是特定于 CView 类的,但在执行这些操作之前,始终使用 CObject::IsKindOf

拆分条:位于窗格行和列之间的控件。 它可用于调整窗格的行或列的大小。

拆分框:动态 CSplitterWnd 中的一个控件,可用于创建窗格的新行或列。 它位于垂直滚动条的顶部或水平滚动条左侧。

分隔条交点:垂直分隔条与水平分隔条的交点。 可以拖动它以同时调整窗格的行和列的大小。

共享滚动条

CSplitterWnd 类还支持共享滚动条。 这些滚动条控件是 CSplitterWnd 的子级,并与拆分器中的不同窗格共享。

例如,在 1 行 x 2 列窗口中,可以在创建 CSplitterWnd列时指定WS_VSCROLL。 Windows 创建一个在两个窗格之间共享的特殊滚动条控件。

[      ][      ][^]
[pane00][pane01][|]
[      ][      ][v]

当用户移动滚动条时,WM_VSCROLL消息将发送到这两个视图。 当任一视图设置滚动条位置时,将设置共享滚动条。

请注意,共享滚动条对类似的视图对象最有用。 如果在拆分器中混合了不同类型的视图,则可能需要编写特殊代码来协调其滚动位置。 使用CView滚动条 API 的任何CWnd派生类都将委托给共享滚动条(如果存在)。 实现 CScrollView 是支持共享滚动条的 CView 类的一个示例。 不派生自 CView的类、依赖于非控制滚动条的类或使用标准 Windows 实现(例如) CEditView的类将不适用于共享滚动条功能 CSplitterWnd

最小尺寸

对于每一行,行高度最小,每列的列宽度最小。 此最低尺寸保证窗格不会太小而无法完全详细显示。

对于静态拆分器窗口,初始最小行高和列宽为 0。 对于动态拆分器窗口,初始最小行高和列宽由函数 的 sizeMin 参数 CSplitterWnd::Create 设置。

可以使用 CSplitterWnd::SetRowInfoCSplitterWnd::SetColumnInfo 函数更改这些最小大小。

实际大小与理想大小

拆分窗口中窗格的布局取决于包含它们的框架的大小。 当用户调整包含它们的框架的大小时,CSplitterWnd 重新调整窗格的位置和大小,使其尽可能适合框架。

用户可以手动设置行高和列宽大小,或者程序可以使用类设置理想的大小 CSplitterWnd 。 实际大小可以小于或大于理想大小。 如果没有足够的空间显示理想的大小,或者拆分窗口右侧或底部有太多的空白空间,Windows 将调整实际大小。

自定义控件

可以重写许多函数以提供自定义行为和自定义接口。 可以重写以下第一个设置,为拆分窗口的各种图形组件提供备用图像。

  • virtual void OnDrawSpltter(CDC* pDC, ESplitType nType, const CRect& rect);

  • virtual void OnInvertTracker(const CRect& rect);

调用此函数以创建共享滚动条控件。 可以重写它以在滚动条旁边创建额外的控件。

  • virtual BOOL CreateScrollBarCtrl(DWORD dwStyle, UINT nID);

这些函数实现动态拆分器窗口的逻辑。 你可以重写这些函数,提供更高阶的拆分逻辑。

  • virtual void DeleteView(int row, int col);

  • virtual BOOL SplitRow(int cyBefore);

  • virtual BOOL SplitColumn(int cxBefore);

  • virtual void DeleteRow(int rowDelete);

  • virtual void DeleteColumn(int colDelete);

CView 功能

CView 类使用以下高级命令委托给 CSplitterWnd 实现。 由于这些命令是虚拟的,因此标准 CView 实现不需要链接整个 CSplitterWnd 实现。 对于使用CView但不使用CSplitterWnd的应用程序,CSplitterWnd实现将不会与应用程序链接。

  • virtual BOOL CanActivateNext(BOOL bPrev = FALSE);

    检查 ID_NEXT_PANE 或 ID_PREV_PANE 当前是否可行。

  • virtual void ActivateNext(BOOL bPrev = FALSE);

    执行“下一窗格”或“上一窗格”命令。

  • virtual BOOL DoKeyboardSplit();

    执行键盘拆分命令,通常为“窗口拆分”。

另请参阅

按编号列出的技术说明
按类别列出的技术说明