330 likes | 506 Views
Visual C++ 与面向对象程序设计教程. 第 11 章 文档 / 视图结构. 教学目标. 以单文档界面( SDI )应用程序为例,进一步介绍 MFC 的文档 / 视图程序结构 及编程处理. 学习要求. 理解文档 / 视图结构 掌握在文档类中数据的定义、初始化 掌握在视图类中数据的修改、重画 掌握数据在文档 / 视图类中完整的处理过程 掌握定时器消息处理. 授 课 内 容. 11.1 文档 / 视图概念 11.2 视图类 11.3 文档类 11.4 文档 / 视图类之间的协作关系 11.5 使客户区重绘 调试技术 程序设计举例.
E N D
Visual C++与面向对象程序设计教程 第11章文档/视图结构
教学目标 • 以单文档界面(SDI)应用程序为例,进一步介绍MFC的文档/视图程序结构 及编程处理
学习要求 • 理解文档/视图结构 • 掌握在文档类中数据的定义、初始化 • 掌握在视图类中数据的修改、重画 • 掌握数据在文档/视图类中完整的处理过程 • 掌握定时器消息处理
授 课 内 容 • 11.1文档/视图概念 • 11.2 视图类 • 11.3 文档类 • 11.4 文档/视图类之间的协作关系 • 11.5 使客户区重绘 • 调试技术 • 程序设计举例
11.1文档/视图概念 • 在框架窗口结构中,文档/视图功能均在框架类中 • 功能细化 • 文档可视为一个应用程序的数据元素的集合 • 视图是数据的用户界面, • 通过窗口显示 • 通过打印机打印 • 提供用户与文档中数据的交互功能
文档/视图结构的两种类型 • 单文档界面(SDI:Single Document Interface) • 同一时刻只能操作一个文档 • 如Windows的NotePad(记事本) • 多文档界面(MDI:Multiple Document Interface) • 允许同时对多个文档进行操作 • 如Microsoft Word
文档/视图结构的特点 • 对数据的操作与数据显示界面分离 • 结构清晰 • 组织灵活 • 初学者理解困难 • 标准的操作界面及功能支持,减少开发工作量 • 新建文件、打开文件、保存文件、文档打印等 • 支持打印、打印预览和电子邮件发送功能 • 不适宜使用的场合
11.2 视图类 • 视图类中主要函数 • GetDocument()成员函数用于从文档类中获取数据值 • OnDraw(CDC* pDC)方法完成屏幕显示、打印和打印预览功能 • OnInitialUpdate()虚成员函数在应用程序启动,或用户从File菜单中选择了New或者Open选项时被调用。
从视图类访问文档类中的数据 • 直接调用函数访问 GetDocument ( )>AddBubble (rectBubble ); • 通过指针访问 CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); //在OnDraw中 ……. pDoc->AddBubble(rectBubble);
视图类中主要工作 • 显示信息(OnDraw) • 消息处理(键盘、鼠标 、定时器等) • 读取数据 • 修改数据 • 要求重画数据( CWnd::InvalidateRect )
11.3 文档类 • 数据定义 • 文档类的主要成员函数 • OnNewDocument()//初始化的位置 • DeleteContents()//消除数据 1.删除文档的数据; 2.确信一个文档在使用前为空。 • SetModifiedFlag() • void SetModifiedFlag ( BOOL bModified = TRUE ); //设置修改标志 • Serialize() • OpenDocumentFile()
11.4 文档/视图类之间的协作关系 • 简单的例子(例11-1),文档类中数据只读 • 修改文档类中的数据(例11-2) • 协作关系小结 • 简易计数器程序
简单的例子(例11-1) • 改造例10-3,将数据存放于文档类,在视图类中访问(只读) • 数据定义在文档类中: enum {iPt = 10}; double m_dbXdata[iPt]; double m_dbYdata[iPt]; • 数据初始化,在文档类的OnNewDocument() m_dbXdata[0] = 1; m_dbXdata[1] = 1.5; • 在视图类的OnDraw中访问数据:(加指针pDoc) double dbXMin = pDoc->m_dbXdata[0];
修改文档类中的数据(例11-2) • 视图中显示鼠标点击位置 : • 变量定义在文档类: CPoint m_pointMouse; • 变量显示在视图类的OnDraw中: CString strDisplay; strDisplay.Format("X = %d,Y = %d",pDoc->m_pointMouse.x,pDoc->m_pointMouse.y); pDC->TextOut(10,10,strDisplay);
修改文档类中的数据(例11-2)(续) • 变量修改在视图类的OnLButtonDown CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->m_pointMouse=point; Invalidate();
文档/视图类协作关系小结 • 数据定义、初始化在文档类 • 数据显示、交互修改一般在视图类 • 在视图类的成员函数中(如OnLButtonDown等),可以: • 访问文档类中的数据,可以从OnDraw中复制两条语句,得到指向文档类的指针(pDoc),并通过该指针访问文档类中的数据。 • 如果修改了数据,并要求重新显示,则需要用Invalidate或InvalidateRect发出重画消息,引起对OnDraw的调用
简易计数器程序 • 变量定义 • 变量初始化 • 变量显示 • 变量修改及要求重画(定时器消息处理函数) • 定时器消息设置 • 定时器消息取消
数据初始化的时机 • 文档类中: • 构造函数 • OnNewDocument中 • 视图类中 • 构造函数 • OnDraw中? • 设置定时器的函数中
11.5 使客户区重绘 • 重新绘制的区域(无效区域) • 要求重绘的函数: • void Invalidate( BOOL bErase = TRUE ); • void InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE );
简单的动画效果 • OnDraw函数中显示图形的代码 • pDC->Ellipse(pDoc->m_rectBody); //画出椭圆 • 键盘的消息处理函数OnKeyDown中移动图形: • InvalidateRect(pDoc->m_rectBody, TRUE); //擦除原位置图形 • ……修改坐标 • InvalidateRect(pDoc->m_rectBody, FALSE); //重画新位置图形
在窗口客户区移动一个物体的步骤 • 在文档类中设置存放物体位置的数据成员并初始化; • 在改变物体位置的函数内(如OnKeyDown)做如下工作: 1)通知OnDraw()函数,更新物体原来位置的内容(擦除); 2)修改物体的位置参数; 3)通知OnDraw()函数,更新物体新位置的内容; • OnDraw中以按正常方式处理,按文档类中的位置数据画出物体.
自学内容 • 11.6 定时器消息 • 11.7 文档/视图结构中的应用程序类 • 11.8 文档/视图结构中的框架窗口类 • 11.9 文档/视图结构中各类对象之间的协作关系
11.8 文档/视图结构中的框架窗口类 框架窗口的作用有二: • 为视图提供可视的边框,包括标题条、一些标准的窗口组件(最大、最小化按钮、关闭按钮),象一个容器一样把视图包装起来。 • 响应标准的窗口消息,包括最大化、最小化、调整尺寸等。
调试技术 • Visual C++的常用调试宏 • TRACE()宏 int nSize = 3; CString sName(“why”); TRACE(“Name = %s, Size = %d\n”,sName,nSize);
程序设计举例 • 例11-5 编一程序,允许用鼠标左键拖动一个椭圆在客户区内移动 • 鼠标上次点击的位置 • 鼠标是否点在椭圆上 • 移动椭圆 • 例11-6 吹泡泡程序。
例11-6 吹泡泡程序。 • 宏定义 #define MAX_BUBBLE 250 • 数据定义(文档类) CRect m_rectBubble[MAX_BUBBLE]; int m_nBubbleCount; • 初始化 (文档类的OnNewDocument函数 ) m_nBubbleCount = 0;
例11-6 吹泡泡程序(续) • 显示位置代码 (视图类的OnDraw函数 ) for(int i=0; i<pDoc->m_nBubbleCount; i++) pDC->Ellipse(pDoc->m_rectBubble[i]); • 增加泡泡(视图类的OnLButtonDown函数)
例11-6 吹泡泡程序 (续) CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(pDoc->m_nBubbleCount < MAX_BUBBLE) { int r = rand()%50+10; CRect rect(point.x-r, point.y-r, point.x+r, point.y+r); pDoc->m_rectBubble[pDoc->m_nBubbleCount] = rect; pDoc->m_nBubbleCount++; InvalidateRect(rect, FALSE); }
待扩展功能 • 视图类中修改数据,如何通知文档类? • 泡泡能有颜色吗? • 泡泡的位置能存在磁盘上吗? • 泡泡能自动飞起来吗?
上机练习题 • 在例11-7的基础上增加用鼠标右键删除泡泡的功能。 • 重新编写一吹泡泡程序,用鼠标右键生成泡泡,鼠标左键移动泡泡的位置。 • 修改例11-5,使程序响应鼠标左键消息:当用户在窗口中点击鼠标左键时,将图形原点移至点击处并重画图形。 • 画出函数sin(x)的曲线,并重载鼠标左键消息,当鼠标左单击到曲线上的一点时,弹出对话框显示当前点的坐标。
结 束 语 • 学好程序设计语言的唯一途径是 上机练习。 • 你的编程能力与你在计算机上投入的时间成 正比。