首页 > 解决方案 > 带有 RIDEV_NOHOTKEYS 的原始输入键盘显示经典的 Alt+Tab 菜单

问题描述

我正在尝试为使用 RawInput 处理键盘事件的窗口禁用 Windows 键。执行此操作的常用方法是安装低级键盘挂钩并在那里过滤掉 Windows 键事件。为了让它与 RawInput 一起工作,我必须用 RIDEV_NOHOTKEYS 初始化键盘设备。但是,当我这样做时,如果我从应用程序中使用 Alt+Tab,出于某种原因,Windows 10 会显示经典的 Alt+Tab 内容:

alt 选项卡菜单

我没有在低级键盘挂钩中过滤掉 Alt 或 Tab 事件,如果我根本不安装低级键盘挂钩,也会发生这种情况,只需使用 RIDEV_NOHOTKEYS 初始化键盘设备即可。我尝试为 WM_INPUT 消息返回 0,并尝试调用默认窗口 proc,似乎没有任何帮助...以前有人遇到过这个问题吗?

标签: winapiraw-input

解决方案


添加一个低级挂钩(WH_KEYBOARD_LL)可以防止 Alt 键消息传递到其他窗口。参考“ LowLevelKeyboardProc 回调函数”。

WH_KEYBOARD_LL 挂钩只能在全局范围内设置。

// Register hook
hinstDLL = LoadLibrary(TEXT("sysmsg.dll"));
hkprcSysMsg = (SYSMESSAGEPROC)GetProcAddress(hinstDLL, "SysMessageProc");

HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)hkprcSysMsg, hinstDLL, 0);

DLL中的挂钩回调函数:

__declspec(dllexport)
LRESULT __cdecl SysMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{

    if (nCode < 0)  // do not process message 
        return CallNextHookEx(NULL, nCode,
            wParam, lParam);

    if (wParam == WM_SYSKEYDOWN)
    {
        if(((tagKBDLLHOOKSTRUCT*)lParam)->vkCode == VK_LMENU || ((tagKBDLLHOOKSTRUCT*)lParam)->vkCode == VK_RMENU)
        return 1;
    }


    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

更多参考:“使用 Hooks ”“键盘输入”“ WM_SYSKEYDOWN 消息”“ KBDLLHOOKSTRUCT 结构”“虚拟键代码

笔记

挂钩往往会减慢系统速度,因为它们会增加系统必须为每条消息执行的处理量。您应该仅在必要时安装挂钩,并尽快将其移除。

您应该仅将全局挂钩用于调试目的;否则,您应该避免使用它们。全局挂钩会损害系统性能并导致与实现相同类型全局挂钩的其他应用程序发生冲突。


推荐阅读