• MFC深入浅出读书笔记第三部分1


    第八章 Document-View 深入探讨(总结)

      1、Document

      Document 在MFC 的CDocument 里头被具体化。CDocument 本身并无任何具体数据,它只是提供一个空壳。当你开发自己的程序,应该从CDocument 衍生出一个属于自己的Document 类别,并且在类别中声明一些成员变量,用以承载(容纳)数据。然后再(至少)改写专门负责文件读写动作的Serialize 函数。应为他派生至CObject,所有它有CObject 所支持的一切性质,包括执行时期型别信息(RTTI)、动态生成(Dynamic Creation)、文件读写(Serialization)。

      2、View

      View 负责描述Document中的资料,也是在在MFC 的CView 里头被具体化。它只是提供一个空壳。当你开发自己的程序,应该从CView 衍生出一个属于自己的View 类别,并且在类别中(至少)改写专门负责显示资料OnDraw 函数(针对屏幕)或OnPrint 函数(针对打印机)。由于CView 衍生自CWnd,所以它可以接收一般Windows 消息(如WM_SIZE、WM_PAINT 等等),又由于它也衍生自CCmdTarget,所以它可以接收来自菜单或工具列的WM_COMMAND 消息。

       3、Frame

      框架窗口在Document/View之上,主要管理UI。 其中对象的生成过程如下:

      4、 Document Template

      MFC 把Document/View/Frame 视为三位一体。其中用 Document Template来管理这个"三人组合"。MFC 有一个CDocTemplate 负责此事。它又有两个

    衍生类别,分别是CMultiDocTemplate 和CSingleDocTemplate。而Document Template的控制来自CWinApp。

     1 BOOL CTestApp::InitInstance()//其中的
     2 {
     3         ...
     4         CMultiDocTemplate* pDocTemplate;
     5         pDocTemplate = new CMultiDocTemplate(
     6                 IDR_SCRIBTYPE,           //资源符号
     7                 RUNTIME_CLASS(CScribbleDoc),    //Document
     8                 RUNTIME_CLASS(CChildFrame),     //Frame
     9                 RUNTIME_CLASS(CScribbleView));  //View
    10         AddDocTemplate(pDocTemplate);           //添加到管理模板
    11         ...
    12 }        

      5、Serialize:对象的文件读写

      Serializable 的必要条件:欲让一个对象有Serialize 能力,它必须衍生自一个Serializable 类别。一个类别意欲成Serializable,必须有下列五大条件;

        1. CObject 衍生下来。如此一来可保有RTTIDynamic Creation 等机能。

        2. 类别的声明部份必须有DECLARE_SERIAL 宏。此宏需要一个参数:类别名称。

        3. 类别的实作部份(cpp文件)必须有IMPLEMENT_SERIAL 宏。此宏需要三个参数:一是类别名称,二是父类别名称,三是schema no.

        4. 改写Serialize 虚拟函数,使它能够适当地把类别的成员变量写入文件中。

        5. 为此类别加上一个default 构造式(也就是无参数之构造式)。这个条件常为人所忽略,但它是必要的,因为若一个对象来自文件,MFC 必须先动态生成 它,而且在没有任何参数的情况下调用其构造式,然后才从文件中读出对象资料。

      6、DYNAMIC / DYNCREATE / SERIAL 三“宏”

        DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC     //运行时类型识别

        DECLARE_DYNCREATE / IMPLEMENT_DYNCREATE //动态生成

        DECLARE_SERIAL / IMPLEMENT_SERIAL       //文件读写

      7、CObject 类别的最基本虚函数 ---- IsKindOf 和IsSerializable

        IsKindOf()函数,顾名思义,是用来判断一个类是不是派生至某个类。

    1 BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const

        IsSerializable()函数

      在程序在执行时期判断某类别的schema 号码是否为0xFFFF,藉此得知它是否可以Serialize。其中schema是MFC配置的,如果一个类能Serialize,那么就要将它的schema号码设置为0xFFFF。

    1 BOOL CObject::IsSerializable() const
    2 {
    3   return (GetRuntimeClass()->m_wSchema != 0xffff);//
    4 }

      8、CArchive 类别 ----一块内存缓冲区

      CArchive对运算符进行的重载operator<<  和  operator>>。这对运算符除了实现对基本类型的输入输出,还可以实现继承至CObject的类的输入输出,而如果其他类想使用的话,可以对运算符进行重载。

      如何在一个类中显示串行化

      首先这个类要继承至CObject,然后在头文件里声明如下

    1  DECLARE_SERIAL(CRectangle);
    2 
    3  virtual void Serialize(CArchive& ar);//重载Serialize函数

      //CPP文件里实现如下

    1  IMPLEMENT_SERIAL(CRectangle, CObject, 1);
    2 
    3 void CRectangle::Serialize(CArchive& ar)
    4  {
    5           if (ar.IsStoring())
    6                  ar << m_rect;//
    7           else
    8                  ar >> m_rect;//
    9   }

      一章又一章,好多东西看过就忘了,现在记下来,以后复习也方便了。

  • 相关阅读:
    Java 的字符串,String、StringBuffer、StringBuilder 有什么区别?
    访问一个HTTPS的网站的大致流程
    Spring Boot Mybatis-Plus
    Spring Boot REST
    Spring Boot 以 war 方式部署
    MVC 框架
    HDFS,MongoDB,HBase的区别和使用场景
    什么时候该用NoSQL?
    最近和朋友微信卖螃蟹有点偏离重心了
    我要出去~
  • 原文地址:https://www.cnblogs.com/songliquan/p/3283824.html
Copyright © 2020-2023  润新知