テクニカル ノート 57: MFC コンポーネントのローカライズ

Note

次のテクニカル ノートは、最初にオンライン ドキュメントの一部とされてから更新されていません。 結果として、一部のプロシージャおよびトピックが最新でないか、不正になります。 最新の情報について、オンライン ドキュメントのキーワードで関係のあるトピックを検索することをお勧めします。

このノートでは、MFC が使用されているアプリケーション、OLE コントロール、DLL などのコンポーネントをローカライズするときに使用できる設計や手順について説明します。

概要

MFC が使用されているコンポーネントをローカライズする場合、解決すべき問題が 2 つあります。 まず、ご自身のリソースをローカライズする必要があります。これは、コンポーネントに固有の文字列、ダイアログなどのリソースです。 また、MFC を使用して構築されたほとんどのコンポーネントに、MFC で定義されたリソースが多数含まれ、使用されています。 ローカライズされた MFC リソースも提供する必要があります。 幸い、MFC 自体に複数の言語が既に用意されています。

さらに、お使いのコンポーネントを、ターゲット環境 (ヨーロッパ環境または DBCS 対応環境) で動作するように準備する必要があります。 これは、ほとんどの場合、お使いのアプリケーションが、高位ビットが設定された文字を正しく処理し、ダブルバイト文字を含む文字列を扱うかにかかっています。 MFC は、この両方の環境で既定で有効になっているため、セットアップ時にさまざまなリソースを接続するだけで、すべてのプラットフォーム上で使用される単一のワールドワイド バイナリを持つことができます。

コンポーネントのリソースのローカライズ

ご自身のアプリケーションまたは DLL をローカライズするには、リソースを、ターゲット言語のリソースに置き換えるだけです。 独自のリソースについては、比較的シンプルで、リソース エディターでリソースを編集し、ご自身のアプリケーションをビルドします。 お使いのコードが適切に書かれていれば、ローカライズしたい文字列やテキストが C++ のソースコードにハード コーディングされることはありません。リソースを変更するだけで、すべてのローカライズが可能です。 実際、ローカライズ バージョンを提供するときに、オリジナル コードをビルドする必要がないように、ご自身のコンポーネントを実装することができます。 これはさらに複雑ですが、その価値は十分にあり、MFC 自体のための選ばれたメカニズムです。 EXE ファイル や DLL ファイルをリソース エディターに読み込み、リソースを直接編集することで、アプリケーションをローカライズすることも可能です。 可能ではありますが、新しいバージョンのアプリケーションをビルドするたびに、これらの変更を再適用する必要があります。

これを回避する方法として、個別の DLL (サテライト DLL と呼ばれることもあります) 内のすべてのリソースを検索する方法があります。 その後、この DLL は実行時に動的に読み込まれ、リソースは、すべてのコードが含まれるメイン モジュールからではなく、その DLL から読み込まれます。 MFC では、このアプローチを直接サポートしています。 MYAPP.EXE と呼ばれるアプリケーションを考えてみましょう。このアプリケーションのリソースはすべて、MYRES.DLL という DLL に格納されている可能性があります。 アプリケーションの InitInstance では、次の処理を実行してその DLL を読み込み、MFC によってその場所からリソースが読み込まれるようにします。

CMyApp::InitInstance()
{
    // one of the first things in the init code
    HINSTANCE hInst = LoadLibrary("myres.dll");

    if (hInst != NULL)
        AfxSetResourceHandle(hInst);

    // other initialization code would follow
    // ...
}

それ以降、MFC は、myapp.exe からではなく、その DLL からリソースを読み込みます。 ただし、その DLL 内には、すべてのリソースが存在していなければなりません。MFC が特定のリソースを探すために、アプリケーションのインスタンスを検索することはありません。 この手法は、OLE コントロールのほか、通常の MFC DLL にも同様に適用されます。 ユーザーが希望するリソース ロケールに応じて、適切なバージョンの MYRES.DLL が、お使いのセットアップ プログラムによってコピーされます。

リソースのみの DLL については、比較的容易に作成できます。 DLL プロジェクトを作成し、そのプロジェクトにご自身の .RC ファイルを追加して、必要なリソースを追加します。 この手法が使用されていない既存のプロジェクトがある場合は、そのプロジェクトからリソースをコピーできます。 リソース ファイルをプロジェクトに追加したら、プロジェクトをビルドする準備はほぼ完了です。 あとは、リンカー オプションに /NOENTRY を含めるように設定するだけです。 これにより、DLL にエントリ ポイントがないことをリンカーに伝えます。コードがないため、エントリ ポイントもありません。

Note

Visual C++ 4.0 以降のリソース エディターは、.RC ファイルあたり複数の言語をサポートしています。 これにより、1 つのプロジェクト内でご自身のローカライズを簡単に管理できるようになります。 各言語のリソースは、リソース エディターによって生成されるプリプロセッサ ディレクティブで制御されます。

提供されている MFC ローカライズ済みリソースの使用

ビルドする MFC アプリケーションはすべて、MFC から 2 つの要素、つまりコードとリソースを再利用します。 つまり、MFC には、さまざまなエラーメッセージ、組み込みダイアログなど、MFC クラスによって使用されているリソースが用意されています。 ご自身のアプリケーションを完全にローカライズするには、アプリケーションのリソースだけでなく、MFC から直接取得するリソースもローカライズする必要があります。 MFC では、さまざまな言語のリソース ファイルが自動的に提供されます。このため、対象言語が MFC によって既にサポートされている場合は、そのローカライズされたリソースを使用するようにするだけです。

このドキュメントの作成時点で MFC がサポートしているのは、中国語、ドイツ語、スペイン語、フランス語、イタリア語、日本語、韓国語です。 これらのローカライズ バージョンを含むファイルは、MFC\INCLUDE\L.* ("L" は Localized の略) ディレクトリ内にあります。 たとえば、ドイツ語ファイルは MFC\INCLUDE\L.DEU にあります。 これらの RC ファイルが、MFC\INCLUDE 内のファイルの代わりに、アプリケーションで使用されるようにするには、/IC:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\VC7\MFC\INCLUDE\L.DEU を、RC コマンド ラインに追加します (これは一例なので、ご自身が選択したロケールと、Visual C++ をインストールしたディレクトリに置き換える必要があります)。

上記の手順は、アプリケーションが MFC と静的にリンクしている場合に有効です。 ほとんどのアプリケーションが動的にリンクしています (AppWizard の既定)。 このシナリオでは、コードだけでなく、リソースも動的にリンクされます。 その結果、お使いのアプリケーション内のリソースはローカライズできますが、MFC の実装リソースは引き続き、MFC7x.DLL (以降のバージョン) または MFC7xLOC.DLL (存在する場合) から読み込まれます。 これには、2 つの異なる角度からアプローチできます。

より複雑なアプローチは、ローカライズされた MFC7xLOC.DLL (ドイツ語の場合は MFC7xDEU、スペイン語の場合は MFC7xESP.DLL)、またはそれ以降のバージョンを配布することです。ユーザーはアプリケーションをインストールするときに、適切な MFC7xLOC.DLL をシステム ディレクトリにインストールします。 この方法は、開発者とエンド ユーザーの両方にとって非常に複雑になる場合があるため、お勧めしません。 この手法と注意事項の詳細については、「テクニカル ノート 56」を参照してください。

最も簡単で安全なアプローチは、ローカライズされた MFC リソースを、ご自身のアプリケーションまたは DLL 自体 (あるいは、そのサテライト DLL (使用している場合)) に含めることです。 これにより、MFC7xLOC.DLL のインストールに伴う問題を回避できます。 これを行うには、上記に示した静的なケースと同じ手順に従います (ローカライズされたリソースを指定するように RC コマンド ラインを適切に設定します)。ただし、AppWizard によって追加された /D_AFXDLL 定義も削除する必要があります。 /D_AFXDLL が定義されていると、実際、AFXRES.H (および他の MFC RC ファイル) ではどのリソースも定義されません (MFC DLL からプルされるため)。

関連項目

番号順テクニカル ノート
カテゴリ別テクニカル ノート