As you already know, the System.Windows.Forms.InputLanguage.CurrentInputLanguage.LayoutName property returns the keyboard layout for the current stream, and no matter which layout you choose, it will remain the same for the executable stream if you do not select that window and change keyboard input location for this window.
However, what you are basically trying to do is check out the current keyboard layout culture and find out when it will change. Some time ago, I had a similar requirement, and I came up with the following code that served me well:
public delegate void KeyboardLayoutChanged(int oldCultureInfo, int newCultureInfo);
class KeyboardLayoutWatcher : IDisposable
{
private readonly Timer _timer;
private int _currentLayout = 1033;
public KeyboardLayoutChanged KeyboardLayoutChanged;
public KeyboardLayoutWatcher()
{
_timer = new Timer(new TimerCallback(CheckKeyboardLayout), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
}
[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 int GetCurrentKeyboardLayout()
{
try
{
IntPtr foregroundWindow = GetForegroundWindow();
uint foregroundProcess = GetWindowThreadProcessId(foregroundWindow, IntPtr.Zero);
int keyboardLayout = GetKeyboardLayout(foregroundProcess).ToInt32() & 0xFFFF;
if (keyboardLayout == 0)
{
keyboardLayout = 1033;
}
return keyboardLayout;
}
catch (Exception ex)
{
return 1033;
}
}
private void CheckKeyboardLayout(object sender)
{
var layout = GetCurrentKeyboardLayout();
if (_currentLayout != layout && KeyboardLayoutChanged != null)
{
KeyboardLayoutChanged(_currentLayout, layout);
_currentLayout = layout;
}
}
private void ReleaseUnmanagedResources()
{
_timer.Dispose();
}
public void Dispose()
{
ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}
~KeyboardLayoutWatcher()
{
ReleaseUnmanagedResources();
}
}
And use it like:
new KeyboardLayoutWatcher().KeyboardLayoutChanged += (o, n) =>
{
this.CurrentLayoutLabel.Text = $"{o} -> {n}"; // old and new KB layout
};
source
share