基于MFC SDI的视图分割实现方案

一、理论知识

先简单归纳一下MFC SDI程序架(Frame),视图(View),文档(Doc)之间的关系。

创建MFC SDI程序后我们可以看到建立的工程里生成了Doc类、View类和MainFrame类,它们就分别是文档类、视图类和框架窗口类。

文档/视图结构是MFC提供的一种不错的设计,它将数据的处理和显示分开来,这样更便于我们对程序的维护和扩展。

文档:文档对象用于管理和维护数据,包括保存数据、取出数据以及修改数据等操作,在数据被修改以后,文档可以通知其对应的所有视图更新显示。

视图:视图对象将文档中的数据可视化,负责从文档对象中取出数据显示给用户,并接受用户的输入和编辑,将数据的改变反映给文档对象。视图充当了文档和用户之间媒介的角色。

框架:一个文档可能有多个视图界面,这就需要有框架来管理了。框架就是用来管理文档和视图的。框架窗口是应用程序的主窗口,应用程序执行时会先创建一个最顶层的框架窗口。视图窗口是没有菜单和边界的子窗口,它必须包含在框架窗口中,即置于框架窗口的客户区内。

文档和视图是一对多的关系。一个文档可以对应多个视图,例如在Word中一个文档有普通视图、大纲视图、Web版式视图、阅读版式视图等多种视图。而一个视图只能属于一个文档。最简单的应用程序是单文档单视图程序,除此之外还有单文档多视图程序、多文档程序等。

二、视图分割

就是将一个窗口分割成多个窗格,在每个窗格中都包含有视图。MFC中的分割窗口类---CSplitterWnd类提供了分割窗口的功能。

MFC分割窗口的方式有两种,动态分割和静态分割。这里主要介绍一下静态分割的实现方案。

静态分割窗口比较常见,我们经常能看到某个软件打开后,界面窗口默认被分割成了几个窗格,这就是静态分割窗口。静态分割窗口最多支持16行16列。通常静态分割窗口的每个窗格中包含不同类的视图,当然也可以是同一类的视图。

需求:

将View视图进行分割,共3块区域,左边一块(原View区),右边分上下两块(都是Dialog形式的View)。

2.1 在MainFrm.h文件中为CMainFrame类添加成员对象:

CSplitterWnd m_wndSplitter1;
CSplitterWnd m_wndSplitter2;

2.2 在CMainFrame类中添加一个函数OnCreateClient,在这个函数下面实现。

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
         // TODO: 在此添加专用代码和/或调用基类      
         BOOL bResult = m_wndSplitter1.CreateStatic(this, 1, 2);
         ASSERT(bResult);
         m_wndSplitter2.CreateStatic(&m_wndSplitter1, 2, 1, WS_CHILD | WS_VISIBLE, m_wndSplitter1.IdFromRowCol(0, 1));

         CRect rc;
         GetClientRect(&rc);
         m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(CFormLeft), CSize(rc.Width() / 4, rc.Height() * 3 / 5), pContext);
         m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(CFormRight), CSize(rc.Width() / 4, rc.Height() * 2 / 5), pContext);
         m_wndSplitter1.CreateView(0, 0, RUNTIME_CLASS(CMFCSpiltSDIView), CSize(rc.Width() * 3 / 4, rc.Height()), pContext);

         //设置窗格的初始化的大小
         m_wndSplitter1.SetColumnInfo(0, (int)(rc.Width() / 4), 10);
         m_wndSplitter2.SetRowInfo(0, (int)(rc.Height() * 3 / 5), 10);
         m_bCreateSplitter = TRUE;
         //激活sceneview使得其可以接受命令消息
         m_wndSplitter2.SetActivePane(0, 0, NULL);        
         //return CFrameWndEx::OnCreateClient(lpcs, pContext);
         return TRUE;

}

2.3 在添加了这个函数之后你想看一下分割效果,可能会中断,大概是找不到什么句柄。就这么个问题会让一个初学者半天摸不着头脑。其实深入理解就可以发现问题,因为静态分割时的显示的类是用户自定义的View,也就是说不能光分割,还必须给分割后的各个模块添加View(例如 下面的CFormLeft,CFormRight )。这里顺便简单介绍几种常用的视图:CScrollView(滚动视图)、CEditView(文本编辑视图)、CFormView(对话框视图)、CListView(列表视图)、CTreeView(树形视图等),这些视图都是从CView中派生而来的。实例采用的是CFormView视图,因为要用作“操作面板”,该视图创建后即跟对话框程序差不多,直接在上面添加控件就好,十分方便。所以子视图如果要用作操作面板的,一般要使用CFormView。说明一下,这个CFormLeft实现上 可以新建对话框,对对话框添加使用类向导,绑定实现类,最后在继承窗体的时候改一下基类,改为CFormView。

2.4 接下来就可以在这些View上添加控件了,甚至还可以添加一个Dialog。为了美观,设置均分窗口,且没有滚动条,且可以等比例缩放。原理就是在MainFrame里添加ON_WM_SIZE消息,并编写OnSize函数。感觉MFC创建窗口需要一定时间,而ON_WM_SIZE的响应还是很快的,会导致获得不到窗口句柄而中断。

void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
         CFrameWndEx::OnSize(nType, cx, cy);
         CRect rect;
         GetClientRect(&rect);
         if (m_bCreateSplitter)
         {

                   m_wndSplitter1.SetColumnInfo(0, (int)(rect.Width() / 4), 10);

                   m_wndSplitter1.SetColumnInfo(1, rect.Width() * 3 / 4, 10);

                   m_wndSplitter2.SetRowInfo(0, (int)(rect.Height() * 3 / 5), 10);

                   m_wndSplitter2.SetRowInfo(1, rect.Height() * 2 / 5, 10);

                   m_wndSplitter1.RecalcLayout();

                   m_wndSplitter2.RecalcLayout();

         }

}

运行程序,效果图如下,

下载地址

 

MFC SDI SplitView Sample是一个使用MFC框架开发的单文档界面(single document interface, SDI)应用程序示例。SDI是一种应用程序界面设计模式,其中每个文档在应用程序窗口中有一个单独的视图。 在MFC SDI SplitView Sample中,应用程序窗口被分割为两个区域,分别显示不同的视图。通常情况下,一个视图用于展示文档的内容,另一个视图用于显示相关的信息或者窗口控制操作。 这个示例程序演示了如何有效地管理和组织不同的视图,并实现视图之间的交互。通过使用切分视图技术,用户可以同时查看和编辑多个视图中的内容,从而提高了应用程序的功能和效率。 具体来说,MFC SDI SplitView Sample包含了以下关键组件和功能: 1. 主视图:用于展示主要内容,例如文本编辑区域或图形绘制区域。 2. 副视图:用于展示附加信息或者窗口控制操作,例如属性编辑器或者工具栏。 3. 分割器(Splitter):用于将应用程序窗口分割为不同的视图区域,用户可以自由调整这些区域的大小和位置。 4. 文档类(Document Class):负责管理数据和操作文档数据的类,例如打开、保存和修改文档内容等。 5. 视图类(View Class):负责将数据呈现给用户并处理用户的输入,例如响应鼠标点击事件或者键盘输入事件等。 总而言之,MFC SDI SplitView Sample展示了如何使用MFC框架实现一个灵活多视图的单文档界面应用程序,给予用户更好的用户体验和工作效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

法哥2012

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值