Windows如何更改键盘布局?

时间:2020-04-19 20:03:39

标签: windows winapi keyboard-layout

这样做的热键是:

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

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

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

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

但是它没有用,尽管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中也看到过类似的冻结情况。

1 个答案:

答案 0 :(得分:1)

WM_INPUTLANGCHANGEREQUEST

DefWindowProc函数收到 WM_INPUTLANGCHANGEREQUEST消息,它会激活新的输入语言环境 并通过发送更改通知应用程序 WM_INPUTLANGCHANGE条消息。

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

1

仅在应用程序收到WM_INPUTLANGCHANGEREQUEST消息后,它将激活新的输入语言环境,并通过发送WM_INPUTLANGCHANGE消息将更改通知给应用程序。

一个简单的测试:

2

根据我的理解,实际上有效的是WM_INPUTLANGCHANGEREQUEST消息,但是我还没有找到替代API来完成其工作。

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

引用@Barmak Shemirani's answer

如果目标本身是一个WM_INPUTLANGCHANGEREQUEST,显然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; } 消息)

已更新:

我的测试代码:

if (operation.operationId.Equals("Documents_Post", StringComparison.CurrentCultureIgnoreCase))
{
    if (operation.parameters == null)
        operation.parameters = new List<Parameter>(1);
    else
        operation.parameters.Clear();

    operation.parameters.Add(new Parameter
    {
        name = "File",
        @in = "formData",
        description = "File",
        required = true,
        type = "file"
    });

//hack:
    var provider = (Swashbuckle.Examples.IExamplesProvider)Activator.CreateInstance(typeof(DocumentMetadataModel));
    var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(provider.GetExamples());
    var result = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);

    operation.parameters.Add(new Parameter
    {
        name = "Metadata",
        @in = "formData",
        description = $"Example:{result}",
        required = true,
        type = "string"
    });
}

结果:

2

相关问题