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

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

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

            shareExclusive =    0x0010; // 唯我使用 

             shareDenyWrite =    0x0020; 

             shareDenyRead =0x0030; 

             shareDenyNone =0x0040; 

             modeNoInherit =0x0080; 

             modeCreate =        0x1000;  //产生新档(甚至即使已有相同名称之文件存在) 

             modeNoTruncate =   0x2000; 

             typeText =    0x4000; // typeText and typeBinary are used in 

             typeBinary =       (int)0x8000 // derived classes only 

             }; 

                   typeText = 0x4000; // typeText and typeBinary are used in 



                   typeBinary = (int)0x8000 // derived classes only 



                   }; 



                                                                                       499 


…………………………………………………………Page 562……………………………………………………………

                    第篇    深入  MFC  程式設計 



                    再举一例,下面这段程序代码可将文件mydoc。doc  的所有文字转换为小写: 



                        char* pBuffer = new char'0x1000'; 

                        CFile file(〃mydoc。doc〃; CFile::modeReadWrite); 

                        DWORD dwBytesRemaining = file。GetLength(); 

                        UINT nBytesRead; 

                        DWORD dwPosition; 



                        while (dwBytesRemaining) { 

                            dwPosition = file。GetPosition(); 

                            nBytesRead = file。Read(pBuffer; 0x1000); 

                            ::CharLowerBuff(pBuffer; nBytesRead); 

                            file。Seek((LONG)dwPosition; CFile::begin); 

                            file。Write(pBuffer; nBytesRead); 

                            dwBytesRemaining …= nBytesRead; 

                         } 

                        delete'' pBuffer; 



                      文件的操作常需配合对异常情况(exception )的处理,因为文件的异常情况特别多:档 



                      案找不到啦、文件handles 不足啦、读写失败啦。。。。上一例加入异样情况处理后如下: 



                        char* pBuffer = new char'0x1000'; 



                        try { 

                            CFile file(〃mydoc。doc〃; CFile::modeReadWrite); 

                            DWORD dwBytesRemaining = file。GetLength(); 

                            UINT nBytesRead; 

                            DWORD dwPosition; 



                            while (dwBytesRemaining) { 

                                dwPosition = file。GetPosition(); 

                                nBytesRead = file。Read(pBuffer; 0x1000); 

                                ::CharLowerBuff(pBuffer; nBytesRead); 

                                file。Seek((LONG)dwPosition; CFile::begin); 

                                file。Write(pBuffer; nBytesRead); 

                                dwBytesRemaining …= nBytesRead; 

                            } 

                         } 

                        catch (CFileException* e) { 

                            if (e…》cause == CFileException::fileNoteFound) 

                                MessageBox(〃File not found〃); 

                            else if (e…》cause == CFileException::tooManyOpeFiles) 

                                MessageBox(〃File handles not enough〃); 

                            else if (e…》cause == CFileException::hardIO) 



500 


…………………………………………………………Page 563……………………………………………………………

                                                          第8章    Document…View  深入探討 



                MessageBox(〃Hardware error〃); 

            else if (e…》cause == CFileException::diskFull) 

                MessageBox(〃Disk full〃); 

            else if (e…》cause == CFileException::badPath) 

                MessageBox(〃All or part of the path is invalid〃); 

            else 

                MessageBox(〃Unknown file error〃); 

            e…》Delete(); 

         } 

        delete'' pByffer; 



台面上的Serialize 动作 



    让我以Scribble 为例,向你解释台面上的(应用程序代码中可见的)serialization 动作。根 



    据图8…3 的数据结构,Scribble 程序的文件读写动作是这么分工的: 



     Framework 调用CSribbleDoc::Serialize,用以对付文件。 



      CScribbleDoc 再往下调用CStroke::Serialize,用以对付线条。 



        

       CStroke 再往下调用CArray::Serialize,用以对付点数组。 

         



     读也由它,写也由它,究竟Serialize 是读还是写?这一点不必我们操心。Framework 呼 

        



     Serialize 时会传来一个CArchive 对象(稍后我会解释CArchive),你可以想象它 



     代表一个文件,透过其IsStoring 成员函数,即可知道究竟要读还是写。图8…5 是各层 



     叫 

     级的Serialize 动作示意图,文字说明已在图片之中。 



      注意:Scribble 程序使用CArray 储存鼠标位置坐标,而CArray 是 



      一个template class ,解释起来比较复杂。所以稍后我挖给各位看的Serialize  函数原始 



      码,采用CDWordArray 的成员函数而非CArray 的成员函数。Visual C++ 1。5 版的 



      Scribble 范例程序就是使用CDWordArray           (彼时还未有template class )。 



      然而,为求完备,我还是在此先把CArray 的Serialize  函数源代码列出: 



     template 

    void AFXAPI SerializeElements (CArchive& ar; TYPE* pElements; int nCount) 

     { 

            ASSERT(nCount == 0 || 



                                                                                              501 


…………………………………………………………Page 564……………………………………………………………

                      第篇    深入  MFC  程式設計 



                                      AfxIsValidAddress(pElements; nCount * sizeof(TYPE))); 



                              // default is bit…wise read/write 

                              if (ar。IsStoring()) 

                                      ar。Write ((void*)pElements; nCount * sizeof(TYPE)); 

                              else 

                                      ar。Read ((void*)pElements; nCount * sizeof(TYPE)); 

                      } 



                      template 

                      void CArray::Serialize(CArchive& ar) 

                      { 

                              ASSERT_VALID(this); 

                              CObject::Serialize(ar); 

                              if (ar。IsStoring()) 

                              { 

                                      ar。WriteCount (m_nSize); 

                              } 

                              else 

                              { 

                                      DWORD nOldSize = ar。ReadCount (); 

                                      SetSize (nOldSize; …1); 

                              } 

                              SerializeElements (ar; m_pData; m_nSize); 

                      } 



                       void CScribbleDoc::Serialize(CArchive& ar) 

                                                                         2 CObList::Serialize(Carchive& ar) 

                       {                                                    { 。。。 }  //源代码请看图8…5b 

                               if (ar。IsStoring()) 

                                   {    } 

                                                                                 m_strokeList 是 

                               else 

                                   {    }                                          CObList  对象 

                             1 

                               m_strokeList。Serialize(ar); 

                       } 

                       //…………………………………………………………………………………………………………                到   的过程并非显而易见, 

                                                                                     

                       void CStroke::Serialize(CArchive& ar) 3                       下一节将有详细说明。 

                       { 

                               if (ar。IsStoring()) { 

                                   ar 》 w;                              5 CDWordArray::Serialize(Carchive& ar) 

                                   m_nPenWidth = w;                         { 。。。 }  //源代码请看图8…5c 

                                   m_pointArray。Serialize(ar); 

                               } 

                       } 



                             图8…5a Scribble Step1 的文件读写 (档)动作 



502 


…………………………………………………………Page 565……………………………………………………………

                                                       第8章    Document…View  深入探討 



void CObList::Serialize(CArchive& ar) 

{ 

    ASSERT_VALID(this); 

    CObject::Serialize(ar); 

    if (ar。IsStoring()) 

    { 

        ar。WriteCount(m_nCount); 

        for (CNode* pNode = m_pNodeHead; pNode != NULL; 

             pNode = pNode…》pNext) 

        {    // J。J。Hou :针对串行中的每一个元素写文件 



            ASSERT(AfxIsValidAddress(pNode; sizeof(CNode))); 

            ar data; 

        } 

                                               这将引发CArchive 的多载 

    } 

    else                                    else 运算子,稍后有深入说明。 

    { 

        DWORD nNewCount = ar。ReadCount(); 

        CObject* newData; 

        while  (nNewCount……) 

        {   // 

              J。J。Hou : 一一读入文件内容,加入串行 

            ar 》》 newData; 

            AddTail(newData); 

        } 

    } 

} 



                     图8…5b CObList::Serialize 源代码 



void CDWordArray::Serialize(CArchive& ar) 

{ 

    ASSERT_VALID(this); 

    CObject::Serialize(ar); 

    if (ar。IsStoring()) 

    { 

        ar。WriteCount(m_nSize);             //  

                                                  把数组大小(元素个数)写入ar 

        ar。Write(m_pData; m_nSize * sizeof(DWORD));  //把整个数组写入ar 

    } 

    else 

    { 

        DWORD nOldSize = ar。ReadCount(); 

        SetSize(nOldSize);                    // 从 ar 中读出数组大小(元素个数) 

        ar。Read(m_pData; m_nSize * sizeof(DWORD));   //  ar ar ar  

                                                              从     中读出整个数组 

    } 

} 



                     图8…5c CDWordArray::Serialize 源代码 



                                                                                            503 


…………………………………………………………Page 566……………………………………………………………

                 第篇    深入  MFC  程式設計 



                            File/Save 

                           【      】 



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