Delphi Programming / Object Pascal
[掲載 2018年08月24日] [更新 2018年08月24日] Delphi 一般・その他 |
ロケールの言語と国コードの取得 |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 |
ロケールの ja あるいは ja-JP という言語コードと国コードの値を取得するサンプルです.
以下のコマンドを実行すると下図の [地域と言語] のダイアログが現れます.これがロケール各種の設定内容です.ただし,このダイアログには ja や ja-JP の表示はありません. |
%SystemRoot%\System32\control.exe /name Microsoft.RegionalAndLanguageOptions /page |
|
図1
[地域と言語] のダイアログ
|
01_GetLocaleInfo 関数を使用した言語コードの取得 |
上の図で表示されているロケールの値は,GetLocaleInfo 関数を使用して取得することができます.また,SetLocaleInfo 関数を使用すると設定もできます.ロケールの種類によっては専用の取得あるいは設定用の関数が用意されていることがあります. |
GetLocaleInfo 関数の第 1 引数には以下の値が指定できます.
LOCALE_INVARIANT, LOCALE_CUSTOM_XXX については以下の記事で確認してください. |
LOCALE_SYSTEM_DEFAULT |
システムの既定ロケール |
LOCALE_USER_DEFAULT |
ユーザの既定ロケール |
LOCALE_INVARIANT |
- |
LOCALE_CUSTOM_DEFAULT |
- |
LOCALE_CUSTOM_UI_DEFAULT |
- |
LOCALE_CUSTOM_UNSPECIFIED |
- |
下図は GetLocaleInfo 関数の第 2 引数に,言語コードと国コードに関係ありそうな値を指定して,それらの値を表示した結果です. |
|
図2
言語コードと国コード関係の値
- LOCALE_IXXX は Identify の意味
- LOCALE_SXXX は Signature の意味
- ISO639 の言語コードが ja になっている
|
implementation
uses
AnsiStrings;
{$R *.dfm}
//=============================================================================
// ロケールの言語関係の値を取得
// usesにAnsiStringsが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LStrList : TStringList;
LIndex : Integer;
LCData : Cardinal;
LpcLCA : array[0..LOCALE_NAME_MAX_LENGTH - 1] of Char;
LDataText : AnsiString;
LFlagText : AnsiString;
LRetText : AnsiString;
begin
Memo1.Font.Name := 'Courier New';
Memo1.Font.Pitch := fpFixed;
Memo1.Font.Size := 10;
Memo1.Lines.Clear;
LStrList := TStringList.Create;
try
//取得する情報の種類のリストを作成
LStrList.AddObject('LOCALE_ILANGUAGE', TObject(LOCALE_ILANGUAGE));
LStrList.AddObject('LOCALE_SLANGUAGE', TObject(LOCALE_SLANGUAGE));
LStrList.AddObject('LOCALE_SENGLANGUAGE', TObject(LOCALE_SENGLANGUAGE));
LStrList.AddObject('LOCALE_SABBREVLANGNAME', TObject(LOCALE_SABBREVLANGNAME));
LStrList.AddObject('LOCALE_SNATIVELANGNAME', TObject(LOCALE_SNATIVELANGNAME));
LStrList.AddObject('LOCALE_ICOUNTRY', TObject(LOCALE_ICOUNTRY));
LStrList.AddObject('LOCALE_SCOUNTRY', TObject(LOCALE_SCOUNTRY));
LStrList.AddObject('LOCALE_SENGCOUNTRY', TObject(LOCALE_SENGCOUNTRY));
LStrList.AddObject('LOCALE_SABBREVCTRYNAME', TObject(LOCALE_SABBREVCTRYNAME));
LStrList.AddObject('LOCALE_SNATIVECTRYNAME', TObject(LOCALE_SNATIVECTRYNAME));
LStrList.AddObject('LOCALE_IDEFAULTLANGUAGE', TObject(LOCALE_IDEFAULTLANGUAGE));
LStrList.AddObject('LOCALE_IDEFAULTCOUNTRY', TObject(LOCALE_IDEFAULTCOUNTRY));
LStrList.AddObject('LOCALE_SISO639LANGNAME', TObject(LOCALE_SISO639LANGNAME));
LStrList.AddObject('LOCALE_SISO3166CTRYNAME', TObject(LOCALE_SISO3166CTRYNAME));
//情報に応じた値を順番に取得
for LIndex := 0 to LStrList.Count - 1 do begin
FillChar(LpcLCA, SizeOf(LpcLCA), #0);
LCData := Cardinal(LStrList.Objects[LIndex]);
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LCData, LpcLCA, Length(LpcLCA));
//取得した値を表示
//桁位置を揃えたいのでAnsiStringを使用
//欧文フォントの場合,等幅フォントでも位置がづれることがある
LDataText := AnsiString(LpcLCA);
LFlagText := AnsiString(LStrList[LIndex]);
LRetText := AnsiStrings.Format('%-16s%-25s%', [LDataText, LFlagText]);
Memo1.Lines.Add(String(LRetText));
end;
finally
FreeAndNil(LStrList);
end;
end;
上のサンプルの実行結果から,言語コードである ja の値を取得するには GetLocaleInfo 関数の第 2 引数に LOCALE_SISO639LANGNAME を指定すればいいことが分かります.以下は言語コードだけを取得するサンプルです.
これは ISO639-1 の言語コードの値です. |
|
図3
言語コードを取得するサンプルの実行結果 |
//=============================================================================
// ロケールの言語コードを取得
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LpcLCA : array[0..LOCALE_NAME_MAX_LENGTH - 1] of Char;
LRetText : string;
begin
Memo1.Lines.Clear;
FillChar(LpcLCA, SizeOf(LpcLCA), #0);
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
LOCALE_SISO639LANGNAME,
LpcLCA,
Length(LpcLCA));
LRetText := LpcLCA;
Memo1.Lines.Add(LRetText);
end;
02_GetSystemDefaultLocaleName 関数を使用したロケール名取得 |
GetSystemDefaultLocaleName 関数,あるいは GetUserDefaultLocaleName 関数を使用すると,ja-JP のような [言語コード] と [国コード] を組み合わせたロケール名が取得できます.その例です.
これらの関数は Windows Vista 以降で使用可能です.
結果の JP は ISO3166-1 の国コードの値です. |
[備考]
Delphi XE7 以降には,GetSystemDefaultLocaleName 関数と GetUserDefaultLocaleName
関数が実装されています.下のコードのこれらの関数の定義コードは必要ありません. |
|
図4
言語コードと国コードの組み合わせを取得
- 筆者の環境では,[Button1] クリックの実行結果も [Button2] クリックの実行結果も同じ
|
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
function GetSystemDefaultLocaleName(
lpLocaleName : LPWSTR;
cchLocaleName : Integer) : Integer; stdcall; external 'Kernel32.dll';
function GetUserDefaultLocaleName(
lpLocaleName : LPWSTR;
cchLocaleName : Integer) : Integer; stdcall; external 'Kernel32.dll';
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// システムの既定ロケールの言語を取得
// [言語コード]-[国コード] の組み合わせの値を取得
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LCharArr : array [0..LOCALE_NAME_MAX_LENGTH - 1] of Char;
begin
Memo1.Lines.Clear;
FillChar(LCharArr, SizeOf(LCharArr), #0);
GetSystemDefaultLocaleName(LCharArr, Length(LCharArr));
Memo1.Lines.Add(LCharArr);
end;
//=============================================================================
// ユーザの既定ロケールの言語を取得
// [言語コード]-[国コード] の組み合わせの値を取得
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LCharArr : array [0..LOCALE_NAME_MAX_LENGTH - 1] of Char;
begin
Memo1.Lines.Clear;
FillChar(LCharArr, SizeOf(LCharArr), #0);
GetUserDefaultLocaleName(LCharArr, Length(LCharArr));
Memo1.Lines.Add(LCharArr);
end;
end.
関数の実行結果を String 型の文字列変数で取得するには,String 型の文字列変数のサイズを設定してから関数を実行します.
関数の実行結果を PChar 型の文字列変数で取得するには,PChar 型の文字列変数の領域を確保してから関数を実行します. |
procedure TForm1.Button1Click(Sender: TObject);
var
LText : string;
begin
Memo1.Lines.Clear;
SetLength(LText, LOCALE_NAME_MAX_LENGTH);
GetSystemDefaultLocaleName(PChar(LText), Length(LText));
Memo1.Lines.Add(LText);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
LCharCnt : Integer;
LPChar : PChar;
begin
Memo1.Lines.Clear;
LCharCnt := (LOCALE_NAME_MAX_LENGTH + 1);
LPChar := StrAlloc(LCharCnt);
try
GetSystemDefaultLocaleName(LPChar, LCharCnt);
Memo1.Lines.Add(LPChar);
finally
StrDispose(LPChar);
end;
end;
|