windows编程 12文档与视图(4)

2019-05-18 17:37

1.创建框架窗口的过程

框架窗口的创建过程如图12-15所示。

文档模板:OpenDocumentFile

构造文档对象 CMyDoc 构造框架窗口对象 CMainFrame 框架 否 打开? 创建文档框架 是 调用CFrameWnd::Create 创建框架窗口 处理WM_CREATE消息 CMainFrame::OnCreate调用 CFrameWnd::OnCreateClient 创建客户区 打开文件并创建存档 调用CMyDoc:: OnNewDocument 调用CMyDoc:: OnOpenDocument 调用CMyDoc::Serialize 读取文档文件 关闭存档和文件 文档就绪可用 文档 CMyView::OnCreate 处理WM_CREATE消息 创建视图窗口 构造视图对象 CMyView 图12-15 框架窗口的创建过程

应用程序 ID_FILE_OPEN命令

调用处理函数 CWinApp::OnFileOpen 从用户获取文件名 使用文件扩展名来 选择文档模板 ID_FILE_NEW命令 调用处理函数 CWinApp::OnFileNew 一个文档 模板? 否 从用户获取文档类型 是 ●

文档模板在此点被选择 (MDI或SDI)

图12-16 创建和打开文档的过程

16

2.创建和打开文档的过程

MFC应用程序封装了创建和打开文档的过程,可用默认“文件”菜单中的“新建”和“打开”菜单项启动。MFC应用程序创建和打开文档的过程如图12-16所示。

3.初始化视图的过程

若希望在文档数据被显示之前,根据文档中的参数做一些初始化工作(如按图像的大小改变窗口的尺寸),可以在视图类中添加(重写型)消息响应函数OnInitialUpdate,并在此函数中作一些必要的文档操作。该函数是在窗口已经创建但还没有显示时会被系统调用,这时文档对象已经存在,而且文档文件已经被读取。需要说明的是,OnInitialUpdate函数不仅在程序启动(窗口创建)时会被调用,而且在每次打开或创建新文件时,也会被被系统调用。

视图初始化的过程如图12-17所示。

视图 WM_INITIALUPDATE 消息发送到视图 CMyView::OnInitialUpdate 处理消息 ●

视图在此点被初始化

默认OnInitialUpdate 调用CView::OnUpdate 图12-17 视图初始化的过程

4.创建应用程序过程

需要注意的是,应用程序中的文档对象虽然在视图对象创建之前已经被创建,但是文档类中(Serialize函数)对文件的读取则是在视图对象创建之后,而且是在视图类的OnCreate和OnSize函数被调用之后,但是是在视图类的OnInitialUpdate函数之前(参见图12-14和图12-18)。所以不能在视图类的构造函数中或OnSize的首次被调用时,使用GetDocument来获得用户文档的指针,不然得到的将是一个空文档的指针,利用该指针对文档类数据的任何操作都会导致系统的致命错误(因为其变量还没有初始化)。

另外,在系统第一次调用(窗口消息WM_SIZE的响应函数,需要自己添加)OnSize之前,文档还没有就绪,窗口也未初始化。所以,不能在首次调用OnSize函数时,进行窗

17

口操作或使用文档数据。解决办法是,在视图类中定义一个bool型类变量如m_bInit,在构造函数中将其初始化为false,在(重写型函数,需要自己添加)OnInitialUpdate中再将其设置为true,然后在OnSize函数中判断m_bInit是否为真。

构造应用程序对象 调用应用程序类的InitInstance函数 SDI 新建 构造文档对象 打开 构造[主/子]框架窗口对象 MDI 构造主框架窗口对象 调用主框架窗口类的PreCreateWindow函数 创建主档框架窗口 调用[主/子]框架窗口类的PreCreateWindow函数 调用主框架窗口类的OnCreate函数 创建[主/子]框架窗口 创建主框架窗口的客户区 调用[主/子]框架窗口类的OnCreate函数 调用主框架窗口类的OnCreateClient函数 创建[主/子]框架窗口的客户区 调用文档类的On[New|Open]Document函数 调用[主/子]框架窗口类的OnCreateClient函数 打开 打开文件并创建存档对象 新建 构造视图对象 调用文档类的Serialize函数 读取文档文件[后关闭文件] 调用视图类的PreCreateWindow函数 文档就绪 调用视图类的 创建视图窗口 OnInitialUpdate函数 调用视图类的OnDraw函数 调用视图类的OnCreate函数 调用视图类的OnSize函数 调用视图类的各种消息响应函数 18

图12-18 创建SDI和MDI应用程序的过程 (实线箭头表示实际过程,虚线箭头表示逻辑过程)

5.例子

下面是一个如何在OnSize中正确使用文档和窗口对象的例子代码框架:

class CTestView : public CView { }

CTestView::CTestView() { }

void CTestView::OnInitialUpdate() { }

void CTestView::OnSize(UINT nType, int cx, int cy) { }

CView::OnSize(nType, cx, cy); // TODO: 在此处添加消息处理程序代码

if (m_Init) …… // 使用文档和窗口对象的代码 CView::OnInitialUpdate();

// TODO: 在此添加专用代码和/或调用基类 m_Init = true; ……

// TODO: 在此处添加构造代码 m_Init = false; ……

bool m_Init; ……

12.2.6 滚动和编辑视图类

除了标准的视图类外,MFC还提供了许多其他功能更强大的视图类,参见图12-13。由于篇幅的限制,这里只简单介绍可自动支持窗口滚动的视图类CScrollView和能自动支持文

19

本文件的读写和编辑的CEditView类。

其他视图类,如CRichEditView(富文本编辑视图)、CHtmlView(网页浏览器视图)、CFormView(窗体视图)和MFC 8.0新加的CWndFormsView(Windows窗体视图)等,已经超过本书的范围,有兴趣的同学,可以自己找资料看。

1.CScrollView类

如果文档较大(如大尺寸图像),不能一次在视图窗口中完整显示,则必须使用滚动窗口。此时,用户视图类必须以CView的派生类CScrollView为基类,该类可以自动支持文档的滚动。

滚动视图类CScrollView是MFC提供的一种自动化程度非常高的滚动窗口类,可在创建项目时,在“MFC应用程序向导”最后一步的“生成的类”页,将C*View的基类从默认的CView改成CScrollView。

对已经存在的项目,可在*View.h和*View.cpp文件中,将所有的CView全部替换成CScrollView。替换方法和步骤:可以选“编辑\\查找和替换\\在文件中替换”菜单项或按“Ctrl+Shift+H”组合键,打开“查找和替换”对话框,在“查找内容”栏中输入“CView”、在“替换为”栏中输入“CScrollView”,保持“查找范围”栏的“整个解决方案”选项不变,按该对话框右下角的“全部替换”按钮。

在OnInitialUpdate函数中或其他需要的地方调用CScrollView类的成员函数SetScrollSizes来设置滚动的范围和参数,该函数的原型为:

void SetScrollSizes( int nMapMode, SIZE sizeTotal, const SIZE& sizePage = sizeDefault,

const SIZE& sizeLine = sizeDefault );

例如(其中m_iWidth、m_iHeight为视图类的整型类变量,m_bInit为视图类的布尔型类变量(初始化为false);img为文档类中定义的CImage对象,在文档类的序列化函数中装入图像文件,参见9.3.4小节2.中的例子):

void CImageView::OnInitialUpdate() {

CScrollView::OnInitialUpdate(); CImageDoc* pDoc = GetDocument(); // 对滚动视图类,必须设置滚动的尺寸 if(pDoc->img.IsNull())

20


windows编程 12文档与视图(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:山东省2009届各地期末考试数学(新课标)章节分类试题《数列》(

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: