Necky
Necky

Reputation: 70

LoadKeyboardLayout doesn't change keyboard layout

I'm trying to change the keyboard layout to English, but the changes don't reflect in Windows.

The layout is installed, I have checked with GetKeyboardLayoutList.

screenshot

Code:

#include <windows.h>

int main()
{
    LoadKeyboardLayout("00000409", KLF_ACTIVATE);
    return 0;
}

GetKeyboardLayoutName shows that the language has changed, but I don't see that in Windows

Test code:

#include <windows.h>
#include <iostream>
using namespace std;

int main()
{
    TCHAR keyboard[KL_NAMELENGTH];
    GetKeyboardLayoutName(keyboard);
    cout << keyboard << endl;

    LoadKeyboardLayout("00000409", KLF_ACTIVATE);

    GetKeyboardLayoutName(keyboard);
    cout << keyboard << endl;

    return 0;
}

Outputs:

00000405
00000409
[Finished in 2.2s]

UPDATE: Tried runnin the .exe on different windows computer, same result

Upvotes: 0

Views: 3069

Answers (1)

Maximus
Maximus

Reputation: 10855

Working with keyboard layout is rather tricky and it is different for Console and GUI applications. And LoadKeyboardLayout just make the layout "available" for activation unfortunately.

GUI

  1. Application must have GetMessage, TranslateMessage, DispatchMessage cycle. (Sublime has GetMessage cycle)
  2. You may switch layout with two sequental calls

    DWORD dwNewKeybLayout = 0x00000409; // Layout must be already loaded!
    PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 0, (LPARAM)dwNewKeybLayout);
    PostMessage(hWnd, WM_INPUTLANGCHANGE, 0, (LPARAM)dwNewKeybLayout);
    

Console

Your application with int main() is console application, it does not have GetMessage cycle. All messages are processed by conhost itself. That's why your GetKeyboardLayoutName will not return correct result. Never! No way!

However, you still may change layout for all processes are running in this console window. But take in mind, that conhost processes messages asynchronously and the actual layout (which you can't determine or check) may be changed after some lag.

    HWND hCon = GetConsoleWindow();
    DWORD dwNewKeybLayout = 0x00000409; // Layout must be already loaded!
    PostMessage(hCon, WM_INPUTLANGCHANGEREQUEST, 0, (LPARAM)dwNewKeybLayout);
    PostMessage(hCon, WM_INPUTLANGCHANGE, 0, (LPARAM)dwNewKeybLayout);

Upvotes: 2

Related Questions