現在オフラインです。再接続するためにインターネットの接続を待っています

[VC50] 1 つのドキュメントに 2 つのファイル拡張子を関連付ける方法

この記事は、以前は次の ID で公開されていました: JP141921
サポート期間が終了した「サポート技術情報」資料に関する免責事項
この資料は、マイクロソフトでサポートされていない製品について記述したものです。そのため、この資料は現状ベースで提供されており、今後更新されることはありません。
概要
MFC のドキュメント/ビュー アーキテクチャを使用して作成されたアプリケーションでは、ドキュメント タイプごとに関連付けられるファイル拡張子は 1 つであり、ファイル拡張子を定義した場合、その情報はストリング テーブル中のドキュメント テンプレート文字列に保存されます。

特定の文書タイプに 2 つのファイル拡張子を関連付けると便利なこともあります。この資料は、ドキュメント テンプレート文字列に 2 つのファイル拡張子を定義する方法を説明します。クラスの派生と関数オーバーライドを使用することで、ドキュメント テンプレートに両方のファイル拡張子を関連付けることができます。
詳細

手順

SDI または MDI アプリケーションにおいて、1 つのドキュメント タイプに 2 つのファイル拡張子を関連付けるには、下記の手順に従います。

  1. ストリング テーブル エントリを、2 つのファイル拡張子を含むように変更。2 つの拡張子は、セミコロンで区切り filterExt フィールドに入力します。例 : たとえば Exts という名前のプロジェクトで aaa と bbb を拡張子とする場合
         \nExts\nExts\nFiles (*.aaa; *.bbb)\n.aaa;.bbb\nExts.Doc\nExts Doc.
  2. CMultiDocTemplate から MDI アプリケーションのためのクラスを派生するか、SDI アプリケーションのために CSingleDocTemplate から派生します。このクラスをプロジェクトに追加し、ドキュメント テンプレートを作成するときに 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)             {                 //文字列は 2 つの拡張子を含む                 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;         // すべての文書を検査         POSITION pos = GetFirstDocPosition();         while (pos != NULL)         {              CDocument* pDoc = GetNextDoc(pos);             if (pDoc->GetPathName() == pszPathName) {                 // 既に開いている                 rpDocMatch = pDoc;                 return yesAlreadyOpen;             }         }  // while の終わり         // いずれかのサフィックスに一致するか調べる         CString strFilterExt;         if (GetDocString(strFilterExt, CDocTemplate::filterExt) &&                                                      !strFilterExt.IsEmpty())         {             // 拡張子が一致するか調べる             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)             {                 // 文字列は 2 つの拡張子を含む                 ext1=strFilterExt.Left(nSemi);                 ext2=strFilterExt.Mid(nSemi+2);                 // いずれかの拡張子に一致するか検査する                 if (nDot >= 0 && (lstrcmpi(pszPathName+nDot, ext1) == 0                                        || lstrcmpi(pszPathName+nDot,ext2) ==0))                     return yesAttemptNative; // 拡張子が一致             }             else             { // 文字列は   1 つの拡張子を含む                 if (nDot >= 0 && (lstrcmpi(pszPathName+nDot, strFilterExt)==0))                     return yesAttemptNative;  // 拡張子の一致             }         }         return yesAttemptForeign; //不明の文書タイプ     }
  5. [保存]、[名前を付けて保存] コマンドを正しく機能させるために、CDocument から派生したクラスの中で DoSave 関数をオーバーライド。mfc\Src\Doccore.cpp から CDocument::DoSave() の実装コードをコピーして派生クラスで使用し、さらにコードを追記します。
         // 既定値のサフィックスがあれば追加する     CString strExt;     if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&                                                             !strExt.IsEmpty())     {         ASSERT(strExt[0] == '.');         int nSemi;                       //追加         if(nSemi = strExt.Find(';'));    //追加         strExt = strExt.Left(nSemi);     //追加         newName += strExt;     }
    追加された 3 行のコードは、ドキュメント文字列中に 2 つの拡張子が指定されているドキュメント タイプに対して [名前を付けて保存] が処理されると、既定値として最初の拡張子を戻します。ドキュメント文字列の中で指定されている 2 番目の拡張子を使用してファイルを保存したい場合は、ユーザーはこの拡張子の上から入力し直す必要があります。

    また、コード中の下記の行を置き換える必要があります。
         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();     //修正済み     }
    このコンテキストでは DELETE_EXCEPTION() マクロは未定義であるため、この処理が必要になります。
  6. (16bit エディションのみ) クラス ウィザードを使用し、派生したドキュメントクラス中に OnFileSave および OnFileSaveAs コマンド ハンドラを提供。これは、Visual C++ の 16bit バージョンでは DoSave は仮想関数ではないために必要となる作業です。mfc\Src\Doccore.cpp から両方の関数の基本クラス バージョンの内容をコピーして、コマンド ハンドラに貼り付けます。この結果、関数は基本クラス バージョンではなく、DoSave のローカル コピーを呼び出すようになります。_access 関数の定義を提供するためには、プロジェクトに#include "io.h" を追加する必要が生じる場合があります。
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 141921 (最終更新日 1998-08-07) をもとに作成したものです。

kbinf 1.50 1.51 1.52 2.00 2.50 3.00 3.10
プロパティ

文書番号:141921 - 最終更新日: 01/28/2004 20:52:23 - リビジョン: 3.0

  • Microsoft Foundation Class Library 4.2
  • 2.00 kbhowto vc1x vc41 vc42 vc4x vc50 KB141921
フィードバック