windows - Windows 如何更改键盘布局?

标签 windows winapi keyboard-layout

执行此操作的热键是:

Alt+Shift - Windows 7 以及 Win 8 和 10 中的Win 按钮 + 空格

以编程方式,我可以使用WM_INPUTLANGCHANGEREQUEST来做到这一点,但这不是Windows的方式。我试图弄清楚 Windows 如何改变布局。使用 spy++ 我发现 Windows 发送了 WM_INPUTLANGCHANGE 消息来改变布局,所以我自己尝试了一下:

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

我有键盘钩子(Hook)绑定(bind),当按 f1 时向当前事件窗口的事件控件发送消息。

但它不起作用,尽管 spy ++中的消息是相同的:

img

第一个使用“Windows热键”/“任务栏”来更改布局,它有效。第二条我的消息,它不起作用。我是否遗漏了一些东西,为什么消息适用于“Windows”但不适用于我。

WM_INPUTLANGCHANGEREQUEST 可以工作,但它会卡住某些特定的应用程序,我想弄清楚 Windows 更改布局的方式以避免这种情况。

--更新

在 DxO Photolab 3 中,当在“导出到磁盘”对话框中使用 WM_INPUTLANGCHANGE 时,它会卡住:

当您使用“Windows”方法(键盘热键/任务栏)更改布局时: 2020 04 19 - 22'11'40_rect 工作正常,不卡顿。

发布 WM_INPUTLANGCHANGE: 2020 04 19 - 22'10'06_rect 收到WM_INPUTLANGCHANGEREQUEST就卡住了: 2020 04 19 - 22'05'07_rect

我在 Skype、MS Office、Adobe After Effects 中也看到过类似的卡住情况。

最佳答案

来自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.

我们可以通过spy++查看详细信息。

1

只有在应用程序收到 WM_INPUTLANGCHANGEREQUEST 消息后,才会激活新的输入区域设置,并通过发送 WM_INPUTLANGCHANGE 消息来通知应用程序更改。

一个简单的测试:

2

根据我的理解,真正起作用的是WM_INPUTLANGCHANGEREQUEST消息,但我还没有找到替代的API来完成其工作。

针对您遇到的某些应用的卡顿问题,我发现了一些类似的案例。

引用@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)

更新:

我的测试代码:

#include <Windows.h>

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

结果:

2

关于windows - Windows 如何更改键盘布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61310903/

相关文章:

windows - 删除名称中包含 "EXAMPLE"的打印机

windows - windows中的START命令——系统无法接受启动命令参数1

c++ - 为什么 GID_ZOOM 的中心点会改变?

unicode - Tkinter 条目接受 Unicode 文本?

windows - 通过powershell在windows 10中添加国际英语键盘

windows - VBA 获取当前机器上的可用语言列表

c# - 如何查找进程属于哪个产品?

windows - Windows 上的 Mercurial "hg clone"通过 ssh 出现 plink 问题

c++ - 具有不存在的线程 ID 的 OpenThread

c++ - 以随机访问模式访问原始磁盘 C++