本ページは公開が終了した情報の複製であり、掲載時点での情報です。本ページに記載されている内容について各所に問い合わせることはご遠慮下さい。
サポート技術情報

[MSVC] MFC 拡張 DLL が正しいリソースを読み込まない現象

文書番号: 150121

最終更新日: 2003/07/22


この資料は以下の製品について記述したものです。


この記事は、以前は次の ID で公開されていました: JP150121

概要


MFC 拡張 DLL (AFXDLL) における、CBitmap::LoadBitmap、CMenu::LoadMenu、CString::LoadString などリソースを読み込む MFC 関数が正しいリソースを読み込まないことがあります。拡張 DLL 内の適切なリソースではなく、アプリケーション内のリソースが読み込まれるされることもあります。

原因

拡張 DLL 内のリソースでなくアプリケーションや他の拡張 DLL 内のリソースが読み込まれる現象は、多くの場合、不適切なリソース管理が原因です。MFC アプリケーションや MFC 拡張 DLL は、グローバルに結ばれた 1 つのリソース (リソース チェイン) です。結ばれた個々のモジュール間に同じ ID 値を持つ複数のリソースが存在する場合、MFC は ID 値から見つけた最初のリソースを使用します。MFC は、アプリケーション内のリソースを拡張 DLL よりも先に検索するため、最初のリソースはアプリケーションから見つけられることがよくあります。

解決方法

アプリケーションとアプリケーションが使用する拡張 DLL における全てのリソースにおいて、ID 値を重複しない一意な値に変更します。これらの値は、プロジェクトの resource.h にて定義されており、リソース エディタ (Visual C++ 1.x では AppStudio) のシンボル ブラウザで変更できます。

シンボルの値が重複しないことを保証するためには、モジュール (ビルド単位) ごとに範囲の異なる ID 値を 1 から 0x6FFFF の間で割り当てます。それぞれのモジュールで、リソースを作成する前に resource.h に _APS_NEXT_RESOURCE_VALUE を定義することで、そのモジュールにおける ID 値の最小値を設定してください。リソース エディタは、次に作成されるリソースの ID をこのシンボルから決定します。

この技法は、MFC テクニカルノート 35 および Visual C++ に含まれているサンプル DLLHUSK において紹介されています。

詳細

MFC を動的にリンクする EXE、DLL ファイルにおいて、リソースを読み込む機能を持つ MFC の関数は、リソースが定義されているモジュールのハンドルを得るために AfxFindResourceHandle 関数を呼び出します。AfxFindResourceHandle 関数は、リソースの型や ID を元にリソース リストを検索して必要なリソースを以下の中から検索します。

  • AfxGetResourceHandle 関数の戻り値。通常、アプリケーション リソースを表します。
  • CDynLinkLibrary オブジェクト リストから得られる拡張 DLL のリソース リスト。
  • 言語固有のリソース DLL
  • MFC 共有 DLL (MFCxx.dll など)
注意: Visual C++ 1.x において、リソースを読み込む MFC 関数の一部は、AfxFindResourceHandle 関数を呼び出す代わりに、AfxCurrentResourceHandle 関数の戻り値を使用します。

個々の拡張 DLL は、CDynLinkLibrary オブジェクトを作成、初期化した後、AfxInitExtensionModule 関数へ渡し、DLL はリソース チェインに加えられます。AfxTermExtensionModule 関数は、DLL がアプリケーションから切り離されるときに DLL をチェインから除きます。

この仕様の長所は、アプリケーションや拡張 DLL で使用するリソースが他のアプリケーションや拡張 DLL 含まれていても、MFC がそれらを見つけられることです。プロセス内の全リソースが結ばれているため、ID 値は DLL とアプリケーションの間を伝わり、適切なリソースが読み込まれます。短所は、プロセス内の複数の DLL とアプリケーションにおいて重複する ID 値を持てないことです。

AfxFindResourceHandle 関数が調べるリソース リストの先頭位置を設定するために、AfxSetResourceHandle 関数を使用してください。 AfxFindResourceHandle 関数は、最初に AfxSetResourceHandle 関数により設定されたハンドルを調べるので、チェインを回り、1 つの適切な DLL またはアプリケーションからリソースを読み込むことができます。リソースの読み込みが済むとリソース ハンドルは元に戻されます。その時々におけるデフォルト リソース ハンドルは、AfxGetResourceHandle 関数により得ることができます。

この現象は、仕様です。

関連情報

拡張 DLL

MFC テクニカル ノート 33
DLLHUSK サンプル

リソース管理

MFC テクニカル ノート 35

関連情報

この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 150121 (最終更新日 1999-03-19) をもとに作成したものです。

Keywords: KBPRB VC10 VC15 VC20 VC40 VC41 VC42 VC4x VC50 キャッシュ KB150121
Technology: kbAudDeveloper kbMFC kbvc100 kbvc150 kbVC151 kbVC152 kbVC16bitSearch kbVC200 kbVC210 kbVC220 kbVC32bitSearch kbVC400 kbVC410 kbVC420 kbVC500 kbVC500Search kbVC600 kbVCsearch

inserted by FC2 system