C#忽略ProcessKeyPreview中的Keydowns

时间:2014-07-07 16:05:35

标签: c# events keydown

你们所做的一切。我已经覆盖了ProcessKeypreview方法,因此我可以检测到WASD'密钥被持有,然后被释放。但是,当发生碰撞时,我遇到了问题,例如当A' A' A'被按下的同时“W'已被压制。如何在按住特定键时阻止所有其他键盘操作?

这是我的代码片段:

const int WM_KEYDOWN = 0x0100;
const int WM_KEYUP = 0x0101;
protected override bool ProcessKeyPreview(ref Message m) 
{
    int msgVal = m.WParam.ToInt32();
    if (m.Msg == WM_KEYDOWN)
    {
        switch((Keys)msgVal) {
        case Keys.W:
            Console.WriteLine("W being held");
            break;

        case Keys.A:
            Console.WriteLine("A being held");
            break;
        }
    }

    if (m.Msg == WM_KEYUP) {
        switch((Keys)msgVal) {
            case Keys.W:
                Console.WriteLine("W released");
                break;

            case Keys.A:
                Console.WriteLine("A released");
                break;
        }
    }  
return base.ProcessKeyPreview(ref m);  
}

1 个答案:

答案 0 :(得分:2)

保持HashSet<Keys>当前正在按下的Keys的一组(Add}按下Remove按键,Contain在键盘上设置的键。

然后,由于您知道按下了多少个键,如果您想在特定键关闭时不再处理任何键,您可以检查您的组return true;是否为键。如果是,则const int WM_KEYDOWN = 0x0101; const int WM_KEYUP = 0x0100; HashSet<Keys> keysDown = new HashSet<Keys>(); protected override bool ProcessKeyPreview(ref Message m) { int msgVal = m.WParam.ToInt32(); if (m.Msg == WM_KEYDOWN) { keysDown.Add((Keys)msgVal); switch((Keys)msgVal) { case Keys.W: Console.WriteLine("W being held"); break; case Keys.A: Console.WriteLine("A being held"); break; } if (keysDown.Contains(keyToCheck)) return true; } if (m.Msg == WM_KEYUP) { switch((Keys)msgVal) { case Keys.W: Console.WriteLine("W released"); break; case Keys.A: Console.WriteLine("A released"); break; } keysDown.Remove((Keys)msgVal); } return base.ProcessKeyPreview(ref m); }

您的方法应如下所示:

"prevent all other keydowns while a specific key is being held down"

由于您没有指定要检查的密钥(keyToCheck),因此我将其保留为变量Set。您可以更改条件以更改何时忽略按键。

或者,如果要检查的密钥是常量,那么您不需要bool,而只需保留const int WM_KEYDOWN = 0x0101; const int WM_KEYUP = 0x0100; bool keyToCheckDown = false; protected override bool ProcessKeyPreview(ref Message m) { int msgVal = m.WParam.ToInt32(); if (m.Msg == WM_KEYDOWN) { if ((Keys)msgVal == KEY_TO_CHECK) keyToCheckDown = true; switch((Keys)msgVal) { case Keys.W: Console.WriteLine("W being held"); break; case Keys.A: Console.WriteLine("A being held"); break; } // the second condition is necessary so that you don't "return true" the when the key to check is pressed. if (keyToCheckDown && (Keys)msgVal != KEY_TO_CHECK) return true; } if (m.Msg == WM_KEYUP) { switch((Keys)msgVal) { case Keys.W: Console.WriteLine("W released"); break; case Keys.A: Console.WriteLine("A released"); break; } if ((Keys)msgVal == KEY_TO_CHECK) keyToCheckDown = false; } return base.ProcessKeyPreview(ref m); } 该密钥是否已关闭:

KEY_TO_CHECK

此常量为{{1}}。

我希望这有帮助!