八宝书库 > 文学其他电子书 > 深入浅出MFC第2版(PDF格式) >

第42部分

深入浅出MFC第2版(PDF格式)-第42部分

小说: 深入浅出MFC第2版(PDF格式) 字数: 每页4000字

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




    else { 

        WORD nNewCount; 

        ar 》》 nNewCount; 

        while (nNewCount……) { 

            CObject* newData; 

            ar 》》 newData; 

            AddTail(newData); 

        } 

    } 

} 



void CStroke::Serialize(CArchive& ar) 

{ 

    m_ptArray。Serialize(ar); 

} 



void CDWordArray::Serialize(CArchive& ar) 

{ 

    if (ar。IsStoring()) { 

        ar  nOldSize; 

        for (int i = 0; i 《 m_nSize; i++) 

            ar 》》 m_pData'i'; 

    } 

} 



void CRectangle::Serialize(CArchive& ar) 

{ 

    if (ar。IsStoring()) 

        ar 》 m_rect; 

} 



void CCircle::Serialize(CArchive& ar) 

{ 

    if (ar。IsStoring()) { 



                                                                                          165 


…………………………………………………………Page 228……………………………………………………………

                    第篇  勿在浮砂築高台 



                            ar 》 (WORD&)m_center。y; 

                            ar 》》 (WORD&)m_radius; 

                        } 

                    } 



                 每一个可写到文件或可从文件中读出的类别,都应该有它自己的Serailize  函数,负责它 



                 自己的资料读写文件动作。此类别并且应该改写》 运算子,把资料导流到 



                 archive  中。archive 是什么?是一个与文件息息相关的缓冲区,暂时你可以想象它就是 



                 文件的化身。当图3…3 的文件写入文件时,Serialize  函数的调用次序如图3…4 。 



                                  CMyDoc::Serialize 



                                   CObList::Serialize 



                                      如果串行元素是圆 

                                                          CStroke::Serialize 



                                                                CDWordArray::Serialize 



                                      如果串行元素是矩形 

                                                         CRectangle::Serialize 



                                      如果串行元素是线条 

                                                         CCircle::Serialize 



                     图3…4 图3…3 的文件内容写入文件时,Serialize 函数的调用次序。 



166 


…………………………………………………………Page 229……………………………………………………………

                                                         第3章    MFC 六大關鍵技術之模擬 



DECLARE_SERIAL / IMPLEMENT_SERIAL 宏 



     要将》 两个运算子多载化,还要让Serialize  函数神不知鬼不觉地放入类别声明 



     之中,最好的作法仍然是使用宏。 



     类别之能够进行文件读写动作,前提是拥有动态生成的能力,所以,MFC 设计了两个宏 



     DECLARE_SERIAL 和IMPLEMENT_SERIAL : 



      #define DECLARE_SERIAL(class_name)  

              DECLARE_DYNCREATE(class_name)  

              friend CArchive& AFXAPI operator》》(CArchive& ar; class_name* &pOb); 



      #define IMPLEMENT_SERIAL(class_name; base_class_name; wSchema)  

              CObject* PASCAL class_name::CreateObject()  

                      { return new class_name; }  

              _IMPLEMENT_RUNTIMECLASS(class_name; base_class_name; wSchema;  

                      class_name::CreateObject)  

              CArchive& AFXAPI operator》》(CArchive& ar; class_name* &pOb)  

                    { pOb = (class_name*) ar。ReadObject(RUNTIME_CLASS(class_name));  

                              return ar; }  



      为了在每一个对象被处理(读或写)之前,能够处理琐屑的工作,诸如判断是否第一次 



      出现、记录版本号码、记录文件名等工作,CRuntimeClass 需要两个函数Load 和Store 

                                                                                    : 

      struct CRuntimeClass 

      { 

      // Attributes 

              LPCSTR m_lpszClassName; 

              int m_nObjectSize; 

              UINT m_wSchema; // schema number of the loaded class 

              CObject* (PASCAL* m_pfnCreateObject)(); // NULL =》 abstract class 

              CRuntimeClass* m_pBaseClass; 



              CObject* CreateObject(); 

              void Store(CArchive& ar) const; 

              static CRuntimeClass* PASCAL Load(CArchive& ar; UINT* pwSchemaNum); 



              // CRuntimeClass objects linked together in simple list 

              static CRuntimeClass* pFirstClass; // start of class list 

              CRuntimeClass* m_pNextClass;     // linked list of registered classes 

      }; 



                                                                                            167 


…………………………………………………………Page 230……………………………………………………………

                    第篇  勿在浮砂築高台 



                    你已经在上一节看过Load  函数,当时为了简化,我把它的参数拿掉,改为由屏幕上获 



                    得类别名称,事实上它应该是从文件中读一个类别名称。至于Store  函数,是把类别名 



                    称写入文件中: 



                    // Runtime class serialization code 

                    CRuntimeClass* PASCAL CRuntimeClass::Load(CArchive& ar; UINT* pwSchemaNum) 

                    { 

                        WORD nLen; 

                        char szClassName'64'; 

                        CRuntimeClass* pClass; 



                        ar 》》 (WORD&)(*pwSchemaNum) 》》 nLen; 



                        if (nLen 》= sizeof(szClassName) || ar。Read(szClassName; nLen) != nLen) 

                                return NULL; 

                        szClassName'nLen' = '0'; 



                        for (pClass = pFirstClass; pClass != NULL; pClass = pClass…》m_pNextClass) 

                        { 

                            if (lstrcmp(szClassName; pClass…》m_lpszClassName) == 0) 

                                return pClass; 

                        } 

                        return NULL; // not found 

                    } 



                    void CRuntimeClass::Store(CArchive& ar) const 

                            // stores a runtime class description 

                    { 

                            WORD nLen = (WORD)lstrlenA(m_lpszClassName); 

                            ar 

返回目录 上一页 下一页 回到顶部 0 0

你可能喜欢的