分割窗口教程






4.43/5 (68投票s)
2003年1月14日
4分钟阅读

358378

12547
在 MFC SDI 应用程序中实现 CSplitterWnd 控件
引言
本文旨在涵盖使用默认 MFC CSplitterWnd
对象的基础知识。我花了很长时间寻找关于使用这些对象的入门介绍,但只找到了子类或经过改编的 CSplitterWnd
教程。我希望这篇文章能帮助那些和我一样,只是想对这个基本对象有一个初步了解的人。
背景
CSplitterWnd
或分割器窗口是一种将屏幕分割成两个或多个不同窗格的方法(请参阅截图或 3D 编辑器等应用程序)。窗格本身通常填充有 CView
或 CWnd
派生对象,以提供文档的不同视图(或用户界面功能)。
分割器窗口有两种形式:静态和动态。本教程仅涵盖静态分割器,因为动态分割器稍微复杂一些。两者的主要区别在于,动态分割器可以由用户分割和折叠,而静态分割器则不能。
Using the Code
步骤 1 - 声明数据
使用 AppWizard
创建一个支持文档/视图的新单文档应用程序。在主框架的头文件中添加一个 CSplitterWnd
对象和一个用于分割器管理的布尔标志。
CSplitterWnd m_mainSplitter;
BOOL m_bInitSplitter;
m_mainSplitter
将用于将窗口分割成两个窗格,如上图所示。该布尔标志将用于在管理大小调整之前检查分割器是否已设置。确保在主框架类的构造函数中,将布尔值初始化为 FALSE
。
步骤 2 - 创建分割器
分割器窗口应在主框架窗口客户区的初始化期间创建。在主框架类中为 OnCreateClient
消息添加一个函数,并插入以下分割器创建代码:
//calculate client size
CRect cr;
GetClientRect( &cr);
if ( !m_mainSplitter.CreateStatic( this, 1, 2 ) )
{
MessageBox( "Error setting up splitter frames!",
"Init Error!", MB_OK | MB_ICONERROR );
return FALSE;
}
CreateStatic()
的参数是父窗口(this
)以及行数和列数。获取客户区矩形的大小以便后续进行尺寸调整。
步骤 3 - 创建视图
分割器中的每个窗格,除非嵌套有另一个分割器,否则在显示之前必须附加一个视图。调用 CreateStatic
后,使用以下代码为窗格创建默认视图。请注意,分割器中的每一列都必须有一个视图,因为它没有嵌套的分割器。这给我带来了很多问题(对视图的要求的理解),所以花一些时间查看各种代码示例以获得更深入的理解。然后将布尔标志更新为 TRUE
,以指示分割器已创建。
if ( !m_mainSplitter.CreateView( 0, 0,
RUNTIME_CLASS(CSplitterWindowTutorialView),
CSize(cr.Width()/2, cr.Height()), pContext ) )
{
MessageBox( "Error setting up splitter frames!",
"Init Error!", MB_OK | MB_ICONERROR );
return FALSE;
}
if ( !m_mainSplitter.CreateView( 0, 1,
RUNTIME_CLASS(CSplitterWindowTutorialView),
CSize(cr.Width()/2, cr.Height()), pContext ) )
{
MessageBox( "Error setting up splitter frames!",
"Init Error!", MB_OK | MB_ICONERROR );
return FALSE;
}
m_bInitSplitter = TRUE;
要使用 RUNTIME_CLASS(CSplitterWindowTutorialView)
,您必须在 MainFrm.cpp 中包含您的视图类头文件,并在视图类头文件中包含您的文档类,就在
#endif // _MSC_VER > 1000.
这将允许您在主框架类中使用您的视图类。如果您不在视图类头文件中包含您的文档类,则会遇到很多问题 - 这是另一个需要注意的地方!
步骤 4 - 替换返回值
替换
return CFrameWnd::OnCreateClient(lpcs, pContext);
用
return TRUE;
现有代码的默认返回值将不会显示我们的工作,因为它将默认方法返回给框架窗口。
步骤 5 - 管理大小调整
SetRowInfo
和 SetColumnInfo
负责管理分割器的大小。添加一个 WM_ONSIZE
消息的处理程序,并添加以下代码:
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
CRect cr;
GetWindowRect(&cr);
if ( m_bInitSplitter && nType != SIZE_MINIMIZED )
{
m_mainSplitter.SetRowInfo( 0, cy, 0 );
m_mainSplitter.SetColumnInfo( 0, cr.Width() / 2, 50);
m_mainSplitter.SetColumnInfo( 1, cr.Width() / 2, 50);
m_mainSplitter.RecalcLayout();
}
}
在上面的代码中,我们首先通过检查布尔值来确保分割器已初始化。此检查是必需的,因为我认为在创建方法运行之前,WM_SIZE
消息会传递给框架 - 因此,代码首次运行时对象将不存在,如果您不检查它的存在,就会崩溃。
现在应用程序应该可以运行了,并且会显示一些类似于文章开头截图的内容!我可能会在系列文章中添加第二篇,介绍如何添加更深入的嵌套分割器和其他基于表单的视图!敬请期待...
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。