文章编号: 141921 - 最后修改: 2006年12月7日 - 修订: 5.1

HOWTO: 如何支持二渰每 MFC 文档类型

本页

展开全部 | 关闭全部

概要

生成与 Microsoft 基础类 (MFC) 文档或视图体系结构具有至多一个文件扩展名与每种文档类型关联的应用程序。 此默认值文件扩展名指定,如果存储文档模板字符串存储在字符串表中。

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

更多信息

分步过程

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

  1. 修改字符串表项,以便它包含两个文件扩展名。 两个扩展都将输入到 filterExt 字段之间用分号 (渚嬪.aaa ;.bbb) 分隔。 文档模板字符串可能看上去类似于下图:
       \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 从 Mfc\Src\Doccore.cpp CDocument::DoSave() 的到派生的类的实现。

    替换这些行:
            // 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 知识库中文章:
198538? (http://support.microsoft.com/kb/198538/EN-US/ ) DocMgrEx.exe assoc 命令将多个文件扩展名 w/1 文档类型

这篇文章中的信息适用于:
  • Microsoft Foundation Class Library 4.2?当用于
    • Microsoft Visual C++ 1.0 专业版
    • Microsoft Visual C++ 1.5 专业版
    • Microsoft Visual C++ 1.51
    • Microsoft Visual C++ 1.52 专业版
    • Microsoft Visual C++ 2.0 Professional Edition
    • Microsoft Visual C++ 2.1
    • Microsoft Visual C++ 2.2
    • Microsoft Visual C++ 4.0 标准版
关键字:?
kbmt kbdocview kbhowto KB141921 KbMtzh
机器翻译机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 141921? (http://support.microsoft.com/kb/141921/en-us/ )
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。
Retired KB Article不再更新的 KB 内容免责声明
本文介绍那些 Microsoft 不再提供支持的产品。因此本文按“原样”提供,并且不再更新。
 

文章翻译