12

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.

Kromster
  • 7,181
  • 7
  • 63
  • 111
Nejchy
  • 666
  • 11
  • 24

2 Answers2

11

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)

ordag
  • 2,497
  • 5
  • 26
  • 35
0

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:

http://www.codeproject.com/KB/system/registrymonitor.aspx

Steve Wellens
  • 20,506
  • 2
  • 28
  • 69
  • Order of values in HKEY_CURRENT_USER\Keyboard Layout\Preload changes only when you change default keyboard layout or add new keyboard layout – Nejchy Dec 04 '11 at 13:12