Search code examples
c#wpfwindowskeyboardsendmessage

LoadKeyboardLayout() fails to change Keyboard Layout if the Windows Taskbar has current focus


I am changing the Keyboard Layout in Windows programmatically with global hot keys using:

IntPtr fGWindow = GetForegroundWindow();
SendMessage(fGWindow.ToInt32(), WM_INPUTLANGCHANGEREQUEST_as_unit, IntPtr.Zero, LoadKeyboardLayout(LANG, KLF_SUBSTITUTE_OK));

The code works perfectly except when I click the Windows Taskbar using the mouse (giving it current focus). In that situation, the message is sent but LoadKeyboardLayout() does noting.

Using HWND_BROADCAST instead of GetForegroundWindow() does not help.

UPDATE / More information:

The pointer obtained by GetForegroundWindow() when I click the taskbar (giving it focus) belongs to explorer.exe. In that situation the code is not working.


Solution

  • Here is the solution, basically adjustments are needed if the current foreground window is the system tray:

    IntPtr shell_TrayWnd = FindWindow("Shell_TrayWnd", null);
    
    if (fGWindow == shell_TrayWnd)
     {
       IntPtr vHandle = FindWindow("Progman", "Program Manager"); // Desktop Handler.
       SetForegroundWindow(vHandle);
       SendMessage(vHandle.ToInt32(), WM_INPUTLANGCHANGEREQUEST_as_unit, new IntPtr(-1), LoadKeyboardLayout(LANG, KLF_NOTELLSHELL));
    }