MFC多文档分割窗口

MFC多文档分割窗口

一、MFC多文档结构

MFC多文档结构是一种面向对象的设计模式,用于创建支持多个文档窗口的应用程序。它主要由以下几个类组成:

1. CWinApp:应用程序对象,管理整个应用程序的生命周期。

2. CDocTemplate:文档模板对象,负责创建新的文档和视图对象,并将它们关联起来。

3. CDocument:文档对象,代表应用程序中的一个文档,负责打开、保存和关闭文件等操作。

4. CView:视图对象,代表一个文档窗口中显示的内容,负责处理用户界面和用户交互。

5. CMDIChildWnd:MDI子窗口对象,代表多文档界面中的一个子窗口(通常是一个文档窗口),由用户控制打开、关闭、移动和调整大小等操作。

6. CMDIFrameWnd:MDI主窗口对象,代表多文档界面中的主窗口,包含菜单栏、工具栏、状态栏等用户界面元素。

以上类通过继承和组合相互关联,并协同完成整个MFC多文档应用程序的运行。

二、多文档结构窗口的分割

静态拆分窗口

静态拆分窗口是用 CSplitterWnd::CreateStatic 创建的,但是MVC不会自动创建静态拆分窗口中显示的视图,所以需要亲自在 CreateStatic 返回之后创建视图。 CSplitterWnd提供了名为 CreateView 的函数。

静态拆分窗口的流程

  1. 给框架窗口类中添加一个 CSplitterWnd 数据成员
    (提示:在多文档窗口中只能对MainFrm的ChildFrm进行拆分,如果对MainFrm拆分,会发生中断,原因不详)

    在ChildFrm.h 文件中定义分割窗口的成员变量
    image-20230331111110751

  2. Override框架窗口的 OnCreateClient 函数

    打开类视图

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GlladHC8-1681348282498)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230331111110751.png)]

    右击ChildFrm,点击属性,点击重写按钮
    在这里插入图片描述

    找到OnCreateClient 函数并添加,会自动添加在childFrm.cpp里

    删除自动创建的OnCreateClient内的所有代码,返回值改为 TRUE;
    在这里插入图片描述

  3. 调用 CSplitterWnd::CreateStatic 来创建静态拆分窗口

    //先把窗口分割为1行2列的形式,即分割为两列	
    m_wndSplitter.CreateStatic(this,1, 2 , WS_CHILD | WS_VISIBLE| WS_BORDER);
    

    (拆分过的窗口内是没有view视图的)

  4. 使用 CSplitterWnd::CreateView 在每个静态拆分窗口中创建视图

    	//两个窗口填充同样的内容
    	if(!m_splitter.CreateView(0, 0, RUNTIME_CLASS(CMyView), CSize(1000, 0), pContext))
    		return FALSE;
        if (!m_splitter.CreateView(0, 1, RUNTIME_CLASS(CMyView), CSize(0, 0), pContext))
            return FALSE;
    

    第一个参数为行数,第二个参数是列数,第三个参数填写RUNTIME_CLASS,第四个参数为CSize(窗口大小)

    RUNTIME_CLASS的定义如下:

    #define RUNTIME_CLASS(class_name) ( class_name::GetThisClass() )
    

    注意:RUNTIME_CLASS内的参数必须是一个CView或者他的子类

    上述代码中MyView是我自定义的一个类,继承于CView

    在解决资源管理器中,右键点击 “ 头文件 ” ,然后点击类向导

在这里插入图片描述

点击添加类

基类选择CView

在这里插入图片描述

点击完成,然后点击应用、确定。此时一个CView类的派生类已经创建完成

在分割后的窗口上填入相应的视图,此时分割窗口以及完成

在这里插入图片描述

编译运行

在这里插入图片描述

以上就是一个静态拆分窗口的例程

三、在视图类里添加一个Dialog

经过上述流程,此时用CMyView作为分割窗口的视图窗口,但是CMyView内并没有Dialog,此时我们需要新建一个Dialog的类,把他放到MyView中

右键头文件,点击类向导

添加一个类,基类为CDialogEx

在这里插入图片描述

在资源管理器中找到该例程的rc文件并打开

选择刚刚创建的dialog的IDD

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4IM888X4-1681348282499)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230412174841248.png)]

此时右侧会弹出一个对话框,可以在工具箱内添加相应的控件,之间拖进来即可

右击dialog,将此dialog的样式改为child,因为此时我们的dialog是需要内嵌在MyView中的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qrNcjbcE-1681348282500)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230412180040931.png)]

将Visible设置为可见的(TRUE)

一个对话框类就此已经添加完成了,然后我们需要将这个对话框放到刚才创建的MyView里

在MyView.h中声明这个对话框类的指针

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jwLwBLfy-1681348282500)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230412175422033.png)]

按照此前重写ChildFrm的OnCreateClient函数的方法,重写MyView的Create函数,然后在Create中初始化 m_dialog
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lxpx5mW8-1681348282500)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230412175629906.png)]

BOOL CMyView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
	// TODO: 在此添加专用代码和/或调用基类
	if(!CView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext))
	{
		return FALSE;
	}

	//实例化dialog对象
	m_dialog = new MyDialog(this);

	//创建dialog
	m_dialog->Create(IDD_MYDIALOG,this);
	//m_dialog->DoModal();
}

此时分割窗口内填充的是MyView视图,MyView内有个MyDialog

编译运行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xcMExCFW-1681348282500)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230412181104772.png)]

四、在MyDialog中添加一个CPropertySheet

CPropertySheet类对象表示属性表,或者说是标签对话框。一个属性表由一个CPropertySheet对象和一个或多个CPropertyPage对象构成。一个属性表由框架来显示,就象是一个具有一系列标签索引的窗口。用户通过这些标签索引来选择当前的页,和一块用于当前所选页的区域。

添加一个CPropertySheet类的子类,方便实现自己的内容

右键头文件,点击类向导,点击添加一个类,基类为CPropertySheet

然后在新建两个CPropertyPage类(可以是N个)


在这里插入图片描述

打开CMyPropertySheet.h文件,在类内添加两个属性页成员变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iFaYR5ck-1681348282501)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230412184551150.png)]

打开CMyPropertySheet.cpp文件,在两个构造函数中,利用AddPage函数将属性页添加到属性表中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nZ8laaza-1681348282501)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230412184725263.png)]

此时属性表类以及创建完成

接下来需要将属性表添加到MyDialog中

在MyDialog内,将CMyPropertySheet的指针添加为成员变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-58TjaVf2-1681348282501)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230412185130372.png)]

然后打开类视图,重写CMyDialog::OnInitDialog()函数

BOOL CMyDialog::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	sheet = new CMyPropertySheet(_T("My Property Sheet"), this);
	sheet->Create(this, WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0);

	//获取客户端窗口大小
	CRect rect;
	GetDesktopWindow()->GetWindowRect(&rect);
	//将dialog移动到窗口内
	MoveWindow(rect);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}

此时以及将CMyPropertySheet添加进入MyDialog了,编译运行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BGE86AX3-1681348282501)(C:\Users\ShangJianyu\AppData\Roaming\Typora\typora-user-images\image-20230412185422025.png)]

可以看到,除了之前我们添加过的控件以外,CMyPropertySheet也显示到MyDialog内了

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MFC (Microsoft Foundation Class)是一种用于Windows平台的应用程序开发框架,它提供了一套面向对象的类库,可以简化Windows应用程序的开发过程。多文档多视图是MFC框架中的一种常见应用模式,它允许用户同时打开多个文档,并在多个视图中显示这些文档的不同部分。 在MFC中,实现多文档多视图应用最关键的是建立一个文档类(CDocument)和至少一个视图类(CView)。文档类用于管理文档的数据和状态,而视图类则用于显示文档的内容,可以有不同类型的视图类对应不同的展示方式。通常情况下,一个应用程序可以有多个文档对象,每个文档对象可以对应多个视图对象。 在源代码中,可以通过继承MFC框架提供的基础类来实现文档类和视图类。文档类必须继承自CDocument类,并且需要重写其中的一些虚函数来处理文档的打开、保存、关闭等操作。视图类则需要继承自CView类,并且需要重写其中的一些虚函数来处理显示文档内容、用户交互等操作。在视图类中,通常需要处理绘图相关的操作,通过GDI(图形设备接口)来绘制文档内容。 在主应用程序中,还需要建立一个框架窗口类(CFrameWnd)来容纳多个视图对象。框架窗口类也需要继承自MFC框架提供的基础类,并在其中创建和管理文档对象和视图对象。用户可以通过菜单、工具栏等交互方式来打开、关闭、保存文档,以及在视图中进行操作。 总的来说,实现MFC文档多视图应用的源代码需要建立文档类、视图类和框架窗口类,并通过继承MFC框架提供的基础类来实现文档管理和视图显示的功能。通过合理的设计和编码,可以实现一个灵活、可扩展的多文档多视图应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shang_Jianyu_ss

感谢大哥

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值