⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap7_5.htm

📁 VC++编程实例。非常详细
💻 HTM
📖 第 1 页 / 共 3 页
字号:
          <p><font  face="Times New Roman"><b>DeleteContents();</b></font></p>
          <p><font  face="Times New Roman"><b>BeginWaitCursor();</b></font></p>
          <p><font  face="Times New Roman"><b>// replace calls to Serialize 
            with ReadDIBFile function</b></font></p>
          <p><font  face="Times New Roman"><b>TRY</b></font></p>
          <p><font  face="Times New Roman"><b>{</b></font></p>
          <p><font  face="Times New Roman"><b>m_hDIB = ::ReadDIBFile(file);</b></font></p>
          <p><font  face="Times New Roman"><b>}</b></font></p>
          <p><font  face="Times New Roman"><b>CATCH (CFileException, eLoad)</b></font></p>
          <p><font  face="Times New Roman"><b>{</b></font></p>
          <p><font  face="Times New Roman"><b>file.Abort(); // will not 
            throw an exception</b></font></p>
          <p><font  face="Times New Roman"><b>EndWaitCursor();</b></font></p>
          <p><font  face="Times New Roman"><b>ReportSaveLoadException(lpszPathName, 
            eLoad,</b></font></p>
          <p><font  face="Times New Roman"><b>FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);</b></font></p>
          <p><font  face="Times New Roman"><b>m_hDIB = NULL;</b></font></p>
          <p><font  face="Times New Roman"><b>return FALSE;</b></font></p>
          <p><font  face="Times New Roman"><b>}</b></font></p>
          <p><font  face="Times New Roman"><b>END_CATCH</b></font></p>
          <p><font  face="Times New Roman"><b>InitDIBData();</b></font></p>
          <p><font  face="Times New Roman"><b>EndWaitCursor();</b></font></p>
          <p><font  face="Times New Roman"><b>if (m_hDIB == NULL)</b></font></p>
          <p><font  face="Times New Roman"><b>{</b></font></p>
          <p><font  face="Times New Roman"><b>// may not be DIB format</b></font></p>
          <p><font  face="Times New Roman"><b>CString strMsg;</b></font></p>
          <p><font  face="Times New Roman"><b>strMsg.LoadString(IDS_CANNOT_LOAD_DIB);</b></font></p>
          <p><font  face="Times New Roman"><b>MessageBox(NULL, strMsg, 
            NULL, MB_ICONINFORMATION | MB_OK);</b></font></p>
          <p><font  face="Times New Roman"><b>return FALSE;</b></font></p>
          <p><font  face="Times New Roman"><b>}</b></font></p>
          <p><font  face="Times New Roman"><b>SetPathName(lpszPathName);</b></font></p>
          <p><font  face="Times New Roman"><b>SetModifiedFlag(FALSE); 
            // start off with unmodified</b></font></p>
          <p><font  face="Times New Roman">return TRUE;</font></p>
          <p><font  face="Times New Roman">}</font></p>
          <p><font  face="Times New Roman">BOOL CDibDoc::OnSaveDocument(LPCTSTR 
            lpszPathName)</font></p>
          <p><font  face="Times New Roman">{</font></p>
          <p><font  face="Times New Roman">CFile file;</font></p>
          <p><font  face="Times New Roman">CFileException fe;</font></p>
          <p><font  face="Times New Roman">if (!file.Open(lpszPathName, 
            CFile::modeCreate |</font></p>
          <p><font  face="Times New Roman">CFile::modeReadWrite | CFile::shareExclusive, 
            &amp;fe))</font></p>
          <p><font  face="Times New Roman">{</font></p>
          <p><font  face="Times New Roman">ReportSaveLoadException(lpszPathName, 
            &amp;fe,</font></p>
          <p><font  face="Times New Roman">TRUE, AFX_IDP_INVALID_FILENAME);</font></p>
          <p><font  face="Times New Roman">return FALSE;</font></p>
          <p><font  face="Times New Roman">}</font></p>
          <p><font  face="Times New Roman"><b>// replace calls to Serialize 
            with SaveDIB function</b></font></p>
          <p><font  face="Times New Roman"><b>BOOL bSuccess = FALSE;</b></font></p>
          <p><font  face="Times New Roman"><b>TRY</b></font></p>
          <p><font  face="Times New Roman"><b>{</b></font></p>
          <p><font  face="Times New Roman"><b>BeginWaitCursor();</b></font></p>
          <p><font  face="Times New Roman"><b>bSuccess = ::SaveDIB(m_hDIB, 
            file);</b></font></p>
          <p><font  face="Times New Roman"><b>file.Close();</b></font></p>
          <p><font  face="Times New Roman"><b>}</b></font></p>
          <p><font  face="Times New Roman"><b>CATCH (CException, eSave)</b></font></p>
          <p><font  face="Times New Roman"><b>{</b></font></p>
          <p><font  face="Times New Roman"><b>file.Abort(); // will not 
            throw an exception</b></font></p>
          <p><font  face="Times New Roman"><b>EndWaitCursor();</b></font></p>
          <p><font  face="Times New Roman"><b>ReportSaveLoadException(lpszPathName, 
            eSave,</b></font></p>
          <p><font  face="Times New Roman"><b>TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);</b></font></p>
          <p><font  face="Times New Roman"><b>return FALSE;</b></font></p>
          <p><font  face="Times New Roman"><b>}</b></font></p>
          <p><font  face="Times New Roman"><b>END_CATCH</b></font></p>
          <p><font  face="Times New Roman"><b>EndWaitCursor();</b></font></p>
          <p><font  face="Times New Roman"><b>SetModifiedFlag(FALSE); 
            // back to unmodified</b></font></p>
          <p><font  face="Times New Roman"><b>if (!bSuccess)</b></font></p>
          <p><font  face="Times New Roman"><b>{</b></font></p>
          <p><font  face="Times New Roman"><b>// may be other-style DIB 
            (load supported but not save)</b></font></p>
          <p><font  face="Times New Roman"><b>// or other problem in SaveDIB</b></font></p>
          <p><font  face="Times New Roman"><b>CString strMsg;</b></font></p>
          <p><font  face="Times New Roman"><b>strMsg.LoadString(IDS_CANNOT_SAVE_DIB);</b></font></p>
          <p><font  face="Times New Roman"><b>MessageBox(NULL, strMsg, 
            NULL, MB_ICONINFORMATION | MB_OK);</b></font></p>
          <p><font  face="Times New Roman"><b>}</b></font></p>
          <p><font  face="Times New Roman"><b>return bSuccess;</b></font></p>
          <p><font  face="Times New Roman">}</font></p>
          <p><font  face="Times New Roman"><b>void CDibDoc::ReplaceHDIB(HDIB 
            hDIB)</b></font></p>
          <p><font  face="Times New Roman"><b>{</b></font></p>
          <p><font  face="Times New Roman"><b>if (m_hDIB != NULL)</b></font></p>
          <p><font  face="Times New Roman"><b>{</b></font></p>
          <p><font  face="Times New Roman"><b>::GlobalFree((HGLOBAL) m_hDIB);</b></font></p>
          <p><font  face="Times New Roman"><b>}</b></font></p>
          <p><font  face="Times New Roman"><b>m_hDIB = hDIB;</b></font></p>
          <p><font  face="Times New Roman"><b>}</b></font></p>
          <p><font  face="Times New Roman">/////////////////////////////////////////////////////////////////////////////</font></p>
          <p><font  face="Times New Roman">// CDibDoc diagnostics</font></p>
          <p><font  face="Times New Roman">#ifdef _DEBUG</font></p>
          <p><font  face="Times New Roman">void CDibDoc::AssertValid() 
            const</font></p>
          <p><font  face="Times New Roman">{</font></p>
          <p><font  face="Times New Roman">CDocument::AssertValid();</font></p>
          <p><font  face="Times New Roman">}</font></p>
          <p><font  face="Times New Roman">void CDibDoc::Dump(CDumpContext&amp; 
            dc) const</font></p>
          <p><font  face="Times New Roman">{</font></p>
          <p><font  face="Times New Roman">CDocument::Dump(dc);</font></p>
          <p><font  face="Times New Roman">}</font></p>
          <p><font  face="Times New Roman">#endif //_DEBUG</font></p>
          <p><font  face="Times New Roman">/////////////////////////////////////////////////////////////////////////////</font></p>
          <p><font  face="Times New Roman">// CDibDoc commands</font></p>
          <p><font  face="Times New Roman">   DIBLOOK</font><font >读入和保存标准的</font><font 
        face="Times New Roman">Windows</font><font >设备无关位图。在内存中,位图以一个</font><font  face="Times New Roman">HDIB</font><font >句柄表示。</font><font  face="Times New Roman">DIBLOOK</font><font >没有重  载</font><font 
        face="Times New Roman">CDocument::Serialize()</font><font >函数,而是重载了</font><font 
        face="Times New Roman">CDocument::OnOpenDocument</font><font >和</font><font  face="Times New Roman">CDocument::OnSaveDocument</font><font >函数。这两个函数使用框架传过来得文件路径名</font><font  face="Times New Roman">pszPathName</font><font >,打开一个文件对象,读入或保存</font><font  face="Times New Roman">DIB</font><font >数据。这就是说,</font><font  face="Times New Roman">DIBLOOK</font><font >把本来在</font><font 
        face="Times New Roman">Serialize()</font><font >中完成的对象保存和载入两个任务分别交与</font><font  face="Times New Roman">OnSaveDocument()</font><font >函数和</font><font 
        face="Times New Roman">OnOpenDocument()</font><font >函数去完成。如果读者希望绕过文档的串行化提供文档数据的保存和载入,也只需要重载这两个成员函数:</font><font  face="Times New Roman">OnOpenDocument()</font><font >和</font><font  face="Times New Roman">OnSaveDocument()</font><font >,通过文件路径参数打开文件,从中读取应用程序数据或向文件里写入应用程序数据。</font></p>
          <p><font >  在</font><font 
        face="Times New Roman">OnOpenDocument()</font><font >中,还必需自己调用</font><font 
        face="Times New Roman">DeleteContents()</font><font >清除原来文档的数据,并调用</font><font  face="Times New Roman">SetModifiedFlag(FALSE)</font><font >。在</font><font 
        face="Times New Roman">OnSaveDocument()</font><font >中也要调用</font><font 
        face="Times New Roman">SetModifiedFlag(FALSE)</font><font >将文档修改标志改为</font><font 
        face="Times New Roman">FALSE</font><font >。</font></p>
          <p><font >在</font><font 
        face="Times New Roman">OnOpenDocument()</font><font >函数开始处(见清单</font><font 
        face="Times New Roman">7.18</font><font >),有一些地方需要解释一下。</font></p>
          <p><font ><b>清单</b></font><font 
        face="Times New Roman"><b>7.18 OnOpenDocument()</b></font><font ><b>函数</b></font></p>
          <p><font  face="Times New Roman">BOOL CDibDoc::OnOpenDocument(LPCTSTR 
            lpszPathName)</font></p>
          <p><font  face="Times New Roman">{</font></p>
          <p><font  face="Times New Roman"><b>CFile file;</b></font></p>
          <p><font  face="Times New Roman"><b>CFileException fe;</b></font></p>
          <p><font  face="Times New Roman"><b>if (!file.Open(lpszPathName, 
            CFile::modeRead | CFile::shareDenyWrite, &amp;fe))</b></font></p>
          <p><font  face="Times New Roman"><b>{</b></font></p>
          <p><font  face="Times New Roman"><b>ReportSaveLoadException(lpszPathName, 
            &amp;fe,</b></font></p>
          <p><font  face="Times New Roman"><b>FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);</b></font></p>
          <p><font  face="Times New Roman"><b>return FALSE;</b></font></p>
          <p><font  face="Times New Roman"><b>}</b></font></p>
          <p><font  face="Times New Roman">......</font></p>
          <p><font  face="Times New Roman">}</font></p>
          <p><font color="#3973DE"  face="Times New Roman">7.5.1 </font><font color="#3973DE" >文件操作</font></p>
          <p><font color="#3973DE" >文件读写</font></p>
          <p><font  face="Times New Roman">  OnOpenDocument</font><font >首先声明一个</font><font 
        face="Times New Roman">CFile</font><font >类的对象。</font><font  face="Times New Roman">CFile</font><font >是</font><font  face="Times New Roman">MFC</font><font >提供的一个类,它提供了访问二进制文件的接口。可以使用带参数的</font><font  face="Times New Roman">CFile</font><font >构造函数创建对象,在构造函数中指定了文件名和打开文件的模式,这样在对象创建的同时也就打开了这个文件;也可以象本例那样使用不带参数的</font><font  face="Times New Roman">CFile</font><font >构造函数构造一个</font><font 
        face="Times New Roman">CFile</font><font >对象,然后调用</font><font  face="Times New Roman">CFile::Open()</font><font >打开一个文件。</font></p>
          <blockquote> 
            <blockquote> 
              <p><font  face="Times New Roman"><b>BOOL</b> <b>CFile::Open(</b> 
                <b>LPCTSTR</b> <i>lpszFileName</i><b>,</b> <b>UINT</b> <i>nOpenFlags</i><b>,</b> 
                <b>CFileException*</b> <i>pError</i> <b>=</b> <b>NULL</b> <b>);</b></font></p>
            </blockquote>
          </blockquote>
          <p><font  face="Times New Roman">  CFile::Open</font><font >成员函数带三个参数,第一个参数指定了要打开的文件的完整路径名,如“</font><font  face="Times New Roman">c:\hello\hello.cpp</font><font >”;第二个参数指定打开文件的模式。</font></p>
          <p><font >  常见的文件打开模式有以下几种:</font></p>
          <p><font  face="Times New Roman">  CFile::modeCreate</font><font >:创建一个新文件,如果该文件已经存在,则把该文件长度置为零</font></p>
          <p><font  face="Times New Roman">  CFile::modeNoTruncate</font><font >:与</font><font 
        face="Times New Roman">modeCreate</font><font >一起使用。告诉</font><font  face="Times New Roman">CFile</font><font >,如果要创建的文件已经存在,则不再将文件长度设置为零。这对于系统设置文件、日志文件等特别有用,因为第一次启动系统时,这些文件通常不存在,需要创建,而下次则只需要修改文件。</font></p>
          <p><font  face="Times New Roman">  CFile::modeRead</font><font >:打开文件用于读</font></p>
          <p><font  face="Times New Roman">  CFile::modeWrite</font><font >:打开文件用于写</font></p>
          <p><font  face="Times New Roman">  CFile::modeReadWrite</font><font >:打开文件且对文件可读可写</font></p>
          <p><font >  可以使用比特位或“</font><font  face="Times New Roman">|</font><font >”对上述操作进行组合。比如,要打开文件写,可以用以下方式打开:</font></p>
          <p><font  face="Times New Roman">CFile file;</font></p>
          <p><font  face="Times New Roman">file.Open(</font><font >“</font><font  face="Times New Roman">c:\\readme.txt</font><font >”</font><font  face="Times New Roman">,CFile::modeCreate|CFile::modeWrite); 
            </font></p>
          <p><font color="#3973DE" >读文件</font></p>
          <p><font >  既然已经打开了文件,就可以对文件进行读写操作了。要读取文件内容到内存,可以调用</font><font  face="Times New Roman">CFile::Read()</font><font >。</font><font  face="Times New Roman">CFile::Read()</font><font >函数原型如下:</font></p>
          <p><font size="2" face="Arial"><b>UINT</b> <b>Read(</b> <b>void*</b> 
            <i>lpBuf</i><b>,</b> <b>UINT</b> <i>nCount</i> <b>);</b></font><br>
              Read函数包含两个参数,第一个参数是一个缓冲区指针,该缓冲区用于存放从文件读进来的内容。第二个参数是要读取的字节数。Read函数返回实际读入的字节数。例如:</p>
          <p>CFile file;</p>
          <p>char buf[100];</p>
          <p>int nBytesRead;</p>
          <p>nBytesRead=file.Read(buf,100);</p>
          <p><font color="#3973DE" >写文件</font></p>
          <p><font >  写文件与读文件操作方式类似,通过调用</font><font  face="Times New Roman">CFile::Write</font><font >函数来完成。</font></p>
          <p><font  face="Times New Roman">void Write( const void* lpBuf, 
            UINT nCount );</font></p>
          <p><font  face="Times New Roman">Write</font><font >函数第一个参数是指向要写入到文件中的缓冲区的指针,第二个参数是要写入到文件中的字节数。例如:</font></p>
          <p><font >CFile file;</font></p>
          <p><font >CString str(“This is a string.”);</font></p>
          <p><font >file.Write(str,str.GetLength());</font></p>
          <p><br>
            <font color="#3973DE" >关闭文件</font></p>
          <p><font >  在完成文件读写操作后,要调用CFile::Close成员函数及时将文件关闭。</font></p>
          <p><font >CFile file;</font></p>
          <p><font >//一些读写操作.....</font></p>
          <p><font >file.Close();</font></p>
          <p><font color="#3973DE">7.5.2异常处理</font></p>
          <p><font >  在打开和保存文件时,我们并未作传统的错误检查,而是采用一种异常机制来处理错误。</font></p>
          <p><font >  异常处理为异常事件提供了结构化、规范化的服务。它一般是指处理错误状态。</font></p>
          <p><font >  我们先回顾一下传统的错误处理方式。传统的错误处理方式通常有两种:</font></p>
          <p><font >1.返回错误值</font></p>
          <p><font >2.使用goto,setjmp/longjmp协助报告错误</font></p>
          <p><font >  对于第一种技术,要求程序员记住各种错误代码,并且加入大量的检查情况。由于大多数错误是很少会发生,这样处理的结果是代码冗余性很大,效率不高。</font></p>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -