基于单文档的(MFC)窗口分割

合集下载

MFC如何在文档(CXXXDoc)类或框架(CMainFrame)类中获得视类(CMyView)指针

MFC如何在文档(CXXXDoc)类或框架(CMainFrame)类中获得视类(CMyView)指针
CDocument对象 视列表 GetFirstViewPosition,GetNextView
文档模板 GetDocTemplate
CView 对象 文档对象 GetDocument
边框窗口 GetParentFrame
如何在OnDraw函数或***Dlg函数中获得View类的指针(this)或整个对话框的指针?
在单文档中你可以采用如下方法:
现在要获得指针的文件开始处包含两个文件:
视图的主框架类头文件,即#include "MainFrm.h"
视图类头文件,即#include "XXView.h"
在CDocument类中,调用GetFirstViewPosition()和GetNextView()得到所有的view。
在其它类中,一种方法先是把指针传进去,以备调用的时候使用。另外就要用AfxGetApp()得到CWinApp,然后再用GetFirstDocTemplatePosition()和GetNextDocTemplate()得到doc template,然后调用GetFirstDocPosition()和GetNextDoc()得到doc。
在文档类中(CMainFrame*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
MFC中怎么在CMainFrame下获得View类的指针
使用GetActiveView()函数
MFC中普通类如何获取view类的指针?
在普通类(Generic class)中怎么得到view类的指针?我试过这样:
然后在要访问m_pSet处添加如下语句
CMainFrame* frm=(CMainFrame*)AfxGetApp()->m_pMainWnd;

MFC学习笔记-窗口创建

MFC学习笔记-窗口创建

MFChierarchy chart(类库列表)MFC与Win321 win32:函数,使用API一步一步搭建应用程序。

(常使用FileView操作)2 MFC编程:实现仍然调用API函数,但是是用类封装API函数,使用向导自动生成应用程序框架。

(常使用ClassView操作)2.1需要掌握的技能2.1.1断点调试2.1.2堆栈调用的查看MFC课程内容1 MFC:MFC的六大机制,文档式架构,常用的MFC类,(10--12)。

2 COM(组件对象模型):COM的原理和应用(6)。

3 ADO/Socket:MFC访问数据库以及一些简单的网络编程。

MFC应用程序编程1 MFC的历史:92(VC1)98(VC6)……………………….2 MFC库基础:2.1 MFC库,微软基础类库。

封装了Windows应用程序编程的各种API以及相关机制的C++类库3 类库的相关头文件件★afx-application framework(应用程序框架x)3.1<stdafx.h>-不是类库头文件,是项目的头文件,称为VC下编译的预编译头文件,用来提高编译速度的。

(*.pch)(头文件是不参加编译的但是他参与生成*.pch)3.2<afxwin.h>-几乎包含了各种常用的MFC有文件3.3 <afxext.h>-提供扩展窗口类的支持(创建工具栏,状态栏等………)MFC应用程序的类型1 支持MFC的控制台应用程序(控制台的第四个选项)1.1 多了一个CWinApp(应用程序类,封装类应用程序启动过沉重所涉及到得相关信息)的全局对象(必须有,而且只能有一个)1.2主函数中多了一个AfxWinInit函数,初始化MFC库中的相关信息2 MFC库程序2.1 MFC支持的静态库2.2 MFC支持的动态库2.2.1 MFC规则库(shared MFC DLL)-可以被各种应用程序调用(非MFC程序,没有MFC类也可以调用)★还是有一个CWinApp派生的CMFC_DLLApp类对象2.2.2 MFC扩展库(using shared MFC DLL)-只能被MFC库所编写的应用程序所调用(对原有的MFC类扩展)★DllMain主函数只能被MFC程序调用3 MFC应用程序-----(注意看父类,子类名字可能不一样)3.1单文档视图应用程序★CWinApp 应用程序类★CAboutDlg(对话框-生成关于窗口-和框架没有任何关系)★CMainFrame(父类是:CFrameWnd)(应用程序主框架窗口类-生成应用程序的主框架-负责各个对象的协调工作)★CDocument(它是父类)(文档类-看不到的很重要-管理数据)★CView(它是父类)(视图类-显示数据并和用户进行交互)★CSingleDocApp(父类是CWinApp)-(使用前面的3个类来创建对象)3.2多文档视图架构★CWinApp 应用程序类★CAboutDlg(对话框-生成关于窗口-和框架没有任何关系)★CView(它是父类)(视图类-显示数据并和用户进行交互)★CDocument(它是父类)(文档类-看不到的很重要-管理数据)★CMDIChildWnd(子框架窗口类,父类)★CMDIFrameWnd(主框架窗口类,父类)我们看到的子窗体其实是★CView和★CMDIChildWnd叠加的3.3基于对话框的应用程序★CWinApp 应用程序类★CDialog(对话框窗口类)★★m_pMainWnd保存主窗口地址DoModal 显示对话框MFC相关类的说明1继承自CObject1.1 CObject类:绝大多数MFC类的父类,提供了MFC库的一些机制1 new/delete操作符,定义了与构造函数相关的内存分配函数2 assert和dump调试,堆调试的支持★3 运行时类信息-属于哪个类,还有类的层次结构★4 动态创建★5 序列化1.2 CWinThread: 线程类。

mfc入门单文档MFC应用程序实例-图文

mfc入门单文档MFC应用程序实例-图文

mfc入门单文档MFC应用程序实例-图文14单文档MFC应用程序实例
对话框应用程序使用简洁高教,所以被广泛地使用。

对话框在默认情
况下缺少状态栏、f具栏等界面元素,不能算作是。

完整”的Wwbn应用
程序。

RIUt/Clllr面,可以看作是“标准”的Windown应用程序再面。

1.41技术要点
’MFC的单文档应用程序结构的一大特点是教据和界面分N,在单文
档应用程序中,程序中数据的保存、加藏和处理等功糖由CDocumtI完戚,而数据的显示由cV.州来完成a这种结构又被称为“文彬视田”结构,
在这种结构下.很容器做刊数据和界面的一对多关联。

‘MFC中提供T众多派生于CView的弦生类,每个类都翻IT同的功能,在新建项目时,可以根据蜜际需謇选样不同的根生类。

142实例步骤奉实棚将以CFonnView为例,演示在ViualC++60中新建单文档项目
的鼻体方法。

实例步骤如下所示。

(I)打开ViualC++6.0.单击。

File”/“N州‘菜单。

在弹出对话摧
中选择项目类撼为“MFCAppWiurd(e某e)1.在项目名称文本框中输
A“NffcSdi”,单击“OK-MHE入向导界面。

(2)在向导的Skpl中,选择“Sinlledoeummt“,其余琏项用默认值(参麒1:919)。

单击“Ne某t”按钮进人下一步。

(”向导的Step2.用于设置是否在程序中自动加A对散据库的支持,此步鼻对默认设置不做改动(参照图iIO),直接单击“Ne某r按钮进
AT一步。

如何在MFC单文档中创建多视图

如何在MFC单文档中创建多视图

u 一个文档可以有多个视图,由Document中成员变量CPtrList m_ViewList维护。
u CFrameWnd拥有一个成员变量CView* m_pActiveView指向当前活动的View。
u CView中拥有一个成员变量CDocument* m_pDocument指向该视图相关的Document。
!m_wndSplitter2.CreateView(1, 0, RUNTIME_CLASS(BottomLView), CSize(350, 240), pContext) ||
!m_wndSplitter2.CreateView(0, 1, RUNTIME_CLASS(TopRView), CSize(350, 240), pContext) ||
/wang_qingyuan/blog/item/60870400275c5b087bec2cbd.html
深入分析MFC文档视图结构
2008-10-16 19:40
文档视图结构(Document/View Architecture)是MFC的精髓,也是Observer模式的具体实现框架之一,Document/View Architecture通过将数据和其表示分开,提供了很好的数据层次和表现层次的解耦。然而,虽然我们使用MFC AppWizard就可以很轻松地获得一个支持Document/View Architecture的MFC程序框架,Document/View Architecture本身的复杂性加上VC产生的一系列代码足够让我们眼花缭乱,一时陷入云里雾里不可自拔。加上我们更多的人都没有经过Windows SDK Programming 的学习和经历就直接进行MFC Programming的学习和开发,更是面对一堆的代码不知所措。

MFC实验六 文档视图和单文档界面

MFC实验六 文档视图和单文档界面

实验六文档/视图和单文档界面1.创建一个单文档界面应用程序,项目名设置为wx03.2.在文档类CWx03Doc中添加数据成员用于保存应用程序的数据。

二维数组m_clrGrid用于保存每个方格的颜色,数据成员m_clrCurrentColor用于保存方格被单击时赋给方格的颜色。

3.在文档类CWx03Doc的OnNewDocument函数中对数据成员进行初始化:4.向类wx03Doc添加三个成员函数,如下:函数定义如下:GetCurrentColor、GetSquare和SetSquare作为文档和视图之间的桥梁,视图对象通过它们可以访问文档的保护成员。

5.编辑CWx03View的OnDraw函数,在视图窗口中绘制网格,并根据文档类中保存的方格颜色来设置方格的颜色。

6.在视图类CWx03View中添加消息处理函数WM_LBUTTONDOWN的处理函数:7.利用菜单编辑器编辑个添加如下菜单,各菜单的属性设置如下表:8.9.为添加的菜单项添加命令消息处理函数和用户界面更新命令处理函数。

由于这些函数都是针对文档数据的操作,因此将这些菜单命令的消息处理函数添加在文档类中。

10.编译、链接和运行程序,结果如下:11.添加序列化功能,将各个方格的颜色以及当前颜色存入文件,并允许从文件中读取。

12.编写一个SDI程序,可以用鼠标在视图窗口中划线,并能将所画的线条保存。

13.定义一个新类Cline。

14.编辑类Cline,在其中添加相应的数据成员和成员函数。

15.在文档类中添加保存线段的数组。

在头文件wx03Doc.h中添加如下的数据成员和成员函数,并包含定义类Cline的头文件和使用MFC模板类时需要的头文件:在文档类的实现文件中编写添加的成员函数:16.当在视图窗口中按下鼠标右键时开始画线,鼠标右键抬起时完成线段的绘制,在鼠标移动的过程中画橡皮筋线。

因此需要记录划线的起点和终点并设置画橡皮筋线的跟踪标志。

画橡皮筋线时,需要将原来的线条删除,重新画一条从起点到当前鼠标指针坐标的线条,最简单的办法是使用R2_NOT绘图模式反转线条。

静态分割窗口与多视图实例

静态分割窗口与多视图实例

静态分割窗口与多视图实例所谓多视,是指在同一个框架窗口下同时显示多个视图。

通过运用这种技术,可以在框架的有限的空间内同时提供给用户更大的信息量,并且使得用户界面更加的友好,增强了软件的可操作性。

窗口分割的基本概念按照分割的时机的不同,窗口分割可以分为两类:动态分割和静态分割。

动态分割是指用户可以动态的分割和合并窗口。

动态分割最多可以有2行2列个窗口,并且所有的窗格只能使用同一种视图类。

静态分割是指窗口在创建时,分割窗格窗口的窗格已经创建好了,且窗格的数量和顺序不会改变了,窗格为一个分隔条所分割,用户可以拖动分割条调整相应的窗格的大小。

静态分割窗口最多可以有16行16列的窗格,但是各个窗格可以使用不同的视图类。

无论创建那一种分割,都必须在创建时指定最大的行数和列数,这些值是有CSplitterWnd 对象进行管理。

对于静态分割,必须创建指定数目的所有窗格以填满行和列。

而对于动态分割,第一个窗格将在框架创建CSplitterWnd对象时自动创建。

窗口分割支持类CSplitterWndCSplitterWnd类主要为窗口的风格提供了封装,窗口被分厂各个窗格后,又该类的对象负责管理。

对于windows而言,CSplitterWnd是一个真正的窗口,它完全占据了框架窗口的用户区域,而视图则占据了分割窗口的床片区域。

CSplitterWnd窗口不参与命令传递机制。

使用时,CSplitterWnd对象通常为其父框架窗口CFrameWnd或CMDIChildWnd(MID应用中)对象的内嵌成员。

CSplitterWnd对象创建过程如下。

在父框架窗口中嵌入CSplitterWnd类的对象成员;重载父框架窗口的CFrameWnd::OnCreateClient成员函数;从上一步重载的函数内部调用Create创建动态分割窗口或者调用CreateStatic创建静态的分割窗口。

下面介绍CsplitterWnd类的几个常用的函数创建动态分割窗口函数Create该函数用于动态创建分割窗口,同时将该窗口与类CSplitterWnd相关联,其生声明如下:BOOL Create(CWnd* pParentWnd, int nMaxRows, int MaxCol, SIZE sizeMin, CcreateContext* pContext, DOWRD dwStyle = WS_CHILD |WS_VISIBLE | WS_HSCROLL | WSVSCROLL | SPLS_DYNAMIC_SPLIT,UINT nID=AFX_IDW_PANE_FIRST);各主要参数的含义如下:pParentWnd:分割窗口的父框架窗口的指针nMaxRows和你MaxCols:行与列的最大值,二者均不大于二sizeMin:指定窗格被显示时的最小值。

MFC的窗口分割实例以及CSplitterWnd类

MFC的窗口分割实例以及CSplitterWnd类
在 MFC 的框架下,文档对象(CDocument)有一个保存其所有视图的列表,并提供了 增加视图(AddView)与删除视图(RemoveView)函数,以及当文档内容改变时通知其所 有视图的方法(UpdateAllViews)。通过多文档框架的窗口复制机制和单文档框架的分割窗 口机制是实现单文档多视图的主要方法。
3 分割窗口ቤተ መጻሕፍቲ ባይዱ
如图 1,把窗口分成三个视图,左视图基于 CView 类,可用来作几何图形;右上视图基 于 CEditView 类,用于显示文本消息;右下视图基于 CFormView 类,在此视图中做一个文 本框及发送、清除按钮,发送按钮用来向右上视图传送消息。
图 1 设计样式 打开 Microsoft VC++ 6.0,通过 MFC AppWizard(exe)新建名为 SplitWnd 的单文档(SDI) 工程,新建工程时所有选项均按默认设定。 工程建好后,把工程中的 CSplitWndView 视图类作为左视图所对应的类(该类的实现 与本文重点无关,故不阐述,有兴趣读者可与作者联系),由于需要三个视图窗口对应三个
视图类,因此需要手动创建右上视图、右下视图对应的类,可以通过 MFC 向导向应用程序 添加两个 MFC 类(菜单“Insert | New Class>”),因为在右上视图用于显示文本,故其基类选 CEditView,类名为 CLeftTopView;另一个 MFC 类的基类选 CFormView 类,取类名为 CLeftBttmView,该类即对应右下视图(由于该类基于 CFormView 类,需要有对话框与之对 应,故应先在资源中新建对话框,对话框中的控件如图 1)。
void CLeftBttmView::OnSendMsg() { UpdateData();//更新控件变量数据,文本框对应的变量为 m_sText //通过 CMainFrame 类中的 m_wndSplitterRight 变量获得右上视图类指针 CMainFrame * pMainFrm = (CMainFrame *)AfxGetApp()->GetMainWnd(); CWnd * pWnd = pMainFrm->m_wndSplitterRight.GetPane(0, 0); CLeftTopView* pLeftTopView = DYNAMIC_DOWNCAST(CLeftTopView, pWnd); pLeftTopView ->GetMsg( m_sText + "\r\n" );//CLeftTopView 成员函数,接收数据 } 右上视图类 CLeftTopView 的成员函数 GetMsg 则需保存接收到的消息并显示,主要代 码如下: void CLeftTopView::GetMsg(CString sMsg) { m_sAllMsg += sMsg; // m_sAllMsg 为成员变量,记录所有消息 int nTextLen = GetWindowTextLength(); GetEditCtrl().SetSel(nTextLen, nTextLen); GetEditCtrl().ReplaceSel( sMsg );//显示新消息 } 有了上面两个函数就可以实现右上视图类 CLeftTopView 与右上视图类 CLeftBttmView 之间的简单通讯,类似地,可以实现所有视图之间任意的数据传递。

MFC单文档窗体类的创建过程

MFC单文档窗体类的创建过程

MFC单文档窗体类的创建过程MFC(Microsoft Foundation Classes)是微软公司提供的一种面向对象的程序开发工具,用于简化Windows操作系统的应用程序开发。

MFC 提供了丰富的类库和框架,使开发人员能够更快速地创建Windows程序。

在MFC中,窗体类是常用的一种类,用于创建窗体应用程序。

本文将详细介绍MFC单文档窗体类的创建过程。

在MFC中,创建单文档窗体类的过程可以分为以下几个步骤:1.创建一个新的MFC应用程序项目首先,需要使用MFC应用程序向导创建一个新的MFC应用程序项目。

打开Visual Studio,选择“文件”->“新建”->“项目”,在“新建项目”对话框中选择“Visual C++”->“MFC”->“MFC应用程序”,并填写项目名称和保存路径,点击“确定”按钮。

接下来,按照向导的指引,选择“单文档”应用程序类型,并点击“完成”按钮。

2.添加对话框资源在MFC应用程序项目创建完成后,需要添加对话框资源。

在资源视图中,选择“添加”->“资源”->“对话框”,在弹出的对话框中输入对话框名称,并点击“确定”按钮。

此时,会自动生成一个对话框资源,可以在其中添加所需的控件。

3.创建窗体类在MFC应用程序项目中,会自动生成一个CWinApp类和一个CMainFrame类。

我们需要创建一个新的窗体类,用于承载对话框资源。

在Solution Explorer中,右击“源文件”->“添加”->“类”,在弹出的“添加类”对话框中选择“MFC”->“MFC类”->“单文档视图”,并填写类名称和保存路径,点击“添加”按钮。

此时,会自动生成一个新的窗体类,可以在其中添加处理逻辑。

4.修改窗体类代码打开新生成的窗体类的头文件和源文件,可以看到自动生成的代码。

在头文件中,需要包含所需的头文件,并声明成员变量和成员函数。

在源文件中,需要实现窗体类的构造函数、析构函数和其他成员函数。

在View类中创建分割多视

在View类中创建分割多视

本文在介绍了几种标准的单文档与多视结构的VC5.0 MFC实现方法之后,介绍了笔者摸索出的另外两种实用方法,并给出了实现它们的的主要程序框架。

一、单文档与多视Windows程序一般分为以下几种风格:多文档、单文档、基于对话框的。

Word一类多文档程序和计算器一类基于对话框的程序不在本文介绍之列。

单文档又分为单视的和多视的。

一般情况下,单文档仅需要单视就够了,如画笔等。

但也有一些情况下,单文档需要多视支持,比如同时观察文档的不同部分,同时从不同的角度观察同一文档等。

在MFC的框架下,文档对象(CDocument)维持了一个保存其所有视的列表,并提供了增加与删除视的函数,以及当文档内容改变时通知其所有视的方法。

通过多文档框架的窗口复制机制和单文档框架的分割窗口机制是实现单文档多视的主要方法。

但这些标准方法在有的情况下并不够用,为此笔者摸索出另外两种实用的方法,在实践中使用效果良好。

二、三种标准的单文档与多视情况1.视对象基于同一视类,每个视位于MDI的一个独立子文档框架中。

用户可以通过“窗口\新窗口”菜单,为同一文档的视再创建一个窗口,通过新创建的窗口,可以编辑和观察文档的另一部分,同一文档各个视图之间自动实现同步,用户修改一个视的内容,在另外的视中也自动更新。

MFC框架通过复制原来的子框架窗口和其中的视来实现上面的功能,并且是完全自动的。

2.视对象基于同一视类,所有视位于同一文档框架中。

分割窗口将单文档窗口的视区分割成几个独立的视,框架从同一视类创建多个视对象。

Word的子窗口即属于这种类型。

3.视对象基于不同的视类,所有的视位于同一文档框架中。

多个视共享同一文档框架,但从不同的视类创建,每个视可以为文档提供不同的观察和编辑方法。

比如一个视用图形观察文档,而另一个视用文本编辑文档中对象的属性。

这种情况也适应于用不同的视来观察文档的不同部分。

这种类型的实现方法是通过重载OnCreateClient函数实现。

MFC分割窗口创建

MFC分割窗口创建

【转】 MFC 分割窗体(Splitter Windows)2011-03-20 18:32转载自651405842最终编辑drunkdreamMFC 分割窗体(Splitter Windows)<reference MSDN Microsoft Foundation Class Library and Templates TNO 029>文档描述MFC中的CSplitterWnd类,该类用来支持窗体的分割和管理分割后每一个子窗格(pane)的大小1 分割窗体风格(Splitter Styles)CSplitterWnd类支持2种不同风格的分割窗口1.1 静态分割(static splitter)分割的窗格(pane)在分割窗体(splitter window;)创建时创建,而且顺序,数量不会变化,分割控制条(Spli 控制每个窗格的大小.通常不同的窗格是不同的视图类(view class);例如 Visual C++graphics 和 Windows文件管理器就是这个风格的分割窗体;该风格分割窗体不会用到分割格(splitter box)1.2 动态分割(dynamic splitter)当用户控制视图的分割或停止分割, 附加窗格会被创建或销毁; 这种动态分割开始于一个单独的视图,分割格box)用于初始化分割;当一个视图可以在2个方向上被分割时,会有3个新的视图被创建并显示为3个新的窗格;当被激活(active)时,分割格(splitter box)会如同分割控制条(splitter bar)一样在各个窗格间被绘制;当用户除加窗格会被销毁,只有原来的视图(分割时位于0行0列位置的窗格)会被保留直到分割窗体本身被销毁;例如 Microsoft Excel 和 Microsoft Word都是这种风格的分割窗体;当创建任意一种风格的分割窗体时,必须给定分割窗体的最大的行列数;静态风格的分割窗体,每个窗格必须被创建CSplitterWnd::CreateView;动态风格的分割窗体第一个窗格会在CSplitterWnd对象创建被自动创建静态风格的分割窗体的最大行列数为 16 x 16动态风格的分割窗体的最大行列数为 2 x 2推荐的分割方式为:1 X2 2 X 1 2 X 22 分割窗体的例子(Splitter Samples)很多MFC的列子程序都直接或间接的用到了分割窗体 MFC入门程序Scripple程序的第4 部中就用到动态切分MFC标准示例中ViewEx展示静态使用切分窗体的方法,包括如何在一个切分窗体中包含另一个切分窗体3 分割窗体中使用的术语(Terminology Used By Implement)CsplitterWnd(分割窗体):负责提供窗格切分空间和滚动条(同行(row)共享竖直滚动条(Vertical ScrollBar),同列(column)共享水平滚(Horizontal ScrollBar) );同时行列的下标从0, 0开始,言即第一个窗格为第0行第0列的窗格Pane(窗格)CSplitterWnd管理的应用程序显示数据的窗体,一般而言窗格是一个视图的派生类对象,实际上窗格可以是任中派生的对象;Splitter Bar(分割控制条)在窗格行列间的控件,用于控制行列上窗格的大小Spliiter Box(分割格)动态分割窗体位于竖直滚动条最上的或水平滚动条最左位置的按键,用于创建新的分割窗格Splitter Intersection(分割交叉点)竖直或水平分割控制条的交叉点,可用于同步控制水平,竖直窗格的大小4 共享滚动条(Shared Scroll Bars)CSplitterWnd支持共享滚动条,滚动条是CSplitterWnd的子窗体并且在分割窗体中为不同的窗格所共享;如在创建1X 2 CSplitterWnd时声明了WS_VSCROLL分割那么2个窗格共享的竖直滚动条会创建如:[ ][ ][^][pane00][pane01][|][ ][ ][v]当移动滚动条时,WM_VSCROLL消息会发送到2个窗格中同样,同列的窗格可以共享水平滚动条注意在分割窗体中共享滚动条是非常有用的,如果是2种不同的视图使用共享滚动条那么就必须要协调滚动位置和所有视图的派生类可以通过CWnd中的操作ScrollBar的方法来控制共享滚动条,但是一些非视图派生类,没有使控件的类或通过标准Window的实现方法的类如CEditView将不适合于共享滚动条5 最小大小(Minimum size)在分割窗体中每一行都有最小高度限制,每一列都有最小宽度限制,这2个最小值用于控制窗格显示数据最小静态分割窗体的最小大小为 0,0;动态分割窗体的最小大小可以在CSplitterWnd::创建时设定;这些值可以同过SetColumnInfo 和 SetRowInfo来改变;6 未公布的接口函数(protected interface)以下将讨论一些未公布的CSplitterWnd的技术细节以便高级用户来定制CSplitterWnd;这些API没有官方文档公布同时在将来版本的MFC中极可能会被改变:6.1 分割控制条(splitter bar)分割格(box) 和分割位置跟踪(tracker)的绘制enum ESplitType { splitBox, splitBar, splitIntersection, splitBorder };virtual void OnDrawSplit ESplitType nType, const CRect& rect);virtual void OnInvertTracker(const CRect& rect);这些虚函数可以图形表现的分割窗体6.2 创建视图和控件virtual BOOL CreateScrollBarCtrl(DWORD dwStyle, UINT nID);默认行为时创建滚动条,但是可以重载用于建新控件6.3 动态切分窗体virtual void DeleteView(int row, int col);virtual BOOL SplitRow(int cyBefore);virtual BOOL Spli cxBefore);virtual void DeleteRow(int row);virtual void DeleteColumn(int row);用于实现动态分割窗体的逻体拥有风格SPLS_DYNAMIC_SPLIT时)Trackback: /TrackBack.aspx?PostId=697418VC设计分割视图通用创建框架目前基于分割视图的应用开发十分流行,分割视图技术是在同一个框架窗口下同时显示多个视图的一项技术。

addarray函数用法

addarray函数用法

addarray函数用法一、分割窗体新建一个单文档的MFC工程(注意在向导中设置窗口最大化和分割窗口支持)。

新建两个对话框,用于分割窗口【注意】对话框的样式(Style)属性改为下层(Child),边框(Border)属性改为None,最开始没有改这个,程序运行的时候报错了。

【注意】将两个对话框生成从CFormView派生的类。

在CMainFrame的OnCreateClient中添加【例1】把框架分割成两列,右边的一列和对话框绑定。

【例2】在分割后的子窗口上继续分割在CMainFrame中添加两个成员变量,类型为CSplitterWnd,如下所示CSplitterWnd m_splitterWnd1;CSplitterWnd m_splitterWnd2;添加虚函数virtualBOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);程序代码修改部分如下://初始左右分割框架,要调用函数SetColumnInfo来设定分割线位置对分割出来的一列再进行分割,则是由CreateView中CSize的高度来确定分割线位置*总结:* 给框架窗口添加静态拆分视图的过程如下:* 1.给框架窗口类添加一个CsplitterWnd数据成员。

* 2.覆盖框架窗口的OnCreateClient函数,并调用CsplitterWnd::CreateStatic来创建静态拆分视图。

* 3.使用CsplitterWnd::CreateView在每个静态拆分窗口的窗格中创建视图* 使用静态拆分窗口的一个优点是由于您自己给窗格添加视图,所以可以控制放入视图的种类。

单文档实现多视图

单文档实现多视图
Step 1:使用VC 6.0新建一个Project,命名为:MultiView。除选择单文档属性外,一切使用“默认”方式。于是你可以获得五个类:CMainFrame,CMultiViewApp,CMultiViewDoc,CMultiViewView,和CAboutDlg;
Step 2:新建一个新的视图View,添加一个新的MFC Class(Insert->New Class),基类为CView(或者CView的派生子类,如CEditView等)。类的名字为CAnotherView,这就是新的视图;并为CAnotherView添加GetDocument的实现:
{
// TODO: Add your command handler code here
UINT temp = ::GetWindowLong(m_pAnotherView->m_hWnd, GWL_ID);
::SetWindowLong(m_pAnotherView->m_hWnd, GWL_ID, ::GetWindowLong(m_pFirstView->m_hWnd, GWL_ID));
void CMultiViewApp::OnShowFirstview()
{
// TODO: Add your command handler code here
UINT temp = ::GetWindowLong(m_pAnotherView->m_hWnd, GWL_ID);
::SetWindowLong(m_pAnotherView->m_hWnd,GWL_ID, ::GetWindowLong(m_pFirstView->m_hWnd, GWL_ID));

实验九 基于文档视图结构的MFC简单应用程序框架设计

实验九 基于文档视图结构的MFC简单应用程序框架设计
1
2、 在视图类的头文件 test9View.h 中声明有关的成员变量:
protected:
boolห้องสมุดไป่ตู้m_bDraw;
//绘图标识
HCURSOR m_Hcursor; CPoint m_pOld;
//光标对象 //记录鼠标位置
在视图类 CTest9View 的构造函数中对上述成员变量进行初始化:
CTest9View::CTest9View()
//获取客户窗口 DC //绘图
dc.LineTo(point);
m_pOld=point;
}
CView::OnMouseMove(nFlags, point); }
void CTest9View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bDraw=FALSE;
//取消绘图状态
ReleaseCapture();
//释放鼠标捕捉
ClipCursor(NULL);
//取消鼠标区域的限制
CView::OnLButtonUp(nFlags, point); }
[思考题]
1. 设法将图形信息保存在文档对象中,使当窗口大小改变或覆盖时,可据此进行重绘。 2. 设法通过文档的序列化操作,将图形信息保存在指定文件中。当打开该文件时,显示相
{
// TODO: Add your message handler code here and/or call default
SetCursor(m_Hcursor);

MFC学习总结 (67个技巧) dlg 上建立View

MFC学习总结 (67个技巧) dlg 上建立View

MFC学习总结(67个技巧) dlg 上建立View1."属性页的添加:创建对话框的类,该类要从CpropertyPage继承;然后在要添加该对话框为属性页的类(头文件)里创建CpropertySheet类的一个对象m_tabsheet和新创建的对话框类的对象m_skatch;最后,在.cpp文件里的OnInitDialog()之类的函数里实现如下代码:m_tabsheet.Create(this, WS_CHILD | WS_VISIBLE, 0);"//使选项卡的按钮在下面"if(m_tabsheet.m_hWnd)"m_tabsheet.ShowWindow(SW_MAXIMIZE);//显示选项卡//加入标签,标签名由各个子对话框的标题栏决定"m_tabsheet.AddPage(&m_skatch);"//用Create来创建一个属性页"m_tabsheet.Create(this, WS_CHILD | WS_VISIBLE, WS_EX_CONTROLPARENT);"RECT rect;"m_tabsheet.GetWindowRect(&rect);"int width = rect.right - rect.left;"int height = rect.bottom - rect.top;""//调整属性页的大小和位置"m_tabsheet.SetWindowPos(NULL, 225, 225, width-82, height,SWP_NOACTIVATE);属性页的添加完成。

如果要添加多个属性页,则只需要增加多个对象,如下:m_tabsheet.AddPage(&m_skatch1);m_tabsheet.AddPage(&m_skatch2);. . . . . .2."List Control中标题栏(Column)的添加:创建一个List Control,其ID为IDC_LIST,在其Styles属性项下的View项里选择Report、Align 项里选择Top、Sort项里选择None.然后在该List所在对话框的类(头文件)里创建ClistCtrl的一个对象m_list然后在.cpp文件的OnInitDialog()之类的函数里实现如下代码:CString strname[3];strname[0]="Screen Name";strname[1]="Form ID";strname[2]="Category Path";for(int i=0;i<3;i++){m_List.InsertColumn(i,strname[i],LVCFMT_LEFT,130);}在这之前也要将List Control的ID与ClistCtrl的对象m_list在DoDataExchange(CDataExchange* pDX)函数里绑定,如下:DDX_Control(pDX, IDC_LIST, m_List);3."ToolBar和StatusBar中控件的添加:方法⑴.只能在ToolBar里创建控件:首先,在ToolBar中创建一个Button,其ID为ID_TOOL_COMBO(我们要将创建的控件放在该Button的位置上).其次,新创建一个类CMainToolBar,要从CToolBar继承(创建过程大概如下:选择工程/增加到工程/新的类;也可以选择工程的根,然后点击右键,选择新的类;或者CTL+W,选择增加类/新的类--- 然后在class type里选择Generic Class,在Name栏里输入新类的名字,Base class 里输入CToolBar),创建成功后在该类里创建要增加的控件的对象,如:CComboBox""m_wndMyCombo;CStatic""m_wndCategory, m_wndCategoryPath;CButton""m_wndOpenButton;Cedit"""m_wndEdit;然后在构造函数里初始化如:m_wndMyCombo.m_hWnd = NULL;m_wndCategory.m_hWnd = NULL;m_wndCategoryPath.m_hWnd = NULL;m_wndOpenButton.m_hWnd = NULL;m_wndEdit.m_hWnd = NULL;接着在CMainframe的头文件里创建CMainToolBar的一个对象m_wndToolBar,最后在.cpp 文件的OnCreate函数的最后实现如下:"int index = 0;"CRect rect;// 可定义在头文件当中"//ComboBox"{""//找到指定的工具项""while(m_wndToolBar.GetItemID(index)!=ID_TOOL_COMBO)"""index++;""//设置指定工具项的宽度并获取新的区域120是宽度""m_wndToolBar.SetButtonInfo(index, ID_TOOL_COMBO, TBBS_SEPARATOR, 120); ""m_wndToolBar.GetItemRect(index, &rect);""""//设置位置""rect.top+=1;""rect.bottom += 200;""""// 创建并显示控件""if(!m_wndToolBar.m_wndMyCombo.Create(WS_CHILD|WS_VISIBLE|CBS_AUTOHSCROLL|"""CBS_DROPDOWNLIST | CBS_HASSTRINGS , rect, &m_wndToolBar,ID_TOOL_COMBO))""{"""TRACE0("Failed to create combo-box\n");"""return FALSE;""m_wndToolBar.m_wndMyCombo.ShowWindow(SW_SHOW);""""//填充内容"""m_wndToolBar.m_wndMyCombo.AddString("25%");""m_wndToolBar.m_wndMyCombo.AddString("50%");""m_wndToolBar.m_wndMyCombo.AddString("75%");"""//选择默认项""m_wndToolBar.m_wndMyCombo.SetCurSel(0);""""//获取到内容并MSGBOX显示出来""CString strContent;""m_wndToolBar.m_wndMyCombo.GetWindowText(strContent);""index = 0;"}其他控件都类似创建(只需要注意一下各自的Create函数的参数即可)。

用VC6.0单文档进行数字图像处理

用VC6.0单文档进行数字图像处理

用VC6.0单文档进行数字图像处理以前写一些VC6.0的数字图像处理程序,大多是用对话框写的。

主要是因为对话框就那么两个类:App类和Dlg类,所以理解也比较简单。

但是,最近,听到有人这么讲文档视图类才是MFC的核心。

所以,也想尝试一下。

这两天做了点简单的尝试,特此总结一下。

1、写一个DIB类,因为在单文档或多文档下,如果不写一个DIB 类,那么你做处理就比较麻烦了。

因为我们经常要将这个DIB类的对象来共享,比如一般的DIB类的对象都是放到Doc类中。

那么我们经常要在View类和MainFrame类中引用到Doc类的Dib类的实例。

如果是多个Doc类和View类,这种数据的共享就显得更加重要了。

2、在DIB类中要有一个获得图像像素数据的指针的函数和一个能够设置DIB类的像素数据的指针。

因为,在MainFrame类中我们需要获得Doc类的一个DIB类的对象之后,可以获得指向该对象的像素数据的指针,因为我们要对其中的像素数据进行操作。

另外,我们要将操作之后的像素数据拷贝进DIB类的对象的像素数据中。

3、DIB类中还需要有获得操作像素数据中要用到的函数:获得图像高度、获得图像宽度、获得图像位数、获得图像每行像素所占的字节数。

4、DIB类中当然还需要有读入和写出图像的函数。

5、由于菜单的响应函数都是在MainFrame类中,所以,我们需要在MainFrame类中获得Doc类和View类的指针。

获得Doc类的指针主要是利用其中的DIB类的对象;获得View类的指针主要是更新显示处理后的图像效果。

所以在MainFrame类的cpp文件的包含文件中要包含Doc类和View类的h文件。

获得方法是调用MainFrame类的GetActiveDoc()和GetActiveView()函数。

好了,下面说说主要的程序:DIB类的头文件:// Dib.h: interface for the CDib class.////////////////////////////////////////////////////////////// //////////#if !defined(AFX_DIB_H__1065C5DA_1C47_464F_A225_A AF8D2F15064__INCLUDED_)#defineAFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D2F15064__I NCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class CDib{public:CDib();//构造函数virtual ~CDib();//析构函数private:BITMAPFILEHEADER *m_pBmfh;//保存位图文件头BYTE *m_pBmInfo;//保存位图信息头+调色板(用于显示位图)BYTE *m_pPixel;//保存位图像素数据BITMAPINFOHEADER *m_pBmih;//保存位图信息头public:BOOL m_bRead;//标志是否调用了Read函数public:int Read(CString filename);//读入位图void Draw(CDC *pDC);//显示位图int Write(CString filename);//写出位图public:DWORD GetWidth() const;//获得位图宽度DWORD GetHeight() const;//获得位图高度WORD GetBitCount() const;//获得位图位数DWORD GetLineBytes() const;//获得位图每行像素所占字节数BYTE* GetPixelPointer() const;//获得指向位图像素数据的指针void SetPixelMatrix(BYTE *newPixel);//设置位图的像素矩阵};#endif// !defined(AFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D 2F15064__INCLUDED_)DIB类的cpp文件:// Dib.cpp: implementation of the CDib class.////////////////////////////////////////////////////////////// //////////#include "stdafx.h"#include "VampireImage.h"#include "Dib.h"//包含DIB类的头文件#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif//////////////////////////////////////////////////////////// //////////// Construction/Destruction//////////////////////////////////////////////////////////// //////////CDib::CDib(){m_pBmfh=new BITMAPFILEHEADER;m_pBmih=new BITMAPINFOHEADER;m_pBmInfo=NULL;m_pPixel=NULL;m_bRead=FALSE;}CDib::~CDib(){if(m_pBmfh){delete m_pBmfh;m_pBmfh=NULL;}if(m_pBmih){delete m_pBmih;m_pBmih=NULL;}if(m_pBmInfo){delete[] m_pBmInfo;m_pBmInfo=NULL;}if(m_pPixel){delete[] m_pPixel;m_pPixel=NULL;}}//////////////////////////////////////////////////////////////////////// Methods//////////////////////////////////////////////////////////// //////////int CDib::Read(CString filename){CFile dib;if(!dib.Open(filename,CFile::modeRead)){return -1;}if(dib.Read(m_pBmfh,sizeof(BITMAPFILEHEADER))!=size of(BITMAPFILEHEADER)){//读取位图文件头dib.Close();return -1;}m_pBmInfo=new BYTE[m_pBmfh->bfOffBits-14];//为信息头+调色板分配空间if(!m_pBmInfo){dib.Close();return -1;}if(dib.Read(m_pBmInfo,m_pBmfh->bfOffBits-14)!=(m_pBmfh->bfOffBits-14)){//读取位图信息头+调色板(如果有)delete[] m_pBmInfo;m_pBmInfo=NULL;dib.Close();return -1;}memcpy(m_pBmih,m_pBmInfo,sizeof(BITMAPINFOHEAD ER));//拷贝40字节到位图信息头中WORD bitCount=m_pBmih->biBitCount;DWORD width=m_pBmih->biWidth;DWORD height=m_pBmih->biHeight;DWORD lineBytes=(width*bitCount+31)/32*4;m_pPixel=new BYTE[height*lineBytes*sizeof(BYTE)];//为位图像素矩阵分配空间if(!m_pPixel){dib.Close();return -1;}if(dib.Read(m_pPixel,height*lineBytes*sizeof(BYTE))!=(h eight*lineBytes*sizeof(BYTE))){//读取位图像素矩阵dib.Close();delete[] m_pBmInfo;m_pBmInfo=NULL;delete[] m_pPixel;m_pPixel=NULL;return -1;}dib.Close();m_bRead=TRUE;//标志已经使用过Read函数return 0;}int CDib::Write(CString filename){CFile dib;if(!dib.Open(filename,CFile::modeWrite | CFile::modeCreate | CFile::typeBinary)){return -1;}dib.Write(m_pBmfh,sizeof(BITMAPFILEHEADER));//写入位图文件头dib.Write(m_pBmInfo,m_pBmfh->bfOffBits-14);//写入位图信息头+调色板(如果有)dib.Write(m_pPixel,GetHeight()*GetLineBytes()*sizeof(B YTE));//写入位图像素矩阵dib.Close();return 0;}void CDib::Draw(CDC *pDC){DWORD width=GetWidth();DWORD height=GetHeight();StretchDIBits(pDC->m_hDC,0,0,width,height,0,0,width,h eight,m_pPixel,(BITMAPINFO*)m_pBmInfo,DIB_RGB_COLORS ,SRCCOPY);//用StretchDIBits显示位图}//////////////////////////////////////////////////////////// //////////// Get/Set Functions//////////////////////////////////////////////////////////// //////////WORD CDib::GetBitCount() const{return m_pBmih->biBitCount;}DWORD CDib::GetWidth() const{return m_pBmih->biWidth;}DWORD CDib::GetHeight() const{return m_pBmih->biHeight;}DWORD CDib::GetLineBytes() constreturn (GetWidth()*GetBitCount()+31)/32*4;}BYTE* CDib::GetPixelPointer() const{return m_pPixel;}void CDib::SetPixelMatrix(BYTE *newPixel){delete[] m_pPixel;//删除原来的像素矩阵m_pPixel=NULL;m_pPixel=new BYTE[GetHeight()*GetLineBytes()];//为新的像素矩阵分配空间if(!m_pPixel){return;}memcpy(m_pPixel,newPixel,GetHeight()*GetLineBytes()); //将心的像素矩阵拷贝到DIB类中}View类中的OnDraw函数:void CVampireImageView::OnDraw(CDC* pDC){CVampireImageDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereif(pDoc->GetDibInstance()->m_bRead==TRUE){//如果已经读入图片,则调用DIB类的对象的Draw函数来显示位图pDoc->GetDibInstance()->Draw(pDC);}}Doc类中的获得DIB类的对象的指针的函数:CDib* CVampireImageDoc::GetDibInstance(){return m_pDib;}Doc类中的打开和保存菜单的函数:BOOL CVampireImageDoc::OnOpenDocument(LPCTSTR lpszPathName){if (!CDocument::OnOpenDocument(lpszPathName))return FALSE;// TODO: Add your specialized creation code herem_pDib->Read(lpszPathName);return TRUE;}CDib* CVampireImageDoc::GetDibInstance(){return m_pDib;}BOOL CVampireImageDoc::OnSaveDocument(LPCTSTR lpszPathName){// TODO: Add your specialized code here and/or call the base classCFileDialog sfd(false,"*.bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"BMP Files(*.bmp)|*.bmp||");if(sfd.DoModal()!=IDOK){return FALSE;}if((m_pDib->Write(sfd.GetPathName()))==-1){AfxMessageBox("保存失败");return FALSE;}return TRUE;;}MainFrame类中灰度图菜单的响应函数:void CMainFrame::OnGrayimage(){// TODO: Add your command handler code hereCVampireImageDoc*pDoc=(CVampireImageDoc*)this->GetActiveDocument();//获得当前的Doc类的指针DWORDwidth=(pDoc->GetDibInstance())->GetWidth();//获得DIB对象的宽度DWORDheight=(pDoc->GetDibInstance())->GetHeight();//获得DIB对象的高度WORDbitCount=(pDoc->GetDibInstance())->GetBitCount();//获得DIB对象的位数DWORDlineBytes=(pDoc->GetDibInstance())->GetLineBytes();//获得DIB对象的每行所占字节数BYTE*dib=(pDoc->GetDibInstance())->GetPixelPointer();//得到DIB对象的像素数据的指针BYTE *newDib=new BYTE[height*lineBytes];//新建一块内存if(!newDib){return;}memcpy(newDib,dib,height*lineBytes);//将DIB对象的像素数据拷贝至新建的内存if(bitCount==8)//如果位图是8位{AfxMessageBox("已经是8位的灰度图了,没有必要再转换。

mfc直线和多边形矩形窗口裁剪算法

mfc直线和多边形矩形窗口裁剪算法

mfc直线和多边形矩形窗口裁剪算法MFC直线和多边形矩形窗口裁剪算法是一种在MFC框架下用于裁剪直线和多边形的算法。

该算法可以确保在绘制图形时,图形的边界不会超出指定的矩形窗口范围。

这种裁剪算法是为了确保图形的可视性和美观性,以及提高程序的性能。

在MFC框架中,绘制图形一般是通过在窗口的OnPaint函数中完成的。

在OnPaint函数中,我们可以获取绘图设备上下文(device context,简称DC),并在DC上进行绘图操作。

为了实现裁剪效果,我们需要在绘图之前对要绘制的图形进行裁剪,确保图形不会超出指定的窗口范围。

对于直线的裁剪,我们可以使用Cohen-Sutherland裁剪算法。

该算法是一种基于线段的区域编码(region encoding)算法,用于裁剪位于矩形窗口外部的线段。

算法的基本思路是判断直线的两个端点是否在窗口的内部,如果都在内部,则直接绘制该直线;如果都在外部,则直接丢弃该直线;如果一个在内部,一个在外部,则通过计算交点并选择正确的端点来裁剪直线。

对于多边形的裁剪,我们可以使用Sutherland-Hodgman裁剪算法。

该算法是一种基于点的裁剪算法,用于裁剪位于矩形窗口外部的多边形。

算法的基本思路是将多边形分割为若干条边和端点,然后根据边与窗口的关系进行裁剪。

具体步骤包括:将多边形的各个顶点与窗口的边界进行比较,并根据顶点在内部和外部的情况确定裁剪结果;根据边界与窗口的关系确定新的裁剪结果,并将结果作为下一次裁剪的输入。

在MFC中实现直线和多边形的裁剪算法,可以按照以下步骤进行:1.获取绘图设备上下文(DC)。

2.设置裁剪区域为窗口矩形范围。

3.使用Cohen-Sutherland算法进行直线裁剪,对于每条需要绘制的直线,判断其裁剪结果并进行绘制。

4.使用Sutherland-Hodgman算法进行多边形裁剪,对于每个需要绘制的多边形,判断其裁剪结果并进行绘制。

5.释放绘图设备上下文。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于单文档的窗口分割
简介部分是对于MFC应用程序的介绍,在博客上看到的,觉得受益匪浅,所以写到这里。

不需要的朋友可以从第二部分程序设计开始看起。

目录
基于单文档的窗口分割 (1)
简介 (3)
MFC应用程序类型简介 (3)
单文档与多视图 (5)
单文档多视图程序设计 (6)
Step1:创建单文档的MFC程序 (6)
Step2:声明相关的变量。

(6)
Step3:重载OnCreateClient()函数,进行窗口的分割 (7)
Step4:设置行列初始值 (9)
附:代码 (10)
简介
MFC应用程序类型简介
在Microsoft VC++ 6.0中,基于MFC的应用程序一般分为以下几种:
多文档界面(MDI)
单文档界面(SDI)
基于对话框的应用程序。

图1-1 应用程序类型
其中单文档又可分为单视图的和多视图的。

图1-2 单文档单视图
图1-3 单文档多视图
一般情况下,单文档仅需要单视图就够了,如Windows自带的记事本、画图程序等等,但
在一些情况下,单文档需要多视图支持,比如同时观察文档的不同部分,同时从不同的角度观察同一文档等。

在MFC的框架下,文档对象(CDocument)有一个保存其所有视图的列表,并提供了增加视图(AddView)与删除视图(RemoveView)函数,以及当文档内容改变时通知其所有视图的方法(UpdateAllViews)。

1-4 类视图
通过多文档框架的窗口复制机制和单文档框架的分割窗口机制是实现单文档多视图的主要方法。

单文档与多视图
一般地,单文档与多视图有三种情况:
1)在多文档界面MDI中,每个视图位于MDI的一个独立子文档框架中,视图对象基于同一个视图类。

用户可以通过“窗口|新窗口”菜单,为同一文档的视图再创建一个窗口,通过新创建的窗口,可以编辑和观察文档的另一部分,同一文档各个视图之间自动实现同步,用户修改一个视图的内容,在另外的视图中也自动更新。

MFC框架通过复制原来的子框架窗口和其中的视图来实现上面的功能,并且是完全自动的。

2)视图对象基于同一视图类,所有视图位于同一文档框架中。

分割窗口将单文档窗口的视图区分割成几个独立的视图,框架从同一视图类创建多个视图对象。

Word的子窗口即属于这种类型。

3)视图对象基于不同的视图类,所有的视图位于同一文档框架中。

多个视图共享同一文档框架,但从不同的视图类创建,每个视图可以为文档提供不同的观察和编辑方法。

比如在一个窗口里观察文档的不同部分,或者是在一个窗口里用不用类型的视图观察同一个文档。

这种类型的实现方法是通过重载框架类CMainFrame的成员函数OnCreateClient实现,用户可以根据不同需要将窗口分为垂直或水平的多个分割窗口。

单文档多视图程序设计
下面通过实例设计,介绍单文档多视图的窗口分割(上面介绍的第二种情况)。

Step1:创建单文档的MFC程序
创建一个基于MFC的应用程序,程序类型选择“单文档”,命名为“SplitterTest”。

Step2:声明相关的变量。

在MainFrm.h中添加如下变量声明。

public:
CSplitterWnd m_miansplitter;
CSplitterWnd m_leftSplitter;
CSplitterWnd m_rightSplitter;
CSplitterWnd m_leftbottom;
BOOL m_isSplitter;
并在CMainFrame的构造函数中,初始化isSplitter为FALSE
Step3:重载OnCreateClient()函数,进行窗口的分割
图2-1重载OnCreateClient()函数
在OnCreateClient()函数中添加如下代码:
这时,运行程序,会发现窗口已经被分割为多视图。

但是,需要拖动一下才显示出来。

图2-2 初步运行结果Step4:设置行列初始值
重载OnSize函数。

图2-3 重载OnSize函数在函数中添加如下代码,
此时,运行结果正常。

图2-4 最终运行结果
附:代码
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {
// TODO: 在此添加专用代码和/或调用基类
//窗口的分割
if(m_mainsplitter.CreateStatic(this,1,2)==FALSE)
{
return FALSE;
}
if(m_leftsplitter.CreateStatic(&m_mainsplitter,2,1,WS_CHILD|WS_VISIBLE, m_mainsplitter.IdFromRowCol(0,0))==FALSE)
{
return FALSE;
}
if(m_rightsplitter.CreateStatic(&m_mainsplitter,1,2,WS_CHILD|WS_VISIBLE, m_mainsplitter.IdFromRowCol(0,1))==FALSE)
{
return FALSE;
}
if(m_leftbottom.CreateStatic(&m_leftsplitter,1,2,WS_CHILD|WS_VISIBLE, m_leftsplitter.IdFromRowCol(1,0))==FALSE)
{
return FALSE;
}
m_isSplitter = TRUE;
//绑定视图
CRect cRect;
GetClientRect(&cRect);
if(m_leftsplitter.CreateView(0,0,RUNTIME_CLASS(CSplitterTestView), CSize(cRect.Width()/2,cRect.Height()/2),pContext)==FALSE) {
return FALSE;
}
if(m_rightsplitter.CreateView(0,0,RUNTIME_CLASS(CSplitterTestView), CSize(cRect.Width()/4,cRect.Height()),pContext)==FALSE) {
return FALSE;
}
if(m_rightsplitter.CreateView(0,1,RUNTIME_CLASS(CSplitterTestView), CSize(cRect.Width()/4,cRect.Height()),pContext)==FALSE) {
return FALSE;
}
if(m_leftbottom.CreateView(0,0,RUNTIME_CLASS(CSplitterTestView), CSize(cRect.Width()/4,cRect.Height()/2),pContext)==FALSE) {
return FALSE;
}
if(m_leftbottom.CreateView(0,1,RUNTIME_CLASS(CSplitterTestView), CSize(cRect.Width()/4,cRect.Height()/2),pContext)==FALSE) {
return FALSE;
}
return TRUE;
/*return CFrameWnd::OnCreateClient(lpcs, pContext);*/
}
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
CRect crFram;
GetClientRect(&crFram);
if(m_isSplitter)
{
m_mainsplitter.SetColumnInfo(0,crFram.Width()/2,10);
m_leftsplitter.SetRowInfo(0,crFram.Height()/2,10);
m_rightsplitter.SetColumnInfo(0,crFram.Width()/4,10);
m_rightsplitter.SetColumnInfo(1,crFram.Width()/4,10);
m_mainsplitter.RecalcLayout();
}
}。

相关文档
最新文档