12

I have a winform application, I want to get the information of current typing language in C#. I have windows 10 machine, I have selected Korean language. There is one toggle button in taskbar to change input language as English or Korean once I select Korean language.

Following code always gives Korean language, but it should give English when I select input in English.

    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();
    [DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(IntPtr hwnd, IntPtr proccess);
    [DllImport("user32.dll")]
    static extern IntPtr GetKeyboardLayout(uint thread);
    public Form1()
    {
        InitializeComponent();
        IntPtr foregroundWindow = GetForegroundWindow();
        uint foregroundProcess = GetWindowThreadProcessId(foregroundWindow, IntPtr.Zero);
        int keyboardLayout = GetKeyboardLayout(foregroundProcess).ToInt32() & 0xFFFF;
        CultureInfo info = new CultureInfo(keyboardLayout);
        int keyboardLayoutId = info.KeyboardLayoutId;
        string name = info.Name;
    }

Is there any other way to get the input language information.

You can find the attached image for the same. I have highlighted A as english input. TaskBar Screenshot English Input

TaskBar Screenshot Korean Input

I want this information in WndProc method.

Problem Summry: So I want to handle the case when User switched language to type by toggle button, I want any wndproc message or window side event to get the language information, when User switches language by toggle button.

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
  • 1
    InputLanguage.CurrentInputLanguage – Reza Aghaei Feb 08 '17 at 09:24
  • @RezaAghaei how to use InputLanguage.CurrentInputLanguage? – Vivek Nuna Feb 08 '17 at 09:25
  • I've used that is such scenario:[How to change input-language in a windows forms application for a specific control?](http://stackoverflow.com/q/35813818/3110834) – Reza Aghaei Feb 08 '17 at 09:26
  • 2
    Read the manual: https://msdn.microsoft.com/en-us/library/system.windows.forms.inputlanguage.currentinputlanguage(v=vs.110).aspx – Equalsk Feb 08 '17 at 09:27
  • @RezaAghaei InputLanguage.CurrentInputLanguage giving Korean language, but my input language is English – Vivek Nuna Feb 08 '17 at 09:30
  • Are you really expecting that the form that you're just constructing will already be the foreground window? You might want to get a better understanding of how Windows and Windows Forms work - this is a rather dangerously naive approach. And even if you *did* actually check the right form's setting, it wouldn't help you - each thread has its own input language. The application you just started would just get the default. There is no *global* input layout. – Luaan Feb 08 '17 at 09:30
  • 2
    The toolbar button changes the selected keyboard layout for the process that is in the foreground. Given that your code runs, oh, a microsecond after you start your program, you could not possibly hit that toolbar button quickly enough. So this is just a pebkac problem. Consider the InputLanguageChanged event, perhaps. – Hans Passant Feb 08 '17 at 09:30
  • @HansPassant I want this information in WndProc – Vivek Nuna Feb 08 '17 at 09:35
  • So? `InputLanguage.CurrentInputLanguage` works fine in `WndProc`. `InputLanguageChanged` allows you to respond to a change in the input language. Again, the input language is *per thread*. Just because one application uses Korean doesn't mean yours does (until you change it *for your application*). – Luaan Feb 08 '17 at 09:38
  • 1
    WM_INPUTLANGUAGECHANGE message. Already wrapped in Winforms, it fires the InputLanguageChanged event. – Hans Passant Feb 08 '17 at 09:39
  • @Luaan InputLanguage.CurrentInputLanguage is giving Korean, not English in WndProc – Vivek Nuna Feb 08 '17 at 09:43
  • And *in the same form*, *at the same time*, the taskbar is showing English? I doubt that. In your screenshots, the application with focus is Chrome - not your application. – Luaan Feb 08 '17 at 09:44
  • @Luaan yes, it English only. Focus is on my application only – Vivek Nuna Feb 08 '17 at 09:45
  • @HansPassant WM_INPUTLANGUAGECHANGE only hits when I change the language preference, not the toggle button – Vivek Nuna Feb 08 '17 at 09:52
  • So add *that* to your question, not a screenshot of Chrome. And add a real way to check the input language, not bogus code in form constructor. Make a form with a button, and on pressing the button, check the input language (say, set a label's text to `InputLanguage.CurrentInputLanguage.LayoutName`. – Luaan Feb 08 '17 at 09:52
  • I've noticed on my home Windows 10 PC (same OS as OP) what language switch is not per process/window anymore. It's rather global (or more likely per *desktop*, as you can create several and switch between them). Could be some settings to control that behavior? – Sinatr Feb 08 '17 at 09:52
  • @Luaan tried on TextChanged event also, same result its also giving Korean – Vivek Nuna Feb 08 '17 at 09:58
  • @all Please request to reopen this question, I have tried everything – Vivek Nuna Feb 08 '17 at 09:59
  • So if you put a textbox on the form and type in it, you get english text even though `InputLanguage.CurrentInputLanguage.LayoutName` returns Korean at the same time? Are you using the built-in IME in Windows, or some custom piece of software? – Luaan Feb 08 '17 at 10:01
  • @Luaan Yes, Its exactly same. "I put a textbox on the form and type in it, you get english text even though InputLanguage.CurrentInputLanguage.LayoutName returns Korean at the same time" – Vivek Nuna Feb 08 '17 at 10:02
  • @Luaan, I'm using the windows IME only – Vivek Nuna Feb 08 '17 at 10:03
  • @Luaan Once you select language as Korean, There comes a toggle button to switch between English and Korean, I have attached the image also in the question – Vivek Nuna Feb 08 '17 at 10:05
  • Okay, that explains it. That isn't the input language - it's the IME layout. You're never changing the input language. – Luaan Feb 08 '17 at 10:14
  • @Luaan, Yes I dont know what exactly I should call it, sorry for that. So Do you have any idea, how to get that? – Vivek Nuna Feb 08 '17 at 10:15
  • @all, will start bounty for this question in 2 days :P – Vivek Nuna Feb 08 '17 at 10:48

1 Answers1

0

Your question is a result of a confusion of IME mode and the input layout. Your input layout is Korean in both cases - what changes is your IME mode.

You can find the IME mode of an input control using Control.ImeMode (and check for a change using Control.ImeModeChanged). This will tell you that you're either in Korean - Hangul, or Korean - Alpha. EDIT: Actually, this only allows you to force a given setting, not read the user-specified IME mode, and apparently shouldn't be used.

Further complication is if you have global input enabled (available since Windows 8), where the input configuration is no longer stored per-thread, but rather is global. In that case ImeMode doesn't work, and is completely ignored. I don't think there's anything you can do about it from the application side - the setting is no longer yours to see or change. According to MSDN, the proper replacement would be the ImmGetConversionStatus function, though only for desktop applications.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • Its giving NoControl, in every case – Vivek Nuna Feb 08 '17 at 10:29
  • @viveknuna Yes, because you have global input enabled. As I noted in the third paragraph, that completely disables the `ImeMode` functionality. – Luaan Feb 08 '17 at 10:30
  • so it means these is no way to get this information that whether typing in Korean or English – Vivek Nuna Feb 08 '17 at 10:35
  • @viveknuna The best I could find is the `imm32.dll`, but I'm not sure how that would work in practice, or if it's a good idea to use it. The approach in Windows seems to be that it's not your business, so to speak - it's something for the user. And given how complex IMEs are, I can't say I disagree :D – Luaan Feb 08 '17 at 10:43
  • will start bounty for this question in 2 days :P – Vivek Nuna Feb 08 '17 at 10:48
  • tried ImmGetConversionStatus this too. but always returns true – Vivek Nuna Feb 08 '17 at 10:49
  • Please help, there is no support for IME on internet too. – Vivek Nuna Feb 08 '17 at 11:17
  • @viveknuna It only returns if the query was successful - you need to use the out arguments to get the conversion status itself. Using `out int` in the P/Invoke declaration should work fine. – Luaan Feb 08 '17 at 12:40
  • out params are same in both cases – Vivek Nuna Feb 08 '17 at 12:54
  • @viveknuna Weird. It might be that imm32 doesn't support Korean IME (it doesn't seem to be listed in the supported conversion statuses), or maybe it also doesn't work with global input modes. – Luaan Feb 08 '17 at 13:23
  • I'm really frustrated – Vivek Nuna Feb 08 '17 at 13:26