ここでは、ActiveX コントロールのインターフェイスのローカライズ方法について説明します。
ActiveX コントロールを国際市場に対応させる場合は、コントロールをローカライズする必要があります。Windows は、既定の言語である英語のほかにも、ドイツ語、フランス語、スウェーデン語など、多くの言語をサポートしています。このため、コントロールのインターフェイスが英語だけでは問題が生じる場合があります。
一般に、ActiveX コントロールのロケールは、常に LocaleID アンビエント プロパティに基づいて決定されるようにします。これには、次の 3 つの方法があります。
-
常に、要求されてからリソースを読み込むようにします。読み込むリソースは、LocaleID アンビエント プロパティの現在の値に基づいて決定します。MFC ActiveX コントロールのサンプル LOCALIZE では、この方法が使用されています。
-
最初のコントロールがインスタンス化されたときに、LocaleID アンビエント プロパティに基づいてリソースを読み込み、それをほかのすべてのインスタンスに使用します。ここでは、この方法について説明します。
メモ : |
|---|
| その後のインスタンスのロケールが異なる場合には、この方法が正しく機能しないこともあります。 |
-
OnAmbientChanged 通知関数を使って、コンテナのロケールに適したリソースを動的に読み込みます。
メモ : |
|---|
| この方法は、コントロールに対しては有効ですが、ランタイム DLL のリソースは、アンビエント LocaleID プロパティが変わっても動的に更新されません。また、ActiveX コントロールのランタイム DLL は、スレッドのロケールを使ってリソースのロケールを決定します。 |
以降では、2 つのローカライズ方法について説明します。最初の方法では、プロパティ、メソッド、イベントの名前などのコントロールのプログラマビリティ インターフェイスをローカライズします。2 つ目の方法では、コンテナの LocaleID アンビエント プロパティを使って、コントロールのユーザー インターフェイスをローカライズします。コントロールのローカライズの例については、MFC ActiveX コントロールのサンプル LOCALIZE を参照してください。
コントロールのプログラマビリティ インターフェイスのローカライズ
コントロールのプログラマビリティ インターフェイス (コントロールを使用するアプリケーションを作成するときにプログラマが使うインターフェイス) をローカライズする場合は、サポートする言語ごとに、その言語用に変更した .IDL ファイル (コントロールのタイプ ライブラリをビルドするためのスクリプト) を作成する必要があります。このスクリプト以外でコントロールのプロパティ名をローカライズする必要はありません。
コントロールをローカライズするには、タイプ ライブラリのレベルで、ロケール ID を属性として含めます。たとえば、フランス語でプロパティ名をローカライズしてタイプ ライブラリを提供するには、SAMPLE.IDL ファイルのコピーを作成し、SAMPLEFR.IDL という名前を付けます。その後、このファイルに、ロケール ID 属性を追加します。フランス語のロケール ID は 0x040c です。次に例を示します。
[ uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx), version(1.0), lcid(0x040c) ]
library Sample
{
SAMPLEFR.IDL 内のプロパティ名をフランス語の名前に変更し、MKTYPLIB.EXE を使ってフランス語のタイプ ライブラリ SAMPLEFR.TLB を生成します。
ローカライズされたタイプ ライブラリを複数作成する場合は、ローカライズした .IDL ファイルをプロジェクトに追加すると、ローカライズされたタイプ ライブラリが自動的にビルドされます。
ActiveX コントロール プロジェクトに .IDL ファイルを追加するには
-
コントロール プロジェクトが開いている状態で、[プロジェクト] メニューの [既存項目の追加] をクリックします。
[既存項目の追加] ダイアログ ボックスが表示されます。
-
必要に応じて、表示するドライブとフォルダを選択します。
-
[ファイルの種類] ボックスの [すべてのファイル] を選択します。
-
ファイルの一覧で、プロジェクトに挿入する .IDL ファイルをダブルクリックします。
-
必要な .IDL ファイルをすべて追加したら、[開く] をクリックします。
プロジェクトに追加したファイルは、プロジェクトの残りの部分がビルドされるときにビルドされます。ローカライズされたタイプ ライブラリは、現在の ActiveX コントロール プロジェクトのフォルダに配置されます。
コードの中では、常に内部プロパティ名 (通常は英語) が使用され、内部プロパティ名がローカライズされることはありません。コントロールのディスパッチ マップ、プロパティ エクスチェンジ関数、プロパティ ページのデータ エクスチェンジ コードなどは、これに該当します。
コントロールの実装 (.OCX) ファイルのリソースに結び付けることができるタイプ ライブラリ (.TLB) ファイルは 1 つだけです。このタイプ ライブラリは、通常は標準化された名前 (通常は英語) のバージョンを使います。ローカライズされたバージョンのコントロールには、既定のバージョンの .TLB に結び付けられている .OCX と、該当するロケールの .TLB が必要です。つまり、英語版の場合は、既に正しい .TLB が .OCX に結び付けられているため、必要なのは .OCX だけです。ローカライズしたバージョンのコントロールを配布するには、.OCX に加えて、該当するロケールのタイプ ライブラリも配布する必要があります。
ローカライズされたタイプ ライブラリをコントロールのクライアントが見つけることができるようにするには、ロケール固有の .TLB ファイルを Windows のレジストリの TypeLib セクションの下に登録します。.TLB ファイルをレジストリに登録するには、AfxOleRegisterTypeLib の 3 番目のパラメータ (通常は省略可能) を使います。次の例では、ActiveX コントロールのフランス語のタイプ ライブラリを登録しています。
STDAPI DllRegisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);
AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid,
_T("samplefr.tlb"))
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);
return NOERROR;
}
コントロールが登録されるときに、AfxOleRegisterTypeLib 関数によって、指定した .TLB ファイルがコントロールと同じフォルダで自動的に検出され、Windows のレジストリに登録されます。.TLB ファイルが見つからなかった場合には、この関数は何もしません。
コントロールのユーザー インターフェイスのローカライズ
コントロールのユーザー インターフェイスをローカライズするには、ユーザーに表示されるすべてのリソース (プロパティ ページやエラー メッセージなど) を言語固有のリソース DLL に追加します。その後、コンテナの LocaleID アンビエント プロパティを使って、ユーザーのロケールに該当する DLL を選択できます。
次のコードは、特定のロケールのリソース DLL を見つけて読み込む方法の一例を示しています。この例で使うメンバ関数 GetLocalizedResourceHandle は、使用する ActiveX コントロール クラスのメンバ関数にすることもできます。
HINSTANCE CSampleCtrl::GetLocalizedResourceHandle(LCID lcid)
{
LPCTSTR lpszResDll;
HINSTANCE hResHandle = NULL;
switch (PRIMARYLANGID(lang))
{
case LANG_ENGLISH:
lpszResDll = "myctlen.dll";
break;
case LANG_FRENCH:
lpszResDll = "myctlfr.dll";
break;
case LANG_GERMAN:
lpszResDll = "myctlde.dll";
break;
case 0:
default:
lpszResDll = NULL;
}
if (lpszResDll != NULL)
hResHandle = LoadLibrary(lpszResDll);
#ifndef _WIN32
if(hResHandle <= HINSTANCE_ERROR)
hResHandle = NULL;
#endif
return hResHandle;
}
switch ステートメントの各 case でサブ言語 ID を確認すると、より特殊なローカライズ (ドイツ語の方言など) を提供できます。この関数の使用例については、MFC ActiveX コントロールのサンプル LOCALIZE の GetResourceHandle 関数を参照してください。
コントロールが初めてコンテナに読み込まれるときに、コントロールから COleControl::AmbientLocaleID を呼び出してロケール ID を取得できます。返されたロケール ID の値を GetLocalizedResourceHandle 関数に渡すと、正しいリソース ライブラリが読み込まれます。結果のハンドルがあった場合は、AfxSetResourceHandle に渡す必要があります。
m_hResDll = GetLocalizedResourceHandle( AmbientLocaleID() );
if (m_hResDll != NULL)
AfxSetResourceHandle(m_hResDll);
上のコード サンプルをコントロールのメンバ関数 (COleControl::OnSetClientSite のオーバーライドなど) に追加します。また、m_hResDLL をコントロール クラスのメンバ変数にする必要があります。
コントロールのプロパティ ページのローカライズでも、同様の手法を使用できます。プロパティ ページをローカライズするには、次のようなコードをプロパティ ページの実装ファイル (COlePropertyPage::OnSetPageSite のオーバーライド) に追加します。
LPPROPERTYPAGESITE pSite;
LCID lcid = 0;
if((pSite = GetPageSite()) != NULL)
pSite->GetLocaleID(&lcid);
HINSTANCE hResource = GetLocalizedResourceHandle(lcid);
HINSTANCE hResourceSave = NULL;
if (hResource != NULL)
{
hResourceSave = AfxGetResourceHandle();
AfxSetResourceHandle(hResource);
}
// Load dialog template and caption string.
COlePropertyPage::OnSetPageSite( );
if (hResource != NULL)
AfxSetResourceHandle(hResourceSave);
参照