【问题标题】:How can I create a global hotkey combination that includes the windows key?如何创建包含 windows 键的全局热键组合?
【发布时间】:2013-10-21 19:37:21
【问题描述】:

我正在使用 SetWindowsHookEx 捕获键盘以显示正在运行的应用程序。我可以使用 CTRL、ALT、SHIFT 和常规键创建组合。但是我无法使用 WINDOWS 键创建组合(例如,CTRL + WINDOWS + A)。

我看过有关单独捕获 WINDOWS 键的文章(例如在游戏运行时防止 Windows 8 启动屏幕),但从未创建组合。

我知道可以通过 AutoHotKey 等软件捕获这些组合。

SetWindowsHookEx 是否是错误的方法?

【问题讨论】:

    标签: hotkeys keyboard-hook windows-key


    【解决方案1】:

    我找到了一个similar question,其中包含一个有帮助的答案。 这使我找到了正确的解决方案。

    看来 Keyboard.Modifiers 无法检测到 Windows 键(至少在我的 Win8 实例上)。

    相反,我不得不使用 Keyboard.IsKeyDown 以不同的方式处理 Windows 键。这导致构建了一个方法来检查按下的键(来自我的 LowLevelKeyboardProc)和当前按下的修饰键的组合是否与属性 HotKeyHotKeyModifiers 中定义的键和修饰键相同。

    这是 LowLevelKeyboardProc 的 C#:

    /// <summary>
    /// Called by windows when a keypress occurs.
    /// </summary>
    /// <param name="nCode">A code the hook procedure uses to determine how to process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.</param>
    /// <param name="wParam">The identifier of the keyboard message. This parameter can be one of the following messages: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP. </param>
    /// <param name="lParam">A pointer to a KBDLLHOOKSTRUCT structure. </param>
    private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN))
        {
            int vkCode = Marshal.ReadInt32(lParam);
            var keyPressed = KeyInterop.KeyFromVirtualKey(vkCode);
    
            if (IsKeyCombinationPressed(keyPressed))
                OnKeyCombinationPressed(new EventArgs());
        }
    
        return CallNextHookEx(_hookId, nCode, wParam, lParam);
    }
    

    还有用于 IsKeyCombinationPressed() 方法的 C#:

    /// <summary>
    /// Returns true if the registered key combination is pressed
    /// </summary>
    /// <remarks>
    /// Keyboard.Modifiers doesn't pick up the windows key (at least on Windows 8) so we use Keyboard.IsKeyDown to detect it (if required).
    /// </remarks>
    bool IsKeyCombinationPressed(Key keyPressed)
    {
        if (keyPressed != HotKey) return false;
    
        //Handle windows key
        bool isWindowsKeyRequired = (HotKeyModifiers & ModifierKeys.Windows) != 0;
        bool isWindowsKeyPressed = Keyboard.IsKeyDown(Key.LWin) || Keyboard.IsKeyDown(Key.RWin);
    
        //Remove windows key from modifiers (if required)
        ModifierKeys myModifierKeys = isWindowsKeyRequired ? HotKeyModifiers ^ ModifierKeys.Windows : HotKeyModifiers;
        bool isModifierKeysPressed = Keyboard.Modifiers == myModifierKeys;
    
        return isWindowsKeyRequired
            ? isWindowsKeyPressed && isModifierKeysPressed
            : isModifierKeysPressed;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-12
      • 1970-01-01
      • 2013-05-12
      • 2011-02-16
      • 1970-01-01
      • 2016-02-22
      • 2011-03-15
      • 1970-01-01
      • 2011-02-21
      相关资源
      最近更新 更多