免責事項:私は .NET Framework のグローバリゼーション側の専門家ではないため、同等の機能がどこかにラップされている可能性があります。もしそうなら、あなたはそれを見つけることができます.素晴らしい - 代わりにそれを使用してください. Globalization.CultureInfo.CurrentCulture
探している情報が返されるのではないかと思っていましたが、残念ながらそうではありません。代わりに、キーボード レイアウトが変更された場合でも、システムの既定のカルチャを返すように見えます。調べるのをやめました。説明されているアプローチは、コードが少し追加されますが、動作することが保証されています。
特定のキーボード レイアウトに関連付けられているコード ページを確認するには、Win32GetLocaleInfo
関数を呼び出して、現在のキーボード レイアウトに関連付けられている言語 ID を指定します。LOCALE_IDEFAULTANSICODEPAGE
定数を使用してこれを要求します。
これらの関数を .NET アプリケーションから呼び出すには、P/Invoke を使用する必要があります。また、いくつかの重要なマクロに対して同等の関数を定義する必要があります。
const int LOCALE_IDEFAULTANSICODEPAGE = 0x1004;
const int LOCALE_RETURN_NUMBER = 0x20000000;
const int SORT_DEFAULT = 0x0;
static int LOWORD(IntPtr val)
{
return (unchecked((int)(long)val)) & 0xFFFF;
}
static int MAKELCID(int languageID, int sortID)
{
return ((0xFFFF & languageID) | (((0x000F) & sortID) << 16));
}
static int MAKELANGID(int primaryLang, int subLang)
{
return ((((ushort)(subLang)) << 10) | (ushort)(primaryLang));
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern int GetLocaleInfo(int locale,
int lcType,
out uint lpLCData,
int cchData);
[DllImport("user32.dll")]
static extern IntPtr GetKeyboardLayout(uint idThread);
次のように使用します。
// Get the keyboard layout for the current thread.
IntPtr keybdLayout = GetKeyboardLayout(0);
// Extract the language ID from it, contained in its low-order word.
int langID = LOWORD(keybdLayout);
// Call the GetLocaleInfo function to retrieve the default ANSI code page
// associated with that language ID.
uint codePage = 0;
GetLocaleInfo(MAKELCID(langID, SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
out codePage,
Marshal.SizeOf(codePage));
米国英語のキーボード レイアウトでテストすると、codePage
1252 です。ギリシャ語のキーボード レイアウトに切り替えた後codePage
は、1253 です。同様に、トルコ語は 1254 を返し、さまざまなキリル言語は 1251 を返します。文書化されているとおりです。
リンクされたドキュメントでは、これらの API 関数は置き換えられたものとして示されていることに注意してください。最新バージョンの Windows では、Microsoft は名前付きロケールに移行しました。これは、最初に数値 ID の余地がなかったためであり、次にカスタム ロケールのサポートを有効にするためでした。ただし、実行していることには古い関数を使用する必要があります。最新の Windows アプリケーションも ANSI コード ページを使用していません。
ただし、逆に噛まれてしまうこともあるので注意が必要です。ANSI コード ページが関連付けられていないキーボード レイアウトがあります。これらには、Unicode のみを使用できます。上記のコードはCP_ACP
(数値に相当する) を返します0
。その扱いはあなた次第です。エラーを表示するか、ファイルを Unicode として保存する必要があります (他のアプリケーションを壊しますが、ユーザーの期待に応えます)。
最後に、値をキャッシュするcodePage
と、ユーザーがいつでもキーボード レイアウトを変更できるため、値が古くなる可能性があることを指摘しておく必要があります。保存を実行するたびに値を決定して、値をキャッシュしない方がおそらく最も簡単です。WM_INPUTLANGCHANGE
ただし、キャッシュする場合は、メッセージを処理し、それに応じてキャッシュされた値を更新する必要があります。