获取所有按下的键

Deu*_*ion 5 c# keypress keydown

我必须使用什么来获得此刻在键盘上按下的"所有键"?因为Form.KeyPress += new EventHandler()当它充满控制时根本没有做太多.无论我做什么,它都不会调用它,KeyDown,KeyUp或其他任何东西......是的,我知道如何使用它们.

因此,如果系统中有任何函数可以检查按下的键,那么它将返回所使用的键的数组或者其他内容 - 我将非常感谢指向正确的方向.

Jar*_*Par 13

听起来你想要查询键盘中所有键的状态.最好的功能是Win32 API调用GetKeyboardState

我不相信有一个很好的管理等效的功能.它的PInvoke代码非常简单

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetKeyboardState(byte [] lpKeyState);

var array = new byte[256];
GetKeyboardState(array);
Run Code Online (Sandbox Code Playgroud)

这将填充byte[]系统中每个虚拟键的up/down状态.如果设置了高位,则当前按下虚拟键.Key仅通过考虑byte数值的一部分来完成将a 映射到虚拟键码Key.

public static byte GetVirtualKeyCode(Key key) {
  int value = (int)key;
  return (byte)(value & 0xFF);
}
Run Code Online (Sandbox Code Playgroud)

以上适用于大多数Key值,但您需要注意修饰键.值Keys.Alt,Keys.ControlKeys.Shift不会在这里,因为他们在技术上改性剂和未键值工作.要使用修改器,你需要使用实际的相关键值Keys.ControlKey,Keys.LShiftKey等...(真的没有什么东西,与主要结束)

因此,检查是否设置了特定键可以如下进行

var code = GetVirtualKeyCode(Key.A);
if ((array[code] & 0x80) != 0) {
  // It's pressed
} else { 
  // It's not pressed
}
Run Code Online (Sandbox Code Playgroud)

  • @Deukalion`DllImport`是一种常见的类型,我觉得不需要包含命名空间espc,因为如果你在自动更正下拉列表中选择命名空间,IDE将只包含它."GetKeyboardState"也不是.Net函数.它是我导入的本机,如果你粘贴我的定义它应该工作正常. (4认同)

bri*_*ler 6

我对 JaredPar 的回答进行了一些扩展。以下方法返回当前按下的所有键的集合:

using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Input;

private static readonly byte[] DistinctVirtualKeys = Enumerable
    .Range(0, 256)
    .Select(KeyInterop.KeyFromVirtualKey)
    .Where(item => item != Key.None)
    .Distinct()
    .Select(item => (byte)KeyInterop.VirtualKeyFromKey(item))
    .ToArray();

/// <summary>
/// Gets all keys that are currently in the down state.
/// </summary>
/// <returns>
/// A collection of all keys that are currently in the down state.
/// </returns>
public IEnumerable<Key> GetDownKeys()
{
    var keyboardState = new byte[256];
    GetKeyboardState(keyboardState);

    var downKeys = new List<Key>();
    for (var index = 0; index < DistinctVirtualKeys.Length; index++)
    {
        var virtualKey = DistinctVirtualKeys[index];
        if ((keyboardState[virtualKey] & 0x80) != 0)
        {
            downKeys.Add(KeyInterop.KeyFromVirtualKey(virtualKey));
        }
    }

    return downKeys;
}

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetKeyboardState(byte[] keyState);
Run Code Online (Sandbox Code Playgroud)