HOWTO: 如何每 MFC 文档类型的支持两个文件扩展名

注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。

点击这里察看该文章的英文版: 141921
本文已归档。它按“原样”提供,并且不再更新。
概要
生成与 Microsoft 基础类 (MFC) 文档的体系结构具有最多一个文件扩展名与每个文档类型关联的视图的应用程序。此默认值扩展名指定,如果存储文档模板字符串存储在字符串表中。

它通常是用于将两个文件扩展名与给定的文档类型关联。本文介绍了一种技术,您可以使用以允许将存储在文档模板字符串中的两个文件扩展名。通过类派生和重写函数,则可以将这两个文件扩展名与文档模板关联起来。
更多信息

分步过程

使用以下步骤来将两个文件扩展名与 SDI 或 MDI 应用程序中的单个文档类型关联。

  1. 修改字符串表项,这样它就会包含两个文件扩展名。 用分号 (例如对于.aaa ;.bbb) 分隔在 filterExt 字段中输入两个扩展。文档模板字符串可能看上去类似于下图:
       \nExts\nExts\nFiles (*.aaa; *.bbb)\n.aaa;.bbb\nExts.Doc\nExts Doc.					
  2. 一个从派生类 CMultiDocTemplate MDI 应用或 $ CSingleDocTemplate SDI 应用程序。将此类添加到您的项目和您 InitInstance 中创建文档模板时使用该函数。您将需要创建一个仅调用基类构造函数的构造函数
       CMyMultiDocTemplate::CMyMultiDocTemplate(      UINT nIDResource, CRuntimeClass* pDocClass,      CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass ) :      CMultiDocTemplate(nIDResource, pDocClass, pFrameClass, pViewClass)      { };					
  3. 重写 GetDocString 函数在第 2 步中从 CMultiDocTemplate 或 $ CSingleDocTemplate 派生类中的
       BOOL CMyMultiDocTemplate::GetDocString(CString& rString,                            enum DocStringIndex i) const   {        CString strTemp,strLeft,strRight;        int nFindPos;        AfxExtractSubString(strTemp, m_strDocStrings, (int)i);        if(i == CDocTemplate::filterExt)  {          nFindPos=strTemp.Find(';');          if(-1 != nFindPos) {            //string contains two extensions            strLeft=strTemp.Left(nFindPos+1);            strRight=strTemp.Right(lstrlen((const            char*)strTemp)-nFindPos-1);            strTemp=strLeft+strRight;          }        }    rString = strTemp;    return TRUE;   }					
  4. 以便这两个文件扩展名识别在打开的文件时,重写 CMyMultiDocTemplate::MatchDocType
       CDocTemplate::Confidence CMyMultiDocTemplate::MatchDocType(const        char* pszPathName, CDocument*& rpDocMatch)   {        ASSERT(pszPathName != NULL);        rpDocMatch = NULL;        // go through all documents        POSITION pos = GetFirstDocPosition();        while (pos != NULL)        {           CDocument* pDoc = GetNextDoc(pos);           if (pDoc->GetPathName() == pszPathName) {              // already open              rpDocMatch = pDoc;              return yesAlreadyOpen;           }        }  // end while        // see if it matches either suffix        CString strFilterExt;        if (GetDocString(strFilterExt, CDocTemplate::filterExt) &&          !strFilterExt.IsEmpty())        {           // see if extension matches           ASSERT(strFilterExt[0] == '.');           CString ext1,ext2;           int nDot = CString(pszPathName).ReverseFind('.');           const char* pszDot = nDot < 0 ? NULL : pszPathName + nDot;           int nSemi = strFilterExt.Find(';');           if(-1 != nSemi)   {             // string contains two extensions             ext1=strFilterExt.Left(nSemi);             ext2=strFilterExt.Mid(nSemi+2);             // check for a match against either extension             if (nDot >= 0 && (lstrcmpi(pszPathName+nDot, ext1) == 0                 || lstrcmpi(pszPathName+nDot,ext2) ==0))               return yesAttemptNative; // extension matches           }           else           { // string contains a single extension             if (nDot >= 0 && (lstrcmpi(pszPathName+nDot,                 strFilterExt)==0))             return yesAttemptNative;  // extension matches           }        }        return yesAttemptForeign; //unknown document type   }					
  5. 若要使保存并正确地存储为函数,重写该 DoSave CDocument 派生类中的函数。只需剪切并粘贴 MFC CDocument::DoSave() Mfc\Src\Doccore.cpp 从您的派生类中实施。

    替换这些行:
            // append the default suffix if there is one        CString strExt;        if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&            !strExt.IsEmpty())        {           ASSERT(strExt[0] == '.');           newName += strExt;        }						
    与这些行:
            // append the default suffix if there is one        CString strExt;        if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&            !strExt.IsEmpty())        {          ASSERT(strExt[0] == '.');          int nSemi;                       //added          if(nSemi = strExt.Find(';'));    //added          strExt = strExt.Left(nSemi);     //added          newName += strExt;        }						
    的三个添加代码行的第一个扩展名默认情况下返回另存为处理时具有在其文档字符串中指定的两个扩展名的文档类型。如果要在文档的字符串中指定第二个的扩展名保存文件,用户必须键入通过此扩展名。

    您还需要替换下列代码行:
          CATCH_ALL(e)      {      TRACE0("Warning: failed to delete file after failed SaveAs.\n");      DELETE_EXCEPTION(e);      }						
    与:
          CATCH_ALL(e)      {      TRACE0("Warning: failed to delete file after failed SaveAs.\n");      e->Delete();     //modified      }						
    这是必要的因为 DELETE_EXCEPTION() 宏未定义在此上下文中。
  6. (仅限 16 位版)类向导用于提供 OnFileSave 和 OnFileSaveAs 派生的文档类中的命令处理程序。这是必要的因为在 16 位版本的 Visual c + +,该 DoSave 函数不是虚拟。只需剪切并 Mfc\Src\Doccore.cpp 从两个函数的基类版本的内容粘贴到您的命令处理程序。生成函数调用 DoSave,而不是基类版本的本地副本。可能需要将 # 添加包括 io.h 到项目中以提供 _access 函数的定义。
参考
请参见下面 Microsoft 知识库中相应的文章:
198538DocMgrEx.exe assoc 命令将多个文件扩展名 w/1 文档类型
kbinf 1.50 1.51 1.52 2.00 2.50 3.00 3.10

警告:本文已自动翻译

属性

文章 ID:141921 - 上次审阅时间:12/04/2015 12:49:30 - 修订版本: 5.1

Microsoft Foundation Class Library 4.2

  • kbnosurvey kbarchive kbmt kbdocview kbhowto KB141921 KbMtzh
反馈