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

📄 chap7_5.htm

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

⌨️ 快捷键说明

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