C# MouseKeyHook:某些键 + 修饰符组合不起作用

Posted

技术标签:

【中文标题】C# MouseKeyHook:某些键 + 修饰符组合不起作用【英文标题】:C# MouseKeyHook: Certain Key + Modifier Combinations Not Working 【发布时间】:2018-11-21 21:15:36 【问题描述】:

我一直在使用 MouseKeyHook NuGet 包,它非常适合捕获大多数输入。但是我在捕捉某些键 + 修饰符的组合时遇到了一些问题。

public static class InputHandler

    private static IKeyboardMouseEvents _GlobalHook;
    public static IKeyboardMouseEvents GlobalHook => _GlobalHook;

    public static void Subscribe()
    
        _GlobalHook = Hook.AppEvents();
        _GlobalHook.KeyDown += KeyDown;
    

    private static void KeyDown(object sender, KeyEventArgs e)
    
        Console.WriteLine("Output: " + e.Modifiers + " + " + e.KeyCode);
    

让我们试着敲几个键,看看输出是什么:

Key: A
> Output: None + A

Key: Shift & A
> Output: Shift + A

Key: Shift & Control & Alt & A
> Output: Shift, Control, Alt + A

太棒了!正是你所期望的。那么键盘顶部的数字栏呢?

Key: 1
> Output: None + D1

Key: Shift & Control & Alt & 3
> Output: Shift, Control, Alt + D3

好的,再说一遍,这正是您所期望的。没问题... 0 键呢?

Key: 0
> Output: None + D0

Key: Shift & 0
> Output: Shift + D0

Key: Shift & Control & 0
> Output: Shift, Control + ShiftKey    <---- What????

Key: Shift & Control & Alt & 0
> Output: Shift, Control, Alt + D0

那么这里发生了什么?为什么当 exactly D0 + Control + Shift 被按下时事件没有正确触发?另外值得注意的是,这是一个 KeyDown 事件,因此只要您按住键,输出就会重复,但是当打印“ShiftKey”输出时,它永远不会重复,这很奇怪。

最坏的情况,我总是可以切换我的绑定,但我注意到许多不同的键 + 修饰符组合(主要是 oem 键、数字键盘和数字键)的这种奇怪之处,所以很高兴知道为什么发生这种情况。

【问题讨论】:

按下 Shift 键时会收到通知,这很正常。您不能假设每种组合都可用。还有其他应用程序使用 RegisterHotKey() 来侦听击键,通常使用 Ctrl+Shift。这些钥匙在你看到它们之前就被劫持了。 Intel shovelware 尤其臭名昭著。 【参考方案1】:

我能想到两种可能:

它可能是操作系统的键盘快捷键。

https://support.microsoft.com/en-au/help/967893/input-method-editor-keyboard-shortcut-ctrl-shift-0-switches-the-input

许多键盘在物理上无法正确检测每种可能的键组合。具体细节取决于键盘电路板的布局方式。 Shift-A 或 Ctrl-X 将始终有效,同时按住每个键仅适用于***的键盘,中间有一个灰色区域。

https://en.wikipedia.org/wiki/Rollover_(key)#Key_jamming_and_ghosting

【讨论】:

以上是关于C# MouseKeyHook:某些键 + 修饰符组合不起作用的主要内容,如果未能解决你的问题,请参考以下文章

C# const和readonly修饰符的区别

关于publicprivateprotectedinternal

通过 mousekeyhook C# 检测按键的绝对最小代码

c#类的修饰符都有哪些?

C#中类。方法。字段 的默认访问修饰符分别是啥?

在Java和c#中如果不写访问修饰符,类和类成员默认的是啥访问修饰符?