如何使用低级键盘钩来挂钩Win + Tab

时间:2014-11-28 02:35:17

标签: c# windows keyboard-shortcuts keyboard-hook setwindowshookex

简而言之:在 Win + Tab 后阻止 Win 使Windows认为 Win 仍然是,然后用 Win 键按 S 例如将打开搜索魅力,而不是只输入" s" ...直到用户按下再次赢了阻止它意味着Windows开始菜单将显示。我是一个难题!


使用 Alt + Tab 使用LowLevelKeyboardHook Win + 一些Ubounded我可以顺利使用快捷方式密钥使用RegisterHotKey。问题仅在使用LowLevelKeyboardHook Win 键时发生。

在下面的示例中,当检测到 Win + Tab 组合时,我接管 Win up事件。这导致使后面的每次击键都表现得好像 Win 键仍在关闭。

        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode != HC_ACTION)
                return CallNextHookEx(_hookID, nCode, wParam, lParam);

            var keyInfo = (Kbdllhookstruct)Marshal.PtrToStructure(lParam, typeof(Kbdllhookstruct));

            if (keyInfo.VkCode == VK_LWIN)
            {
                if (wParam == (IntPtr)WM_KEYDOWN) {
                    _isWinDown = true;
                } else {
                    _isWinDown = false;

                    if (_isWinTabDetected) {
                        _isWinTabDetected = false;
                        return (IntPtr)1;
                    }
                }
            }
            else if (keyInfo.VkCode == VK_TAB && _isWinDown) {
                _isWinTabDetected = true;

                if (wParam == (IntPtr)WM_KEYDOWN) {
                    return (IntPtr)1;
                } else {
                    _isWinTabDetected = true;
                    Console.WriteLine("WIN + TAB Pressed");
                    return (IntPtr)1;
                }
            }

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

您可以在此处找到完整的代码(请注意,它应该替换您运行的空WinForms项目中的Program.cs):https://gist.github.com/christianrondeau/bdd03a3dc32a7a718d62 - 按 Win + 每次按下快捷方式时,选项卡Form标题都会更新。

  
    

请注意,挂钩到此特定组合的 intent 是提供 Alt + Tab 备选方案而不替换 Alt + Tab 本身。还可以接受使用 Win + Tab 启动自定义代码的能力的答案。

  

以下是我的想法,我找不到文档。所有人都可能成功回答我的问题。

  • 告诉Windows"取消" 而没有实际触发它
  • 阻止Windows启动“开始”菜单
  • 直接在Windows中关注' 赢取 +事件,而不是手动挂钩击键(如果存在,这将是到目前为止我的第一选择)

2 个答案:

答案 0 :(得分:4)

系统需要知道您释放Windows密钥。 我检查了我自己的钩子谁没有这个问题和你和我之间的唯一差异是这一行:

if (_isWinTabDetected) {
    _isWinTabDetected = false;
     return (IntPtr)1; //THIS LINE 
}

答案 1 :(得分:2)

这似乎完全符合你的要求(如果你愿意,可以省略RWin)。

当您的应用失去焦点时,请注意并取消注册此KB挂钩!

    [DllImport("user32.dll")]
    static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey);

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode == HC_ACTION)
        {
            var keyInfo = (Kbdllhookstruct) Marshal.PtrToStructure(lParam, typeof (Kbdllhookstruct));
            if ((int) wParam == WM_KEYDOWN
                && keyInfo.VkCode == VK_TAB
                && (GetAsyncKeyState(Keys.LWin) < 0 || GetAsyncKeyState(Keys.RWin) < 0))
            {
                _mainForm.Text = "Win + Tab was pressed " + (++_winTabPressCounter) + " times";
                return (IntPtr) 1;
            }
        }

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

在发现这种技术之前我尝试了几件事。 这篇文章是最有帮助的https://stackoverflow.com/a/317550/55721

相关问题