9

I am trying to develop an application in C# which required to detect user selected language (keyboard layout). However two languages are installed on my computer, the code always returns the default one, even I change the language before run the application.

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

Is there any technique to detect the real selected / running language?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Shaahin
  • 1,195
  • 3
  • 14
  • 22
  • Just to note, this code does work for me if you change the input using the Language Bar, as opposed the system default language, (which appeared not to work but the Windows 8 language control panel is confusing so I may not have set things up right) – Rhumborl Jan 02 '15 at 19:13

6 Answers6

7

Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName in the namespace System.Threading returns what you call the default culture and is not related to the keyboard layout. I.e. on my computer this returns "de", the culture I am using for date and number formatting. However, I am using an US-ASCII keyboard and .Culture.Name and .LayoutName from System.Windows.Forms.InputLanguage.CurrentInputLanguage return "en-US" and "US" respectively.

Thread.CurrentThread.CurrentCulture gives a lot of additional information like KeyboardLayoutId, DisplayName (localized culture name), EnglishName, DateTimeFormat and more.


I made some tests and noticed a strange behavior. I displayed the Windows language bar and selected a secondary input language. But whenever I started a little test-WinForms application, the input language automatically switched back to the default language. Once the application was started, I switched back the input language to the secondary one. Now it stayed to this one.

In both cases this gave me the correct input language (the one displayed on the language bar):

lblInputLanguage.Text = InputLanguage.CurrentInputLanguage.Culture.Name;
lblKeyboardLayout.Text = InputLanguage.CurrentInputLanguage.LayoutName;

This thread on superuser might shed some light on the problem: How to avoid keyboard layout automatically changing on windows

Community
  • 1
  • 1
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • Thank you Olivier, I tried it, an error appears that CurrentCulture does not exist in Threading namespace. – Shaahin Jan 02 '15 at 19:26
  • `System.Threading.Thread.CurrentCulture.TwoLetterISOLanguageName`. Or with a `using System.Threading;` just `Thread.CurrentCulture.TwoLetterISOLanguageName`. – Olivier Jacot-Descombes Jan 02 '15 at 19:38
  • 1
    This example deals with the culture and retrieve the default one, but I need the language or keyboard which might be different. for example: my default culture / keyboard is English but second one is German. I want detect the selected keyboard by user. – Shaahin Jan 02 '15 at 19:52
  • For example, if I try to get keyboard id, int KeybId = Thread.CurrentThread.CurrentCulture.KeyboardLayoutId; it still return first language. – Shaahin Jan 02 '15 at 19:59
  • @Shaahin Every thread has its own input language. When you start a new application, it gets the default input language. Note that when you change applications, the keyboard layout will switch back to what you had selected before *in that application*. There is no *global* input language. – Luaan Feb 08 '17 at 09:47
  • Ok, but you define a standard input language in the OS and expect starting applications to take this as default. The question is, whether changing the input language in the Windows language bar changes that default, or whether it changes only the input language of the current application? – Olivier Jacot-Descombes Feb 08 '17 at 13:12
3

This one returns the input language currently active (the one that is your keyboard types currently):

InputLanguage myCurrentLang = InputLanguage.CurrentInputLanguage;
ib11
  • 2,530
  • 3
  • 22
  • 55
2

You can get this by calling the GetKeyboardLayout Windows API function.

Keyboard layout is by thread.

I am not aware if there is a built-in managed version of this function.

  • I think it does not support in C#, it belong to C++ – Shaahin Jan 02 '15 at 19:08
  • 1
    See the interop declaration you need to use from C# in the comment section on the linked page. – 500 - Internal Server Error Jan 02 '15 at 19:09
  • 2
    @Shaahin Windows APIs don't belong to any single language. You can access non-managed APIs by using `DllImport`: http://www.webtropy.com/articles/art9-1.asp?f=GetKeyboardLayout – JLRishe Jan 02 '15 at 19:10
  • According to the [reference source](http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/InputLanguage.cs,da996582673486e5), `CurrentInputLanguage` just calls `GetKeyboardLayout`, so its not clear why this would be any different. – Mike Zboray Jan 02 '15 at 19:17
2

For WPF (instead of Windows Forms) there's System.Windows.Input.InputLanguageManager which has InputLanguageManager.Current.AvailableInputLanguages and InputLanguageManager.Current.CurrentInputLanguage etc.

Peter
  • 3,322
  • 3
  • 27
  • 41
0

You've gotta uncheck the setting let me set a different input method for each app window under Settings/Devices/Typing/Advanced Keyboard for the

string lang = InputLanguage.CurrentInputLanguage.Culture.Name;

to work. If you do so, it will return the current language layout that you use to type, even if it's different to your default keyboard language.

davidanderle
  • 638
  • 6
  • 12
0
string StrCurrentLang = InputLanguage.CurrentInputLanguage.Culture.TwoLetterISOLanguageName;

up line code get you two last letter sign of current language

on the other side you can change current language by using down paragraph code

    foreach (InputLanguage lang in InputLanguage.InstalledInputLanguages)
    {

        if (lang.Culture.TwoLetterISOLanguageName != StrCurrentLang )
        {
            InputLanguage.CurrentInputLanguage = lang;
            return;
        }
    }
Esi
  • 389
  • 5
  • 14