GNU gettext for Delphiを使って国際化してみる

ソフトウェアを日本語や英語など、さまざまな言語に対応させたいことがあると思います。
DelphiにはITE(Integrated Translation Environment;統合翻訳環境)がありますが、今回は一般的なgettextを使って国際化してみます。
http://dybdahl.dk/dxgettext/
ライセンスはGPLではなくBSDライクのもののようです。
ダウンロードページからインストーラをダウンロードして実行し、指示に従ってインストールを行います。
インストールを行うと、.poと.moファイルの関連付けが行われます。
また、いくつかの翻訳作業に役に立つコマンドツールもインストールされます。
poファイルの編集ツールとしてPoedit - Gettext Translations Editorもインストールしておくと良いでしょう。
今回作成したサンプルは下記のようなディレクトリ構造になっています。

+ dxgettext_sample
  - dxgettext_sample.bdsproj
  - dxgettext_sample.dpr
  - dxgettext_sample.res
  - dxgettext_sample.exe
  - gnugettext.pas
  - SampleForm.pas
  - SampleForm.dfm
  - default.po
  + locale
    + en
      + LC_MESSAGES
        - default.po
    + ja
      + LC_MESSAGES
        - default.po

使用したDelphiのバージョンは2005Proです。
まず、インストール先に gnugettext.pas が存在しているので、プロジェクトフォルダにコピーし、プロジェクトに追加しておきます。
次に、プロジェクトのソースを変更します。
dxgettext_sample.dpr

program dxgettext_sample;

uses
  Forms,
  Graphics,
  SampleForm in 'SampleForm.pas' {FormMain},
  gnugettext in 'gnugettext.pas';

{$R *.res}

begin
  TP_GlobalIgnoreClass(TFont);

  Application.Initialize;
  Application.CreateForm(TFormMain, FormMain);
  Application.Run;
end.

TP_GlobalIgnoreClassで指定したクラスにはgettextが適用されません。
今回はTFontを指定しています。
フォームを作成し、FormCreateイベントの中で、TranslateComponentを呼び出します。
ソースコード中の文字列は、_('翻訳用文字列')のように書きます。翻訳用の文字列は英語で書くと良いでしょう。
プログラム中で動的に言語を変更する場合はUseLanguageを使います。またコンポーネントの再翻訳のために、ReTranslateComponentも呼び出しています。
SampleForm.pas

unit SampleForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, XPMan, gnugettext;

type
  TFormMain = class(TForm)
    Button1: TButton;
    XPManifest1: TXPManifest;
    RadioGroup1: TRadioGroup;
    procedure FormCreate(Sender: TObject);
    procedure RadioGroup1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  end;

var
  FormMain: TFormMain;

implementation

{$R *.dfm}

procedure TFormMain.FormCreate(Sender: TObject);
begin
  TranslateComponent(Self);
end;

procedure TFormMain.Button1Click(Sender: TObject);
begin
  ShowMessage(_('hello'));
end;

procedure TFormMain.RadioGroup1Click(Sender: TObject);
begin
  UseLanguage(RadioGroup1.Items[RadioGroup1.ItemIndex]);
  ReTranslateComponent(Self);
end;

end.

プログラム側での作業は以上です。コンパイルして実行ファイルを作っておきます。
では、翻訳ファイルを作成します。
コマンドプロンプトを開いて、プロジェクトフォルダに移動し、dxgettextコマンドを実行します。--delphiオプションを付けると自動的にdelphiのソースを参照してくれます。

>dxgettext --delphi

フォルダ内にdefault.poが作成されます。
実行ファイルと同じフォルダに、
locale\言語コード\LC_MESSAGES
のようにフォルダを作成し、default.poをコピーします。
poEdit*1でそれぞれの言語コードのdefault.poを翻訳し、保存します。
poEditで保存するとdefault.moが作成されているはずです。poEditを使わない場合は、poのコンパイルツールが関連付けされていると思うので、ダブルクリックでmoファイルが生成されます。
これで国際化は完了です。


GlobalIgnoreClass(TFont)の行をコメントアウト、MSゴシックを翻訳ファイルで設定した場合はこんな感じになります。

英語ですがdxgettextのドキュメントにもっと詳しく書かれているので、そちらも参照してください。
作成したサンプルのアーカイブは以下に。
dxgettext_sample.zip 258KB

*1:poEditの解説は、あえてここではしません。googleなどで検索して調べて下さい。