在多语言计算机中检测当前键盘语言/布局名称

9

我正在开发一个C#应用程序,它需要检测用户选择的语言(键盘布局)。 然而,在我的电脑上安装了两种语言,代码总是返回默认语言,即使我在运行应用程序之前更改了语言。

InputLanguage myCurrentLanguage = InputLanguage.InstalledInputLanguages[1]; // here I can see collection of languages 
InputLanguage myCurrentLanguage2 = InputLanguage.CurrentInputLanguage; // always return first or default one

有没有技术可以检测真正选择/运行的语言?

只是需要注意,如果您使用语言栏更改输入,而不是系统默认语言,则此代码对我有效(似乎不起作用,但Windows 8语言控制面板很混乱,所以我可能没有正确设置)。 - Rhumborl
6个回答

7
在命名空间System.Threading中,Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName返回默认文化,并且与键盘布局无关。例如,在我的计算机上,它返回"de",这是我用于日期和数字格式的文化。但是,我使用的是US-ASCII键盘,从System.Windows.Forms.InputLanguage.CurrentInputLanguage.Culture.Name.LayoutName返回分别为"en-US""US"Thread.CurrentThread.CurrentCulture提供了许多其他信息,如KeyboardLayoutIdDisplayName(本地化文化名称),EnglishNameDateTimeFormat等。
我进行了一些测试并注意到了奇怪的行为。我显示了Windows语言栏并选择了一个辅助输入语言。但是,每当我启动一个小测试WinForms应用程序时,输入语言会自动切换回默认语言。一旦应用程序启动,我就将输入语言切换回副本。现在它停留在此处。
在这两种情况下,这给了我正确的输入语言(在语言栏上显示的语言)。
lblInputLanguage.Text = InputLanguage.CurrentInputLanguage.Culture.Name;
lblKeyboardLayout.Text = InputLanguage.CurrentInputLanguage.LayoutName;

这个在 superuser 上的帖子可能会解决这个问题:如何避免 Windows 自动更改键盘布局


谢谢Olivier,我尝试了一下,出现了一个错误,提示Threading命名空间中不存在CurrentCulture。 - Shaahin
Thread.CurrentCulture.TwoLetterISOLanguageName。或者使用 using System.Threading; 后,只需写 Thread.CurrentCulture.TwoLetterISOLanguageName - Olivier Jacot-Descombes
1
这个例子涉及到文化和检索默认的文化,但我需要语言或键盘可能是不同的。 例如:我的默认文化/键盘是英语,但第二个是德语。我想检测用户选择的键盘。 - Shaahin
例如,如果我尝试获取键盘ID,int KeybId = Thread.CurrentThread.CurrentCulture.KeyboardLayoutId; 它仍然返回第一语言。 - Shaahin
@Shaahin 每个线程都有自己的输入语言。当您启动新应用程序时,它会获取默认的输入语言。请注意,当您更改应用程序时,键盘布局将切换回您在该应用程序中选择的语言。没有全局输入语言。 - Luaan
好的,但是你在操作系统中定义了一个标准输入语言,并期望启动应用程序将其作为默认语言。问题是,更改Windows语言栏中的输入语言是否会更改默认语言,还是仅更改当前应用程序的输入语言? - Olivier Jacot-Descombes

3

这个函数返回当前活动的输入语言(即您当前键入的语言):

InputLanguage myCurrentLang = InputLanguage.CurrentInputLanguage;

2
对于WPF(而不是Windows Forms),有一个名为System.Windows.Input.InputLanguageManager的类,其中包含InputLanguageManager.Current.AvailableInputLanguagesInputLanguageManager.Current.CurrentInputLanguage等属性。

2

您可以通过调用GetKeyboardLayout Windows API函数来获取此功能。

键盘布局是按线程进行的。

我不知道是否有内置的托管版本此函数。


我认为它不支持C#,它属于C++。 - Shaahin
1
请在链接页面的注释部分查看您需要在C#中使用的Interop声明。 - 500 - Internal Server Error
2
@Shaahin Windows API并不属于任何一种特定的编程语言。你可以通过使用DllImport访问非托管API:http://www.webtropy.com/articles/art9-1.asp?f=GetKeyboardLayout - JLRishe
根据参考来源CurrentInputLanguage只是调用了GetKeyboardLayout,因此不清楚为什么会有任何不同。 - Mike Zboray

0
string StrCurrentLang = InputLanguage.CurrentInputLanguage.Culture.TwoLetterISOLanguageName;

上行代码获取当前语言的最后两个字母标识

另一方面,您可以使用下段代码更改当前语言

    foreach (InputLanguage lang in InputLanguage.InstalledInputLanguages)
    {

        if (lang.Culture.TwoLetterISOLanguageName != StrCurrentLang )
        {
            InputLanguage.CurrentInputLanguage = lang;
            return;
        }
    }

0

你需要取消勾选 设置/设备/输入/高级键盘 下的 让我为每个应用程序窗口设置不同的输入法 选项。

string lang = InputLanguage.CurrentInputLanguage.Culture.Name;

操作。如果你这样做,它将返回你当前使用的语言布局,即使它与你的默认键盘语言不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接