BladeMight
BladeMight

Reputation: 2810

How does Windows changes keyboard layout?

The hotkeys for doing so are:

Alt+Shift - Windows 7 and Win button + Space in Win 8 and 10.

Programmatically I can do that using WM_INPUTLANGCHANGEREQUEST, but it is not the way Windows does that. I am trying to figure out how Windows changes the layout. Using spy++ I figured out that Windows sends WM_INPUTLANGCHANGE message which is changing layout, so I tried it myself:

SendMessage(myHWND, WM_INPUTLANGCHANGE, 0xCC, 0x4190419);

I have keyboard hook bind, when press f1 do the sendmessage to currently active window's active control.

but it didn't work, though the messages in spy++ are thes same:

img

first one using "Windows hotkey"/"Taskbar" to change layout, it works. Second my message, it did not work. Am I missing something, why message works for "Windows" but not for me.

The WM_INPUTLANGCHANGEREQUEST works, but it freezes some certain apps, and I would like to figure out the way Windows does the layout changing to avoid that.

-- update.

In DxO Photolab 3 it freezes when using WM_INPUTLANGCHANGE in "Export to Disk" Dialog:

When you change layout using "Windows" Method(Keyboard Hotkey/Taskbar): 2020 04 19 - 22'11'40_rect Works normally, no freezing.

Posting the WM_INPUTLANGCHANGE: 2020 04 19 - 22'10'06_rect Received the WM_INPUTLANGCHANGEREQUEST and froze: 2020 04 19 - 22'05'07_rect

Also similar freezing I've seen in Skype, MS Office, Adobe After Effects.

Upvotes: 2

Views: 623

Answers (1)

Strive Sun
Strive Sun

Reputation: 6289

From WM_INPUTLANGCHANGEREQUEST,

When the DefWindowProc function receives the WM_INPUTLANGCHANGEREQUEST message, it activates the new input locale and notifies the application of the change by sending the WM_INPUTLANGCHANGE message.

We can view the details through spy++.

1

Only after the application receives the WM_INPUTLANGCHANGEREQUEST message, it will activate the new input locale, and notifies the application of the change by sending the WM_INPUTLANGCHANGE message.

A simple test:

2

According to my understanding, what actually works is the WM_INPUTLANGCHANGEREQUEST message, but I have not found an alternative API to complete its work.

For the freezing problem of some certain apps you encountered, I found some similar cases.

Refer @Barmak Shemirani's answer,

Apparently WM_INPUTLANGCHANGEREQUEST fails if the target itself is a dialog based application (I don't know why!) To solve the problem you can post WM_INPUTLANGCHANGEREQUEST message to dialog's descendants (in addition to WM_INPUTLANGCHANGEREQUEST message to the dialog itself)

Updated:

My test code:

#include <Windows.h>

int main()
{       
    HWND hwnd = (HWND)0x00070EBA; // hwnd of skype
    while (1)
    {
        Sleep(1000);
        PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, 0, 0);
    }
    return 0;
}

Result:

2

Upvotes: 3

Related Questions