In this program written below, using the GetKeyboardLayoutName from user32.dll. When I type the first symbol using the "English USA" layout, I get 00000409. This is fine. But when I change my layout to something else, like "English UK" or "Russian", GetKeyboardLayoutName returns the code for "English USA" - 00000409.
I tested this and if I input the first symbol in "Russian", it returns 00000419 and if I switch back to "English USA" and input a second symbol, GetKeyboardLayoutName still returns the code for "Russian" - 00000419.
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace ConsoleApp2
{
class Program
{
const int KL_NAMELENGTH = 9;
[DllImport("user32.dll")]
private static extern long GetKeyboardLayoutName(StringBuilder pwszKLID);
public static string GetLayoutCode()
{
var name = new StringBuilder(KL_NAMELENGTH);
GetKeyboardLayoutName(name);
return name.ToString();
}
static void Main(string[] args)
{
Console.ReadKey();
var res = GetLayoutCode();
Console.WriteLine("\n" res);
Console.ReadKey();
res = GetLayoutCode();
Console.WriteLine("\n" res);
}
}
}
CodePudding user response:
The problem is that a console application doesn't allow you to handle windows messages.
You could convert your application to winforms application, make the main form hidden and subclass WndProc
to handle the WM_INPUTLANGCHANGE
message that triggers on the keyboard layout change:
public class MyHiddenForm : Form
{
...
protected override void WndProc(ref Message m)
{
const int WM_INPUTLANGCHANGE = 0x0051;
if (m.Msg == WM_INPUTLANGCHANGE)
{
Console.WriteLine("{0:X8} {1:X8}", m.WParam.ToInt64() , m.LParam.ToInt64());
}
base.WndProc(ref m);
}
}
Another approach is to create a hidden window via WinAPI in the console application that will receive messages. But i'd personally prefer the first approach.
CodePudding user response:
If you don't need a KLID (keyboard layout identifier) specifically, and you just need a way to identify keyboard layouts then you can use the following to get the HKL (input locale identifier):
var focusedHWnd = GetForegroundWindow();
var activeThread = GetWindowThreadProcessId(focusedHWnd, IntPtr.Zero);
var hkl = GetKeyboardLayout(activeThread);