I wanna detect every keyboard layout change with C#. It doesn't matter whether it is switched by win + space or alt + shift or with mouse... I wrote a code that works considerably well (see below) for desktop apps. But it doesn't work for UWP apps. If I switch layout while within the UWP app, it is not detected, if I switch to desktop app the change is detected right away... How can I do it to detect any change in the layout? Is there any other way how to find out what layout is active at any given moment no matter what window is active? My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string lastLang = "";
while (true)
{
string langSuffix = GetKeyboardLayoutIdAtTime();
if (!langSuffix.Equals(lastLang))
{
// do something
Console.WriteLine(getCurrentTimeStamp() + ": Changing '" + lastLang + "' to '" + langSuffix + "'.");
lastLang = langSuffix;
}
System.Threading.Thread.Sleep(1000);
}
}
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern int GetWindowThreadProcessId(IntPtr handleWindow, out int lpdwProcessID);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern IntPtr GetKeyboardLayout(int WindowsThreadProcessID);
public static string GetKeyboardLayoutIdAtTime()
{
IntPtr hWnd = GetForegroundWindow();
int lpdwProcessId;
InputLanguageCollection installedInputLanguages = InputLanguage.InstalledInputLanguages;
CultureInfo currentInputLanguage = null;
int WinThreadProcId = GetWindowThreadProcessId(hWnd, out lpdwProcessId);
IntPtr KeybLayout = GetKeyboardLayout(WinThreadProcId);
// this remain unchanged when I switch layouts in UWP
Console.WriteLine("KL IntPtr: " + KeybLayout);
for (int i = 0; i < installedInputLanguages.Count; i++)
{
if (KeybLayout == installedInputLanguages[i].Handle) currentInputLanguage = installedInputLanguages[i].Culture;
}
if(currentInputLanguage == null)
{
Console.WriteLine(getCurrentTimeStamp() + "current input language is null...");
}
return currentInputLanguage.TwoLetterISOLanguageName;
}
private static string getCurrentTimeStamp()
{
return DateTime.Now.ToString("yyyyMMddHHmmssffff");
}
}
}