Help and Support

文章编号: 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. 重写在步骤 2 中派生 CMultiDocTemplate 或 CSingleDocTemplate 类中的 GetDocString 函数
       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;
            }
    						
    </a0>-三添加另存为为具有两个扩展名的文档字符串中指定的文档类型处理时,行代码默认情况下返回第一个扩展名。 如果要与第二个文档字符串中指定的扩展名保存文件,则用户必须键入通过此扩展。

    还需要将以下代码行:
          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 命令处理程序在您的派生的文档类中。 这是必需的因为 Visual C++,在 DoSave 16 位版本中不是虚拟函数。 只需剪切并粘贴您的命令处理程序的从 Mfc\Src\Doccore.cpp 两个函数的基类版本的内容中。 生成的函数调用 DoSave,而不是基类版本的本地副本。 可能需要添加 # 包括"io.h"您的项目提供 _access 函数的定义。

参考

请参见下面的 Microsoft 知识库文章:
198538? (http://support.microsoft.com/kb/198538/EN-US/ ) DocMgrEx.exe Assoc 多个文件扩展名但有 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 不再提供支持的产品。因此本文按“原样”提供,并且不再更新。

文章翻译