友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

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

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


                           BOOL IsBufferEmpty() const; 



                           CFile* GetFile() const; 



532 


…………………………………………………………Page 595……………………………………………………………

                                                  第8章    Document…View  深入探討 



        UINT GetObjectSchema(); // only valid when reading a CObject* 

        void SetObjectSchema(UINT nSchema); 



        // pointer to document being serialized …must set to serialize 

        //  COleClientItems in a document! 

        CDocument* m_pDocument; 



// Operations 

        UINT Read(void* lpBuf; UINT nMax); 

        void Write(const void* lpBuf; UINT nMax); 

        void Flush(); 

        void Close(); 

        void Abort();   // close and shutdown without exceptions 



        // reading and writing strings 

        void WriteString(LPCTSTR lpsz); 

        LPTSTR ReadString(LPTSTR lpsz; UINT nMax); 

        BOOL ReadString(CString& rString); 



public: 

        // Object I/O is pointer based to avoid added construction overhead。 

        // Use the Serialize member function directly for embedded objects。 

        friend CArchive& AFXAPI operator(CArchive& ar; CObject*& pOb); 

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



        // insertion operations 

        CArchive& operator(unsigned& u); 



                             // object read/write 

                             CObject* ReadObject(const CRuntimeClass* pClass); 

                             void WriteObject(const CObject* pOb); 

                             // advanced object mapping (used for forced references) 

                             void MapObject(const CObject* pOb); 



                             // advanced versioning support 

                             void WriteClass(const CRuntimeClass* pClassRef); 

                             CRuntimeClass* ReadClass(const CRuntimeClass* pClassRefRequested = NULL; 

                                     UINT* pSchema = NULL; DWORD* pObTag = NULL); 

                             void SerializeClass(const CRuntimeClass* pClassRef); 

                             。。。 

                     protected: 

                             // array/map for CObject* and CRuntimeClass* load/store 

                             UINT m_nMapCount; 

                             union 

                             { 

                                     CPtrArray* m_pLoadArray; 

                                     CMapPtrToPtr* m_pStoreMap; 

                             }; 

                             // map to keep track of mismatched schemas 

                             CMapPtrToPtr* m_pSchemaMap; 

                             。。。 

                     }; 



                    这些多载运算子均定义于AFX。INL 文件中。另有些函数可能你会觉得眼熟,没错,它 



                    们在稍早的「台面下的Serialize 奥秘」中已经出现过了,它们是ReadObject 、WriteObject  、 



                    ReadClass 、WriteClass。 



                    各种类型的operator》》 和operator》(CArchive& ar; const CObject*& pOb) 

         { pOb = ar。ReadObject(NULL); return ar; } 



其中CArchive::WriteObject 先把类别的CRuntimeClass 信息写出, 再调用类别的 



Serialize  函数。CArchive::ReadObject  的行为类似,先把类别的CRuntimeClass 信息读入, 



再调用类别的Serialize  函数。Serialize 是CObject 的虚拟函数,因此你必须确定你的 



类别改写的Serialize  函数的回返值和参数类型都符合CObject 中的声明:传回值为 



void ,唯一一个参数为CArchive&。 



  注意:CString、CRect、CSize、CPoint 并不衍生自CObject,但它们也可以直接使用针 



  对CArchive 的》 运算子,因为它们自己设计了一套: 



 // in AFX。H 

 class CString 

 { 

     friend CArchive& AFXAPI operator(CArchive& ar; CString& string); 

     。。。 

 }; 



 // in AFXWIN。H 

 // Serialization 

 CArchive& AFXAPI operator(CArchive& ar; RECT& rect); 



一个类别如果希望有Serialization 机制,它的第二要件就是使用SERIAL 宏。这个巨 



集包容DYNCREATE 宏,并且在类别的声明之中加上: 



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



在类别的实作档中加上: 



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

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

                 return ar; }  



                                                                                      535 


…………………………………………………………Page 598……………………………………………………………

                 第篇    深入  MFC  程式設計 



                 如果我的类别名为CStroke,那么经由 



                 class CStroke : public CObject 

                 { 

                    。。。 

                    DECLARE_SERIAL(CStroke) 

                 } 



                 和 



                 IMPLEMENT_SERIAL(CStroke; CObject; 1) 



                 我就获得了两组和CArchive 读写动作的关键性程序代码: 



                 class CStroke : CObject 

                 { 

                    。。。 

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

                 } 



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

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

                                 return ar; } 



                 好,你看到了,为什么只改写operator》》 ,而没有改写operator》(CArchive& ar; class_name* &pOb)  

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

                              return ar; }  



      也就是,令CreateObject 函数为NULL ,这才能够使用于抽象类别之中。 



在 CObList 中加入 CStroke 以外的类別 



      Scribble Document 倾印码中的那个代表「旧类别」的8001 一直令我如坐针毡。不知道 



      什么情况下会出现8002?或是8003?或是什么其它东东。因此,我打算做点测试。除 



       了CStroke,我打算再加上CRectangle 和CCircle 两个类别,并把其对象挂到CObList 



       中。这个修改纯粹为了测试不同类别写到文件档中会造成什么后果,没有考虑使用者介 



      面或任何外围因素,我并不是真打算为Scribble 加上画四方形和画圆形的功能(不过如 



                                                                                    537 


…………………………………………………………Page 600……………………………………………………………

                   第篇    深入  MFC  程式設計 
返回目录 上一页 下一页 回到顶部 0 0
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!