Find out when keyboard layout is changed
-
10-03-2021 - |
Question
I am writing an onscreen keyboard and would like to redraw my layout as soon as keyboard layout is changed.
Currently I call:
GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), NULL));
on every key press to find out if the layout has changed. It does not work if user changes the layout by mouse, until key is pressed.
I would like to know if there is any way to get notified when the keyboard layout of the current foreground window is changed, so I can redraw my layout as soon as the change happens.
Solution
There is a way ...
First you need to register your application to capture foreground window changes:
Use SetWinEventHook
with EVENT_SYSTEM_FOREGROUND
(and WINEVENT_OUTOFCONTEXT
as it's .NET) for that.
If that happens: Use your GetKeyboardLayout
solution for getting the current layout of that window.
Then use a local Windows Hook (you're probably using it low-level-globally for key captures) with WH_CALLWNDPROC
and the thread of the new foreground window.
Listen to WM_INPUTLANGCHANGE
messages to that window to receive changes to the layout.
(You may want to unhook/rehook after another foreground change)
OTHER TIPS
It looks like the keyboard layout is stored here: HKEY_CURRENT_USER\Keyboard Layout\Preload
When I changed keyboard languages, the order of settings there changed.
So you could possibly monitor the registry entry. Here's one way: