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

第101部分

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

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

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






      关文件、读文件、写文件、搜寻资料。。。。MFC 把这些操作都包装在CFile 之中。可想而知,它 



      必然有Open、Close、Read 、Write、Seek 。。。 等等成员函数。下面这段程序代码示范CFile 如 



      何读档: 



       char* pBuffer = new char'0x8000'; 

       CFile file(〃mydoc。doc〃; CFile::modeRead);  //  

                                                     打开mydoc。doc 文件,使用只读模式。 

       UINT nBytesRead = file。Read(pBuffer; 0x8000); // 读取8000h 个字节到pBuffer 中。 



       上述程序片段中,对象file   的构造式将打开mydoc。doc 档。并且由于此对象产生于函数 



       的堆栈之中,当函数结束,file   的析构式将自动关闭mydoc。doc 档。 



       开文件模式有许多种,都定义在CFile             (AFX。H )之中: 



       enum OpenFlags { 

             modeRead =    0x0000;  //只读 

             modeWrite =         0x0001;  // 唯写 

             modeReadWrite =0x0002;  // 可读可写 

             sharepat =      0x0000; 



            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(th

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

你可能喜欢的