检测是否在C#中按下任何键(不是A,B,但是任何键)

[编辑3]我使用“奇怪”版本“解决了它”。 至少对于最重要的键。 这对我的情况来说是足够的,我想检查ALT和ALT + A是不一样的(从而确保没有按下A)。 不完美,但已经有很多时间来解决这个小问题了。 无论如何,感谢所有答案…… [编辑3]

[编辑4]由于280Z28 [/ EDIT 4]解决了它更清洁

我知道如何检查修改键以及如何测试单个键。 问题是,我想检查是否按下任何键。 以下方法似乎“奇怪”:-)

用C#编写的WPF应用程序

if (Keyboard.IsKeyDown(Key.A)) return true; if (Keyboard.IsKeyDown(Key.B)) return true; if (Keyboard.IsKeyDown(Key.C)) return true; 

我知道这是一个枚举,所以我想到了一个循环,但是使用的“最大数字”是什么。 这可能吗? 顺便说一句,这是一个非常特殊的情况,通常我会使用一个事件,但在这种情况下我必须这样做。 不幸的是,没有“列表”Keyboard.CurrentlyDownKeys。 至少我没有看到它。

谢谢,克里斯

编辑:好的,因为它似乎是一个更大的交易,这里的原因是:我已经定义了一个“KeySet”,它作为自定义函数的DictionaryKey。 如果有人点击某个元素,则包装器会遍历字典并检查是否有任何预定义的“Keysets”处于活动状态。

这允许我定义简单的触发器,例如,如果按下ALT + A + B,则运行此function。 另一个选项是例如,如果按下ALT + STRG + A,则运行此function(在鼠标单击WPF元素期间)。

当前实现的唯一“问题”,如果我定义一个不包含任何REAL键的Keyset,如按下ALT则运行,如果按下ALT + A,也会触发它。 哦,在写这篇文章时,我意识到还有另一个问题。 如果按下ALT + A + B + C,ALT + A + B当前也会触发。

也许我的方法是错误的,我应该创建一个“静态键跟踪器”并将键集与其值进行比较(通过事件获取)。我将尝试一下。

编辑2这不起作用,至少不是一个简单的方法。 我需要一个FrameworkElement来附加到KeyDown,但我没有在静态构造函数中。 我对某个元素的KeyDownEvents不感兴趣,但是“全局”…我认为我推迟了这个问题,它并不那么重要。 不过,如果有人知道更好的不同方法……

很长一段时间,对于任何关心的人,这里有一些代码:

  public class KeyModifierSet { internal readonly HashSet Keys = new HashSet(); internal readonly HashSet MKeys = new HashSet(); public override int GetHashCode() { int hash = Keys.Count + MKeys.Count; foreach (var t in Keys) { hash *= 17; hash = hash + t.GetHashCode(); } foreach (var t in MKeys) { hash *= 19; hash = hash + t.GetHashCode(); } return hash; } public override bool Equals(object obj) { return Equals(obj as KeyModifierSet); } public bool Equals(KeyModifierSet other) { // Check for null if (ReferenceEquals(other, null)) return false; // Check for same reference if (ReferenceEquals(this, other)) return true; // Check for same Id and same Values return Keys.SetEquals(other.Keys) && MKeys.SetEquals(other.MKeys); } public bool IsActive() { foreach (var k in Keys) if (Keyboard.IsKeyUp(k)) return false; if ((Keys.Count == 0) && !Keyboard.IsKeyDown(Key.None)) return false; foreach (var k in MKeys) if ((Keyboard.Modifiers & k) == 0) return false; if ((MKeys.Count == 0) && Keyboard.Modifiers > 0) return false; return true; } public KeyModifierSet(ModifierKeys mKey) { MKeys.Add(mKey); } public KeyModifierSet() { } public KeyModifierSet(Key key) { Keys.Add(key); } public KeyModifierSet(Key key, ModifierKeys mKey) { Keys.Add(key); MKeys.Add(mKey); } public KeyModifierSet Add(Key key) { Keys.Add(key); return this; } public KeyModifierSet Add(ModifierKeys key) { MKeys.Add(key); return this; } } 

 [DllImport("user32.dll", EntryPoint = "GetKeyboardState", SetLastError = true)] private static extern bool NativeGetKeyboardState([Out] byte[] keyStates); private static bool GetKeyboardState(byte[] keyStates) { if (keyStates == null) throw new ArgumentNullException("keyState"); if (keyStates.Length != 256) throw new ArgumentException("The buffer must be 256 bytes long.", "keyState"); return NativeGetKeyboardState(keyStates); } private static byte[] GetKeyboardState() { byte[] keyStates = new byte[256]; if (!GetKeyboardState(keyStates)) throw new Win32Exception(Marshal.GetLastWin32Error()); return keyStates; } private static bool AnyKeyPressed() { byte[] keyState = GetKeyboardState(); // skip the mouse buttons return keyState.Skip(8).Any(state => (state & 0x80) != 0); } 

使用XNA框架,您可以使用后续检查是否已按下任何键。

 Keyboard.GetState().GetPressedKeys().Length > 0 

相当古老的问题但是如果有人遇到这个并且不想使用外部dll,你可以枚举可能的键并循环它们。

  bool IsAnyKeyPressed() { var allPossibleKeys = Enum.GetValues(typeof(Key)); bool results = false; foreach (var currentKey in allPossibleKeys) { Key key = (Key)currentKey; if (key != Key.None) if (Keyboard.IsKeyDown((Key)currentKey)) { results = true; break; } } return results; } 

您可以通过在函数外部执行枚举并稍后保留列表来对此进行优化。

这段代码从哪里运行? 它在事件处理程序中吗? 许多表单和控件将触发KeyPress事件以及KeyDown事件。 您可能希望查看这些事件,并在其中一个事件发生时将其设置为true。 您还必须听取相应的事件,告诉您何时释放密钥(KeyUp,我认为)。

如果您使用的是Windows.Forms ,请使用KeyDown事件并使用相应的KeyEventArgs读取特定密钥。 您可以访问KeyEventArgs变量上的KeyCode属性。

要检查范围,请在A和Z之间进行检查:

 if (e.KeyCode>=Keys.A && e.KeyCode<=Keys.Z) { // do stuff...or not } 

http://sourceforge.net/projects/keystate/显示“特殊”键。 否则我认为你只需要监控它们。 想要在全系统范围内做这样的事情吗? 你想达到什么目的?

您可以为每个keydown事件递增计数器,并为每个keyup事件递减计数器。 当计数器为零时,没有键被关闭。

 normally I would use an event 

你应该仍然使用一个事件,最好是KeyDown,因为你不介意按下什么键,如果你在windows上编程。 如果没有,你可以使用Console.ReadLine();

编辑:如果你正在寻找类似的东西

 if (Keyboard.IsKeyDown(Key.AnyKey)) return true; 

那你一定是在开玩笑……

编辑2:嗯,你的记录器的方法很有趣,但我认为你正在重新发明轮子。 当可以知道时,所有编程语言都提供了一些处理按键的方法。 在C#for Windows中,这是使用事件完成的。 此外,我认为你无法在.NET中自己处理这类事情,因为你需要从Win32 API访问一些系统函数,而AFAIK则不允许这样做(至少很容易。 ..)在托管代码中。 一些解决方案是创建HOOK并从那里向您的应用程序发送消息,但我不知道如何在C#中执行此操作。 这是delphi的方式,我有更多的经验。