【问题标题】:How does Windows changes keyboard layout?Windows 如何更改键盘布局?
【发布时间】:2020-08-02 06:33:33
【问题描述】:

这样做的热键是:

Alt+Shift - Win 8 和 10 中的 Windows 7 和 Win button + Space

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

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

我有键盘钩子绑定,当按下 f1 时发送消息到当前活动窗口的活动控件。

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

第一个使用“Windows 热键”/“任务栏”来更改布局,它可以工作。其次我的信息,它没有工作。我是否遗漏了什么,为什么消息适用于“Windows”但不适用于我。

WM_INPUTLANGCHANGEREQUEST 可以工作,但它会冻结某些应用程序,我想弄清楚 Windows 是如何改变布局以避免这种情况发生的。

-- 更新

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

当您使用“Windows”方法(键盘热键/任务栏)更改布局时: 工作正常,不结冰。

发布 WM_INPUTLANGCHANGE: 收到 WM_INPUTLANGCHANGEREQUEST 并冻结:

我在 Skype、MS Office、Adobe After Effects 中也看到过类似的冻结。

【问题讨论】:

  • "WM_INPUTLANGCHANGEREQUEST 有效,但它会冻结某些应用程序" 您使用什么功能来传递此消息?
  • @BenVoigt 我尝试了SendMessagePostMessage,它们都不适用于“某些应用程序”。
  • Win 8和Win 10可以使用SendInput模拟Win button + Space
  • @StriveSun-MSFT 我知道,但是如果我这样做时用户按住 Win 按钮怎么办?
  • @BladeMight 使用GetAsyncKeyState 检测是否按下了 Win 按钮。

标签: windows winapi keyboard-layout


【解决方案1】:

来自WM_INPUTLANGCHANGEREQUEST

DefWindowProc 函数接收到 WM_INPUTLANGCHANGEREQUEST 消息,它会激活新的输入语言环境 并通过发送 WM_INPUTLANGCHANGE消息。

我们可以通过spy++查看详情。

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

一个简单的测试:

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

对于您遇到的某些应用程序的冻结问题,我发现了一些类似的情况。

参考@Barmak Shemirani's answer

如果目标本身是一个 基于对话框的应用程序(我不知道为什么!)解决你的问题 可以向对话框的后代发布WM_INPUTLANGCHANGEREQUEST 消息(在 除了WM_INPUTLANGCHANGEREQUEST 对话框本身的消息)

更新:

我的测试代码:

#include <Windows.h>

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

结果:

【讨论】:

  • 我已经尝试了您引用的答案中的解决方法,但运气不好,我的情况不同,它只是冻结了我所做的一切。无论如何,面包谢谢你的时间。 “它激活了新的输入语言环境”:我想知道此时发生了什么...但是“Windows”(当您使用键盘快捷键/任务栏更改布局时)设法做到了没有WM_INPUTLANGCHANGEREQUEST,那是怎么回事。我怀疑 Windows 在某个地方“有”该布局实例,并且可以自行更改它,而无需使用 WM_INPUTLANGCHANGEREQUEST 通知应用程序,仅使用 WM_INPUTLANGCHANGE...
  • @BladeMight 哪些应用程序将被冻结?您介意在问题中添加这些细节吗?包括可以重现问题的代码和您尝试过的应用程序。
  • @BladeMight 我已经在 Skype、MS Office 中进行了测试,但我无法重现您的问题。您发送WM_INPUTLANGCHANGEREQUEST 进行测试了吗?为了让测试结果更有说服力,我添加了 gif 图片。
  • 我认为 Skype/MS Office 问题出在旧版本上(大约一年前),并且它在“文本输入”中 - 而不是在窗口本身中,目前我也无法用它们重现该问题,但随着 DxO Photolab 3 冻结正在发生。
  • 好吧,我猜可能是“DxO 内部的消息处理”。谢谢您的宝贵时间。
猜你喜欢
  • 1970-01-01
  • 2012-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-03
  • 2012-12-20
  • 2018-10-03
  • 1970-01-01
相关资源
最近更新 更多