Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取所有按下的键_C#_Keypress_Keydown - Fatal编程技术网

C# 获取所有按下的键

C# 获取所有按下的键,c#,keypress,keydown,C#,Keypress,Keydown,我必须使用什么才能获得当前在键盘上按下的“所有键”?因为Form.KeyPress+=neweventhandler()在充满控件时根本没有什么作用。不管我做什么,它都不会叫它,无论是键下键、键上键还是其他什么。。。是的,我知道如何使用它们 因此,如果系统中有任何功能可以检查按下的键,返回所使用的键的数组或其他东西,我将非常感激被指向正确的方向。我相信您正在寻找在窗体有焦点时按下键将触发的事件,即使该窗体中的另一个子控件当前具有焦点。听起来您想查询键盘中所有键的状态。最好的函数是Win32 AP

我必须使用什么才能获得当前在键盘上按下的“所有键”?因为
Form.KeyPress+=neweventhandler()
在充满控件时根本没有什么作用。不管我做什么,它都不会叫它,无论是键下键、键上键还是其他什么。。。是的,我知道如何使用它们


因此,如果系统中有任何功能可以检查按下的键,返回所使用的键的数组或其他东西,我将非常感激被指向正确的方向。

我相信您正在寻找在窗体有焦点时按下键将触发的事件,即使该窗体中的另一个子控件当前具有焦点。

听起来您想查询键盘中所有键的状态。最好的函数是Win32 API调用
GetKeyboardState

我不相信有一个好的管理相当于该功能。它的PInvoke代码相当简单

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

var array = new byte[256];
GetKeyboardState(array);
这将使用系统中每个虚拟密钥的向上/向下状态填充
字节[]
。如果设置了高位,则当前按下虚拟键。将
映射到虚拟键代码只需考虑数值
值的
字节
部分即可

public static byte GetVirtualKeyCode(Key key) {
  int value = (int)key;
  return (byte)(value & 0xFF);
}
上述方法适用于大多数
值,但需要小心使用修改器键。值
Keys.Alt
Keys.Control
Keys.Shift
在这里不起作用,因为它们在技术上是修饰符,而不是键值。要使用修饰符,您需要使用实际关联的键值
键.ControlKey
键.lshift键
,等等。。。(真的是以Key结尾的任何东西)

因此,检查是否设置了一个特定的键可以按如下方式进行

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

如果只需要在应用程序处于活动状态时知道所有击键,而不管应用程序中的哪个控件具有焦点,则可以使用窗体的属性

只需将属性设置为true并订阅表单上所需的键事件。现在,如果将
cancel
属性设置为true,您将收到应用程序中的所有击键,然后再将其转发到具体控件,从而允许您自己对其作出反应,并取消将其转发到控件


如果您需要在应用程序不是活动的情况下接收按键,则需要某种低级键盘挂钩。我没有测试它,但在这个案例中看起来很有希望。

我对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);
使用System.Collections.Generic;
使用System.Linq;
使用System.Runtime.InteropServices;
使用System.Windows.Input;
私有静态只读字节[]DistinctVirtualKeys=可枚举
.范围(0,256)
.Select(KeyInterop.KeyFromVirtualKey)
.Where(item=>item!=Key.None)
.Distinct()
.Select(项=>(字节)KeyInterop.VirtualKeyFromKey(项))
.ToArray();
/// 
///获取当前处于关闭状态的所有键。
/// 
/// 
///当前处于关闭状态的所有键的集合。
/// 
公共IEnumerable GetDownKeys()
{
var keyboardState=新字节[256];
GetKeyboardState(keyboardState);
var downKeys=新列表();
对于(var index=0;index
您是希望在运行特定代码时按下所有键,还是希望在按下某个键时发生事件?例如,我希望鼠标滚轮有一个eventhandler,但我希望在eventhandler中执行某些操作时按下“Ctrl”键。因此,如果我滚动滚轮,我只会得到鼠标滚轮的结果,而不是按键。它也适用于修改键,但是你必须使用键。AltKey,ShiftKey和ControlKey。是的。。。但是一个以前没有使用过这些东西的人,最好包括我需要的名称空间,为什么DllImport显示红色,为什么GetKeyboardState不在任何地方,等等。。。半生不熟的答案意味着我必须搜索更多的答案,因为答案等于没有答案。@Deukalion
DllImport
是一种非常常见的类型,我觉得不需要包含名称空间espc,因为如果您在“自动更正”下拉列表中选择名称空间,IDE只会为您包含它。另外,
GetKeyboardState
不是.Net函数。这是我导入的本地版本,如果你粘贴到我的定义中,它应该可以正常工作。我在VB.Net中翻译
DistinctVirtualKeys
赋值时遇到了困难。您能对其进行更好的注释吗?我还得到一个错误,即没有
的参数。请选择(KeyInterop.KeyFromVirtualKey)
?添加对WindowsBase的引用。在那里可以找到
enum System.Windows.Input.Key