340 likes | 486 Views
第八章 文档和视图. 文档和视图的关系 文档模板的作用 创建用户自定义类 文档的读写. 第一节 文档 / 视图结构概述. 文档和视图的关系 文档模块的功能 设计一个简单的文本编辑器. MFC 创建的三种应用程序类结构. 基于对话框的应用程序类结构 SDI 应用程序类结构 MDI 应用程序类结构. 基于对话框的应用程序类结构. SDI 应用程序类结构. MDI 应用程序类结构. 文档和视图的关系. 数据操作和数据表示的分离. 文档和视图的相互访问. 文档 / 视图应用程序的实现. 在文档类中定义公有类成员变量描述数据
E N D
第八章 文档和视图 文档和视图的关系 文档模板的作用 创建用户自定义类 文档的读写
第一节 文档/视图结构概述 文档和视图的关系 文档模块的功能 设计一个简单的文本编辑器
MFC创建的三种应用程序类结构 • 基于对话框的应用程序类结构 • SDI应用程序类结构 • MDI应用程序类结构
文档和视图的关系 • 数据操作和数据表示的分离
文档/视图应用程序的实现 • 在文档类中定义公有类成员变量描述数据 • 在视图类中的OnDraw()函数中通过pDoc访问文档类中成员变量,输出数据的文本或图形描述 • 定义消息处理函数 • 修改文档数据 • 发出视图更新命令 • 系统接到WM_PAINT消息,自动调用OnDraw函数,OnDraw函数再次访问文档数据,并重新绘制视图,反应文档数据的变化。
文档模块的功能 • 创建 • 文档类 • 视图类 • 为视图类提供显示的框架窗口类
动态分配SDI文档模板对象 CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CEXSDIDoc ), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CEXSDIView); AddDocTemplate(pDocTemplate); 注:代码摘自应用程序类的InitInstance(),程序名为EXSDI
动态分配MDI文档模板对象 CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MULTITYPE, RUNTIME_CLASS(CMultiDoc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CMultiView)); AddDocTemplate(pDocTemplate); // create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; 注:代码摘自应用程序类的InitInstance(),程序名为EXMDI
例8-1 设计一个简单的文本编辑器 • 视图类不从CEditView继承 文档类 CStringList Lines //字符串列表保存若干行文本 int nLineNum //当前编辑行行号 • 按键消息处理函数OnChar() • 增加一个字符或一行到Lines • 更新视图 视图类 InitUpdate() Ondraw()
第二节 创建用户自定义类 使用Object类 支持持续性和动态性的宏 编程实例
CObject类的特性 • 持续性 • 内存中的对象数据可保存到永久介质中 • 动态性 • IsKindOf(CRunTimeClass *ptr) • 诊断性 • 将对象状态转储给调用机制 • AssertValid() • Dump()
void CEXSDIDoc::AssertValid() const { ASSERT(!m_Name.IsEmpty());//不能为空 ASSERT(!(m_Age<0));//不能小于0 CDocument::AssertValid(); } void CEXSDIDoc::Dump(CDumpContext& dc) const { dc<<"m_Name:"<<m_Name<<"\n"; dc<<"m_Age:"<<m_Age<<"\n"; CDocument::Dump(dc); } 使用诊断性成员函数示例... 判断两个成员变量的值是否有效,无效将中止程序运行 将两个成员变量的当前值输出到Debug窗口
使用诊断性成员函数示例 CEXSDIDoc::~CEXSDIDoc() { #ifdef _DEBUG Dump(afxDump); #endif //_DEBUG } 调用Dump()函数,在OutPut窗口中观察中间结果
支持持续性和动态性的宏 • 支持动态性服务 • DECLARE_DYNAMIC • IMPLMENT_DYNAMIC • 支持对象的动态创建 • DECLARE_DYNCREATE • IMPLMENT_DYNCREATE • 提供对象的持续性 • DECLARE_SERIAL • IMPLMENT_SERIAL
例8-2 创建CStudent类及应用 • 创建CStudent类 • CFormView的使用
第三节 文档读写 文档序列化原理 序列化与数据类型 使用复杂的文档数据
文档序列化原理 • Serialize() • CArchive类对象ar • CArchive类的缓冲机制读写CFile类
WORD LONG DWORD int float double char unsigned CSize CPoint CRect CString ar的操作类型
MFC提供的集合类 • List • CList,CObList,CPtrList,CTypedPtrList,CStringList • Array • CObArray,CByteArray,CDWordArray,CPtrArray,CStringArray,CTypedPtrArray。 • Map • CMap,CTypedPtrMap
CObArray • 多用于存放用户自定义类对象 • 操作函数 • Add() • GetSize() • GetAt() • RemoveAt() • Serialize()
复杂数据的序列化 • 用户自定义类需要定义Serialize()处理成员变量的输入输出 • 使用CObArray类管理多个对象 • 在文档类的Serialize()函数中,直接调用CObArray类的成员函数Serialize()实现序列化,该函数会处理数组成员的序列化操作。
void CStudent::Serialize(CArchive &ar)//序列化函数实现 { if (ar.IsStoring()) { // TODO: add storing code here ar<<m_Grade<<m_Name; } else { // TODO: add loading code here ar>>m_Grade>>m_Name; } void CExam8_3Doc::Serialize(CArchive& ar) { m_ObArray.Serialize(ar); } 示例 使用CStudent类的序列化
例8-3 录入学生记录 • 使用CObArray类实现CStudent类的序列化。