本文介绍了检测是否在 C# 中按下了任何键(不是 A、B,而是任何)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点解决了"通过使用奇怪的"版本.至少对于最重要的键.这对于我的情况就足够了,我想检查 ALT 和 ALT+A 是否不同(从而确保 A 没有被按下).不完美,但对于这么小的问题已经有太多时间了.无论如何,感谢所有的答案......

I kind of "solved it" by at using the "strange" version. At least for the most important keys. It is suffient for my case, where I want to check that ALT and ALT+A are not the same (thereby making sure A is not pressed). Not perfect, but already to much time for such a tiny problem. Thanks for all the answers anyway...

多亏了 280Z28 [/EDIT 4]

我知道如何检查修饰键以及如何测试单个键.问题是,我想检查是否按下了任何键.下面的方法看起来很奇怪":-)

I know how to check for modifier keys and how to test for a single key.The problem is, I want to check if any key is pressed. The following approach seems "strange" :-)

用 C# 编写的 WPF 应用程序

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

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

I know it is an enum, so I thought about a loop, but what is the "biggest number" to use. And is this possible? btw, its a very special case, normally I would use an event, but in this case I have to do it this way. Unfortunatily, the there is no "list" Keyboard.CurrentlyDownKeys. At least I didnt see it.

谢谢,克里斯

好吧,因为这似乎是一个更大的交易,这里的原因是:我已经定义了一个KeySet"它用作自定义函数的 DictionaryKey.如果有人点击了一个元素,包装器将遍历字典并检查是否有任何预定义的键集"被点击.处于活动状态.

Ok, because it seems to be a bigger deal, here the reason for this:I have defined a "KeySet" which serves as DictionaryKey for custom functions. If anybody clicks on an element, the wrapper iterates through the dictionary and checks if any of the predefined "Keysets" is active.

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

This allows me to define simple triggers, like e.g. Run this function if ALT+A+B is pressed. Another option is e.g. Run this function if ALT+STRG+A is pressed (during a mouse click on a WPF element).

唯一的问题"是对于当前的实现,如果我定义了一个不包含任何 REAL 键的 Keyset,比如按下 ALT 时运行,如果按下 ALT+A,它也会被触发.哦,在写这个的时候,我意识到还有一个问题.如果按下 ALT+A+B+C,ALT+A+B 当前也会触发.

The only "problem" with the current implementation, if I define a Keyset which does NOT contain any REAL keys, like run if ALT is pressed, it is also triggered if ALT+A is pressed. Oh, while writing this, I realize that there is another problem. ALT+A+B would currently also trigger if ALT+A+B+C is pressed.

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

Perhaps my approach is wrong, and I should create a "static key tracker" and compare the keyset to its values (aquired via events).. I will give this a try.

编辑 2这是行不通的,至少不是以简单的方式.我需要一个 FrameworkElement 来附加到 KeyDown,但我在静态构造函数中没有它.而且我对某个元素的 KeyDownEvents 不感兴趣,但是全局"......我想我只是推迟这个问题,它并不那么重要.不过,如果有人知道更好的不同方法......

EDIT 2This is not working, at least not in a simple way. I need an FrameworkElement to attach to KeyDown, but I do not have it in a static constructor. And I am not interested in KeyDownEvents of a certain element, but "globally"...I think I juts postpone this problem, its not that important. Still, if anybody knows a better of different approach...

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

So long, for anyone who cares, here some code:

public class KeyModifierSet
{
    internal readonly HashSet<Key> Keys = new HashSet<Key>();
    internal readonly HashSet<ModifierKeys> MKeys = new HashSet<ModifierKeys>();

    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);
}

这篇关于检测是否在 C# 中按下了任何键(不是 A、B,而是任何)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 06:47