2012年4月
« 3月   5月 »
 1
2345678
9101112131415
16171819202122
23242526272829
30  

カテゴリー

最近のコメント

<!–:ja–>Windows API国際化プログラミング – リソース読み込み(Win32、MFC)<!–:–><!–:en–>Windows API Internationalization Programming – Resource Loading (Win32, MFC)<!–:–>

ソフトウェア国際化ツールWorld Wide Navi(ワールドワイドナビ)の国際化プログラミング参考情報から、の抜粋です。

かなり古めな情報になりますが、MFCなどのレガシーなアプリケーションをお持ちで多言語化、海外展開をしたいと思っている方には、上記の参考情報はかなり有用なのではと思います。(特に、GUIのリソースとメッセージのリソースを同期をとって切り替える部分など)

眠っているアプリケーションをもういちど引き出しから出して、世界に羽ばたかせてみてはいかがでしょうか?

Visual Studioなどで作成されたWindows APIアプリケーションは通常、ラベルやメッセージなどの 言語間で異なるリソース情報がアプリケーションと一体化しています。 国際化されたアプリケーションにするには、実行時の言語設定にあったリソースを動的に読み込む 機能を作りこまなければなりません。 そのためにはリソースをDLLとして配布する方法が一般的にとられます。

1. リソースファイル(.rc)を作成する
ラベルやメッセージをリソースキーと値からなるリソースファイルに記述する。
以下はWorld Wide Naviで作成されたファイルの例。

#pragma code_page(1252)
STRINGTABLE
BEGIN
 IDS_MSG_WWNAVI1
"Hello, how are you? This is sample for Windows DLL."
 IDS_MSG_WWNAVI2
 "This is title 1."
 IDS_MSG_WWNAVI3
 "This is message 2."
 IDS_MSG_WWNAVI4
"This is title 2."
END

*コードページとファイルのエンコーディングは正しく対応する必要があります。

2. リソースの読み込み処理を記述する。
ラベルやメッセージを上記のリソースから読み込む処理を記述する。
読み込みにはLoadString関数を使う。
以下はWorld Wide Naviで生成されたコードの例。

LoadString(wwnaviH, uID, wwnaviBuf1,
WWNAVI_BUFF_SIZE);

wwnaviH … DLLモジュールへのポインタ(後述)。
uID … リソースキー
wwnaviBuf1 … 読み込んだ文字列の格納先(TCHAR)。
WWNAVI_BUFF_SIZE … 格納先のバッファサイズ。

3. リソースDLLの動的読み込みを記述する。
エントリポイント(アプリケーション起動時に呼ばれる個所)にリソースDLLを読み込む処理を記述します。
このとき、実行時の言語設定にあったDLLを読み込むようにしなくてはなりません。
World Wide Naviでは、GetUserDefaultLCIDで実行時のLCID(ロケールのID)を取得し、 それをISO-639の言語コードに変換して、該当するDLLをロードする方法をとっています。 以下はWorld Wide Naviで生成されたコードの例。

TCHAR libName[MAX_PATH];
TCHAR langName[];
LCID id=GetUserDefaultLCID();
GetLocaleInfo(id,
LOCALE_SISO639LANGNAME,langName,10);
wsprintf(libName ,
 _T("./%s/wwnavi_string.dll"), langName);
wwnaviH = LoadLibrary(
libName);
if (wwnaviH == NULL) {
 wwnaviH =
LoadLibrary(_T("./wwnavi_string.dll"));
}

wwnaviH … DLLモジュールへのポインタ。
LoadLibrary … DLLを読み込み、ポインタへ渡す関数です。
GetUserDefaultLCID … 実行時のロケールIDを取得する関数です。
GetLocaleInfo … ロケールIDから文字列情報を取得する関数です。
*上記ではLCIDから変換された言語コードのDLLを読み込み、
該当するものがなければデフォルトのDLLを読み込むようにしています。

Visual StudioでWin32アプリケーションを作成する場合は、 デフォルトリソースファイル(メニュー、アイコン、その他リソースを含む your-application-name.rcという名前のもの)を自分自身のファイルと結合しなければなりません。
簡単な方法は、ロードしたモジュールをアプリケーションのデフォルトにセットし、 アプリケーションのリソースを自分自身のファイルに含めることです。

*** 自分自身の .rc file
...
STRINGTABLE
BEGIN
 IDS_MSG_WWNAVI1
"Hello, how are you? This is sample for Windows DLL."
 IDS_MSG_WWNAVI2
"This is title 1."
 IDS_MSG_WWNAVI3
"This is message 2."
 IDS_MSG_WWNAVI4
 "This is title 2."
END

...

#include "././Test.rc"
<- * アプリケーションの.rcファイルを含める

*** main関数内

int WINAPI WinMain(HINSTANCE
hInstance, HINSTANCE hPreInst,
 LPSTR lpszCmdLine,
 int nCmdShow) {
...
hInstance = LoadLibrary(
YOUR_LIB_NAME);
<- * 引数のハンドルにロードしたハンドルをセット

MFCアプリケーションの場合は、hIsntanceをセットする代わりに AfxSetResourceHandleを使います。

*** InitInstanceメソッド内

BOOL CXXXX::InitInstance()
{
...
AfxSetResourceHandle(LoadLibrary(
YOUR_LIB_NAME));
<- * デフォルトのリソースハンドルにロードしたハンドルをセット

4. リソースファイルをDLLにコンパイルする。
Visual Studio附属のRCコマンド、またはDLLプロジェクトから リソースファイル(.rc)をDLL(.dll)にコンパイルします (World Wide NaviはDLLプロジェクトを自動的に作成し、 ソリューションまたはワークスペースに追加します)。
World Wide Naviは、実行ファイルと同じ場所のDLLをデフォルトとし、
言語コードディレクトリ内のものをその言語用のDLLとみなす方法をとっています。
たとえば日本語リソースの場合、以下のようにDLLを作成します。

./Foo.exe
... 実行ファイル
./wwnavi_string.rc
-> ./wwnavi_string.dll
... <- * デフォルトDLL
./wwnavi_string_ja.rc
-> ./ja/wwnavi_string.dll
... <- * 日本語DLL

LCIDとロケール、コードページの対応は以下のようになります。(MSDNページより抜粋)

--------------------------------------------------------------------------------------------------
LCID Language 	 Sublanguage 	 code page Language code
--------------------------------------------------------------------------------------------------
0x0436 Afrikaans 	 South Africa 1252 	 AFK
0x041c Albanian 	 Albania 1250 SQI
0x1401 Arabic 	 Algeria 1256 ARG
0x3c01 Arabic 	 Bahrain 1256 ARH
0x0c01 Arabic 	 Egypt 1256 ARE
0x0801 Arabic 	 Iraq 1256 ARI
0x2c01 Arabic 	 Jordan 1256 ARJ
0x3401 Arabic 	 Kuwait 1256 ARK
0x3001 Arabic 	 Lebanon 1256 ARB
0x1001 Arabic 	 Libya 1256 ARL
0x1801 Arabic 	 Morocco 1256 ARM
0x2001 Arabic 	 Oman 1256 ARO
0x4001 Arabic 	 Qatar 1256 ARQ
0x0401 Arabic 	 Saudi Arabia 1256 ARA
0x2801 Arabic 	 Syria 1256 ARS
0x1c01 Arabic 	 Tunisia 1256 ART
0x3801 Arabic 	 U.A.E. 1256 ARU
0x2401 Arabic 	 Yemen 1256 	 ARY
0x042b Armenian 	 Armenia Unicode only HYE
0x044d Assamese 	 India Unicode only ASM
0x082c Azeri 	 Azerbaijan (Cyrillic) 1251 AZE
0x042c Azeri 	 Azerbaijan (Latin) 1254 AZE
0x042d Basque 	 Spain 1252 EUQ
0x0423 Belarusian 	 Belarus 1251 BEL
0x0445 Bengali 	 India BEN
0x0402 Bulgarian 	 Bulgaria 1251 BGR
0x0403 Catalan 	 Spain 1252 CAT
0x0c04 Chinese 	 Hong Kong SAR 950 ZHH
0x1404 Chinese 	 Macao SAR 950 ZHM
0x0804 Chinese 	 PRC 936 CHS
0x1004 Chinese 	 Singapore 936 ZHI
0x0404 Chinese 	 Taiwan 950 CHT
0x0827 Classic 	 Lithuanian 1257 LTC
0x041a Croatian 	 Croatia 1250 HRV
0x0405 Czech 	 Czech Republic 1250 CSY
0x0406 Danish 	 Denmark 1252 DAN
0x0465 Divehi 	 Maldives Unicode only DIV
0x0813 Dutch 	 Belgium 1252 NLB
0x0413 Dutch 	 Netherlands 1252 NLD
0x0c09 English 	 Australia 1252 ENA
0x2809 English 	 Belize 1252 ENL
0x1009 English 	 Canada 1252 ENC
0x2409 English 	 Caribbean 1252 ENB
0x1809 English 	 Ireland 1252 ENI
0x2009 English 	 Jamaica 	 1252 ENJ
0x1409 English 	 New Zealand 	 1252 ENZ
0x3409 English 	 Philippines 	 1252 ENP
0x1c09 English 	 South Africa 1252 ENS
0x2c09 English 	 Trinidad 1252 ENT
0x0809 English 	 United Kingdom 1252 ENG
0x0409 English 	 United States 1252 USA
0x3009 English 	 Zimbabwe 1252 ENW
0x0425 Estonian 	 Estonia 1257 ETI
0x0438 Faeroese 	 Faeroe Islands 1252 FOS
0x0429 Farsi 	 Iran 1256 FAR
0x040b Finnish 	 Finland 1252 FIN
0x080c French 	 Belgium 1252 FRB
0x0c0c French 	 Canada 1252 FRC
0x040c French 	 France 1252 FRA
0x140c French 	 Luxembourg 1252 FRL
0x180c French 	 Monaco 	 1252 FRM
0x100c French 	 Switzerland 	 1252 FRS
0x042f Macedonian (FYROM) Macedonian (FYROM) 1251 MKI
0x0456 Galician 	 Spain 	 1252 GLC
0x0437 Georgian 	 Georgia 	 Unicode only KAT
0x0c07 German 	 Austria 	 1252 DEA
0x0407 German 	 Germany 		 1252 DEU
0x1407 German 	 Liechtenstein 	 1252 DEC
0x1007 German 	 Luxembourg 	 1252 DEL
0x0807 German 	 Switzerland 	 1252 DES
0x0408 Greek 	 Greece 		 1253 ELL
0x0447 Gujarati 	 India 		 Unicode only GUJ
0x040d Hebrew 	 Israel 		 1255 HEB
0x0439 Hindi 	 India 		 Unicode only HIN
0x040e Hungarian 	 Hungary 		 1250 HUN
0x040f Icelandic 	 Iceland 		 1252 ISL
0x0421 Indonesian 	 Indonesia (Bahasa) 1252 IND
0x0410 Italian 	 Italy 		 1252 ITA
0x0810 Italian 	 Switzerland 	 1252 ITS
0x0411 Japanese 	 Japan 		 932 JPN
0x044b Kannada 	 India (Kannada script) Unicode only KAN
0x043f Kazakh 	 Kazakstan 	 1251 KKZ
0x0457 Konkani 	 India 		 Unicode only KNK
0x0412 Korean 	 Korea 		 949 KOR
0x0440 Kyrgyz 	 Kyrgyzstan 	 1251 KYR
0x0426 Latvian 	 Latvia 		 1257 LVI
0x0427 Lithuanian 	 Lithuania 	 1257 LTH
0x083e Malay 	 Brunei Darussalam 1252 MSB
0x043e Malay 	 Malaysia 		 1252 MSL
0x044c Malayalam 	 India 		 Unicode only MAL
0x044e Marathi 	 India 	 Unicode only MAR
0x0450 Mongolian (Cyrillic) Mongolia 	 	 1251 MON
0x0414 Norwegian 	 Norway (Bokmal) 	 1252 NOR
0x0814 Norwegian 	 Norway (Nynorsk) 	 1252 NON
0x0448 Oriya 	 India 			 ORI
0x0415 Polish 	 Poland 	 1250 PLK
0x0416 Portuguese 	 Brazil 	 1252 PTB
0x0816 Portuguese 	 Portugal 		 1252 PTG
0x0446 Punjabi 	 India (Gurmukhi script) Unicode only PAN
0x0418 Romanian 	 Romania 		 1250 ROM
0x0419 Russian 	 Russia 	 	 1251 RUS
0x044f Sanskrit 	 India 		 Unicode only SAN
0x0c1a Serbian 	 Serbia (Cyrillic) 1251 SRB
0x081a Serbian 	 Serbia (Latin) 	 1250 SRL
0x041b Slovak 	 Slovakia 	 1250 SKY
0x0424 Slovenian 	 Slovenia 	 1250 SLV
0x2c0a Spanish 	 Argentina 	 1252 ESS
0x400a Spanish 	 Bolivia 	 1252 ESB
0x340a Spanish 	 Chile 		 1252 ESL
0x240a Spanish 	 Colombia 1252 ESO
0x140a Spanish 	 Costa Rica 1252 ESC
0x1c0a Spanish 	 Dominican Republic 1252 ESD
0x300a Spanish 	 Ecuador 1252 ESF
0x440a Spanish 	 El Salvador 1252 ESE
0x100a Spanish 	 Guatemala 1252 ESG
0x480a Spanish 	 Honduras 1252 ESH
0x080a Spanish 	 Mexico 1252 ESM
0x4c0a Spanish 	 Nicaragua 1252 ESI
0x180a Spanish 	 Panama 1252 ESA
0x3c0a Spanish 	 Paraguay 1252 ESZ
0x280a Spanish 	 Peru 1252 ESR
0x500a Spanish 	 Puerto Rico 1252 ESU
0x040a Spanish 	 Spain (Traditional sort) 1252 ESP
0x0c0a Spanish 	 Spain (International sort) 1252 ESN
0x380a Spanish 	 	 Uruguay 	 1252 ESY
0x200a Spanish 	 Venezuela 	 1252 ESV
0x0441 Swahili 	 Kenya 	 1252 SWK
0x081d Swedish 	 Finland 	 1252 SVF
0x041d Swedish 	 Sweden 	 1252 SVE
0x045a Syriac 	 Syria 		 Unicode only SYR
0x0449 Tamil 	 India Unicode only TAM
0x0444 Tatar 	 Tatarstan 1251 TTT
0x044a Telugu 	 India (Telugu script) Unicode only TEL
0x041e Thai 	 Thailand 874 THA
0x041f Turkish 	 Turkey 1254 TRK
0x0422 Ukrainian 	 Ukraine 1251 UKR
0x0420 Urdu 	 Pakistan 1256 URP
0x0820 Urdu 	 India 1256 URI
0x0843 online casino  Uzbek 	 Uzbekistan (Cyrillic) 1251 UZB
0x0443 Uzbek 	 Uzbekistan (Latin) 1254 UZB
0x042a Vietnamese 	 Viet Nam 1258 VIT

The following special identifiers are also defined:
Identifier Sublanguage/locale
0x0000 Language-Neutral
0x0400 Process Default Language

--------------------------------------------------------------------------------------------------

上記はWorld Wide Navi付属のサンプルコード(windows_dll)にWindows DLLの外部化を実行することで確認できます。