win32 窗口阻止键盘布局更改

Posted

技术标签:

【中文标题】win32 窗口阻止键盘布局更改【英文标题】:win32 window blocking keyboard layout changes 【发布时间】:2021-06-23 00:26:19 【问题描述】:

我遇到了一个问题,即当应用程序处于焦点时,用户无法更改键盘布局。单击任务栏中的语言首选项或使用快捷键 Alt+Shift 时,它不起作用。我也没有收到任何 WM_INPUTLANGCHANGEREQUESTWM_INPUTLANGCHANGE 事件,这是我所预料的。

#include <Windows.h>
#include <stdio.h>

static int close_requested = 0;

static LRESULT CALLBACK wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

    switch (msg) 
    case WM_CLOSE:
        close_requested = 1;
        break;
    case WM_INPUTLANGCHANGE:
        puts("WM_INPUTLANGCHANGE");
        break;
    case WM_INPUTLANGCHANGEREQUEST:
        puts("WM_INPUTLANGCHANGEREQUEST");
        break;
    

    return DefWindowProc(hWnd, msg, wParam, lParam);


int main(void)

    const HINSTANCE hInst = GetModuleHandle(NULL);

    const WNDCLASS wc = 
        .hInstance = hInst,
        .hIcon = LoadIcon(NULL, IDI_APPLICATION),
        .lpszClassName = TEXT("test-class"),
        .lpfnWndProc = wnd_proc,
    ;

    RegisterClass(&wc);

    const HWND hWnd = CreateWindowEx(0, TEXT("test-class"), TEXT("Test"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 1920, 1080, NULL, NULL, hInst, NULL);

    while (!close_requested) 
        MSG msg;
        while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) 
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        
    

    DestroyWindow(hWnd);
    return 0;

我不确定是什么导致我的应用程序阻止用户更改其键盘布局。我一直在使用US InternationalMicrosoft IME 键盘进行测试。如果键盘保持不变,我也无法更改语言首选项,例如 English (United States)English (United Kingdom) 具有相同的键盘布局 (US International)。

在创建窗口时是否需要处理任何 Windows 消息,或者是否需要设置任何其他标志?

【问题讨论】:

@lun GetModuleHandle 返回一个HMODULE,而不是HINSTANCE,而是they are the same thing。 WNDCLASS 没有 cbSize 字段(与 WNDCLASSEX 不同)。 @IInspectable 很公平 :) 是的,我在考虑 WNDCLASSEX。 The dangers of filtering window messages. 【参考方案1】:

我认为您使用的消息循环导致了问题。将消息循环修改为:

while (GetMessage(&msg, NULL, 0, 0))

    TranslateMessage(&msg);
    DispatchMessage(&msg);

它可以为我工作,我建议你参考Using Messages and Message Queues以澄清两个消息循环之间的区别。

编辑:

你也可以使用:

while (!close_requested) 
    MSG msg;
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    

错误原因由 IInspectable 给出:The dangers of filtering window messages

【讨论】:

正如发布的那样,这个提议的答案完全具有误导性。从PeekMessageGetMessage 的变化并没有什么不同。 我最终使用PeekMessage解决方案,感谢代码sn-p和错误来源的原因! 通过使用PeekMessage,您会不必要地消耗处理器周期(以及笔记本电脑上的电池)。只需使用while (!close_requested) MSG msg; GetMessage(&amp;msg, NULL, 0, 0); TranslateMessage(&amp;msg); DispatchMessage(&amp;msg);

以上是关于win32 窗口阻止键盘布局更改的主要内容,如果未能解决你的问题,请参考以下文章

如何在 win32API 中更改静态窗口的背景颜色? [复制]

在win32中更改无边框窗口的颜色

更改系统语言c#的最佳方法

Win10关机提示此应用程序阻止关机怎么处理

macos 更改罗技k810无线键盘的映射

更改键盘挂钩回调中的键盘布局