Windowsアプリの国際化(i18n)のやり方
ウィンドウズアプリの複数言語対応(Localization、多言語化)対応についてまとめる。環境は以下の通り。
- 実行環境: .Net framework 3.5
- 開発言語: C#, Form Application
- IDE: Windows Visual C# 2008 Express Edition
クイックサマリ
機能と手順
.Net のフォームアプリにはi18n(=Internationalization)機能がサポートされているので、これを組み合わせて使うことで多言語対応できる。実現できる内容は、
- 実行時のシステム言語環境に合わせて、アプリケーションが動的に対応言語で起動される。
- メッセージは、自動的に対応言語で表示される。(言語別メッセージカタログ切り替え)
- その他に、言語設定(language)の参照、設定。
Visual C# Express Editionからは、フォームデザイナーで言語毎の画面を作ることができ、言語毎のメッセージカタログを持たせることができる。また、.Netでは実行環境の言語設定(Posixで言うlang)に対応するクラスがあり、言語設定を参照、設定することができる。
ここでは、オリジナルが日本語のアプリを多言語化するが、デフォルト言語が英語のほうが自然で手間も少ないので、最初から多言語対応が決定している場合は、英語デフォルト言語でやることを検討したほうが良い。
なお、同時多言語化(mulit-lingual)に関しては、UTF-8を使えるというレベルの対応になるが、必ずしも表示が可能な訳ではない。外国語(例えば英語)版では日本語などは対応されていないことがある。また、これは各Windowsバージョンでの対応水準にも違いがあり、Vistaでは日本語のメッセージが表示されるが、XPでは日本語部分のグリフは□で表示されてしまう。
FormのLocalizable property
Formを他言語化する。これは他のページにも解説があって参考にした。
フォームのデザイナーを開き、プロパティ"Localizable"を"true"に設定する。すると"Language"プロパティを設定することができるので、そこで"英語"を選択する。これで、既定値(日本語)と英語のバイリンガルの対応になる。各言語に対して、"Language"設定を切り替えながら、言語に合わせた文言の変更やボタンサイズなどの変更を行って行く。
これによって、フォームデザイナ上で設定する文言は多言語化される。なお、プログラム内部で定義している文言の変更は後述のメッセージカタログによる。
注意すべき点は2つある。一つは、フォームが複数ある場合には、全てのフォームに同じ手順で他言語化しないとならないこと、2つ目は、Languageを設定した時点でファイルが別になってしまうため、その後開発を進めるためには、各々の言語に同じ追加なり修正を別個に加えないとならなくなる、ということだ。従って、主力言語で開発を進め、一段落付いたところでローカライズ先に同じ修正を加えるような開発作業になる。一見不便そうでもあるけど、言語が変わるとwidgetのサイズも変えなくてはならないので仕方ないのかもしれない。
メッセージカタログの作成
なんとなく自動のような手動のような感じで作成することができる。
まず、予備作業として、通常プログラム中に埋め込んでしまっている文言をメッセージカタログとしてくくり出すことが必要だ。プロジェクトの"Resources.resx"を開いて"文字列"のタブを選択すると、表形式でメッセージカタログに入力することができる。ソースコード中から文言文字列を拾ってコピペする。これで「既定」言語(日本語)用のメッセージカタログは完成である。
プログラムからは名前による参照になり、例えば名前が"Reject"の文言は"Properties.Resources.Reject"としてstringクラスのインスタンスとして呼出すことができる。
次に英語用のメッセージカタログを用意する。
プロジェクトに対して"新しい項目の追加"で"アセンブリリソース"を追加する。英語のを追加するのなら、"Resouces.en.resx"か"Resources.en-US.resx"という名前にする。作成後、プロジェクトの"Properties"に移動する。既定言語と同じ名前で英訳した文言を記入していく。
これをコンパイルすると、bin/Release/en/xxxxx.resources.dllが作成される。実行環境には、.exeと共に、en以下をこのままのパスでコピーしてやれば良い。
日本語と他言語の切り替え
残念ながらこの時点では、実行環境が日本語の場合は日本語画面に、英語の場合は英語画面になるが、それ以外の言語の場合は日本語になる。これは望んでいた仕様ではないだろう。日本語の場合は日本語で、それ以外の言語のときは英語になって欲しい。このためには、冒頭で書いた通り、既定言語を英語で、日本語に対してLocalizationを行うのが筋である。しかし、最初に日本語で作ってしまっている訳で、そのための対応を追加しておく。
プログラムの頭に言語が日本語でなければ英語として動作するように制御するコードを追加する。少なくとも文言切り替えが必要な行よりも前に実行する必要があるが、私はProgram.csの頭のほうに挿入した。
// check culture and set en, if not ja.
if (!Thread.CurrentThread.CurrentUICulture.Name.StartsWith("ja") &&
!Thread.CurrentThread.CurrentUICulture.Name.StartsWith("en")) {
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en", false);
}
言語環境のプロパティは、CurrentCultureとCurrentUICultureがあるけれど、実際に試したところ、この目的で使うのは"UI"のほうだ。これにより、日本語でも英語でもない場合は、言語が英語に設定される、つまり、表示が英語になる。