using System.Runtime.InteropServices; namespace CursorLang.Interop; /// /// Win32 API для определения раскладки активного приложения. /// internal static class KeyboardLayoutNative { [DllImport("user32.dll")] internal static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId); [DllImport("user32.dll")] private static extern IntPtr GetKeyboardLayout(uint idThread); /// /// Раскладка, которой сейчас печатает пользователь. /// /// /// Спрашиваем окно с фокусом клавиатуры, а не окно верхнего плана: у Блокнота /// Windows 11, меню «Пуск» и прочих приложений на WinUI поле ввода живёт в /// отдельном потоке, и раскладка меняется только у него. У потока главного /// окна она остаётся прежней, и переключение проходит незамеченным. /// internal static int GetActiveLocaleId() { if (ForegroundInputNative.TryGetInfo(out ForegroundInputNative.GuiThreadInfo info) && info.hwndFocus != IntPtr.Zero) { return GetLocaleIdOf(info.hwndFocus); } return GetLocaleIdOf(GetForegroundWindow()); } /// /// Идентификатор локали для окна. Раскладка в Windows привязана к потоку, /// поэтому так её видно у любого приложения, а не только у своего. /// internal static int GetLocaleIdOf(IntPtr hWnd) { uint threadId = GetWindowThreadProcessId(hWnd, IntPtr.Zero); return (int)GetKeyboardLayout(threadId).ToInt64() & 0xFFFF; } }