C# 如何检测当前按下的键?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1100285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 08:14:36  来源:igfitidea点击:

How to detect the currently pressed key?

c#.netwinformskeyboard

提问by

In Windows Forms, you can know, at any time, the current position of the cursor thanks to the Cursorsclass.

Windows Forms 中,由于Cursors类,您可以随时知道光标的当前位置。

The same thing doesn't seem to be available for the keyboard. Is it possible to know if, for example, the Shiftkey is pressed?

同样的东西似乎不适用于键盘。例如,是否可以知道是否Shift按下了键?

Is it absolutely necessary to track down every keyboard notification (KeyDown and KeyUp events)?

是否绝对有必要追踪每个键盘通知(KeyDown 和 KeyUp 事件)?

采纳答案by SLaks

if ((Control.ModifierKeys & Keys.Shift) != 0) 

This will also be true if Ctrl+Shiftis down. If you want to check whether Shift alone is pressed,

如果Ctrl+Shift关闭,这也是正确的。如果要检查是否单独按下 Shift,

if (Control.ModifierKeys == Keys.Shift)

If you're in a class that inherits Control(such as a form), you can remove the Control.

如果您在继承的类Control(例如表单)中,则可以删除Control.

回答by Will Eddins

In WinForms:

在 WinForms 中:

if( Form.ModifierKeys == Keys.Shift )

It sounds like a duplicate of Stack Overflow question Detect Shift key is pressed without using events in Windows Forms?.

这听起来像是堆栈溢出问题的重复Detect Shift 键被按下而不使用 Windows 窗体中的事件?.

回答by Jason Williams

You can P/Invokedown to the Win32 GetAsyncKeyStateto test any key on the keyboard.

您可以P/Invoke到 Win32 GetAsyncKeyState来测试键盘上的任何键。

You can pass in values from the Keys enum (e.g. Keys.Shift) to this function, so it only requires a couple of lines of code to add it.

您可以将 Keys 枚举(例如 Keys.Shift)中的值传递给此函数,因此只需几行代码即可添加它。

回答by Jeff Wain

You can also look at the following if you reference System.Windows.Input

如果您参考 System.Windows.Input,您还可以查看以下内容

if (Keyboard.Modifiers == ModifierKeys.Shift)

The Keyboard namespace can also be used to check the pressed state of other keys with Keyboard.IsKeyDown(Key), or if you are subscribing to a KeyDownEvent or similar event, the event arguments carry a list of currently pressed keys.

Keyboard 命名空间还可用于通过 Keyboard.IsKeyDown(Key) 检查其他键的按下状态,或者如果您订阅 KeyDownEvent 或类似事件,则事件参数携带当前按下的键的列表。

回答by Rob Elliott

if (Control.ModifierKeys == Keys.Shift)
    //Shift is pressed

The cursor x/y position is a property, and a keypress (like a mouse click/mousemove) is an event. Best practice is usually to let the interface be event driven. About the only time you would need the above is if you're trying to do a shift + mouseclick thing.

光标 x/y 位置是一个属性,按键(如鼠标单击/鼠标移动)是一个事件。最佳实践通常是让界面由事件驱动。关于您需要上述内容的唯一时间是,如果您正在尝试执行 shift + mouseclick 操作。

回答by Ash

The code below is how to detect almost all currently pressed keys, not just the Shiftkey.

下面的代码是如何检测几乎所有当前按下的键,而不仅仅是Shift键。

private KeyMessageFilter m_filter = new KeyMessageFilter();

private void Form1_Load(object sender, EventArgs e)
{
    Application.AddMessageFilter(m_filter);
}


public class KeyMessageFilter : IMessageFilter
{
    private const int WM_KEYDOWN = 0x0100;
    private const int WM_KEYUP = 0x0101;
    private bool m_keyPressed = false;

    private Dictionary<Keys, bool> m_keyTable = new Dictionary<Keys, bool>();

    public Dictionary<Keys, bool> KeyTable
    {
        get { return m_keyTable; }
        private set { m_keyTable = value; }
    }

    public bool IsKeyPressed()
    {
        return m_keyPressed;
    }

    public bool IsKeyPressed(Keys k)
    {
        bool pressed = false;

        if (KeyTable.TryGetValue(k, out pressed))
        {
            return pressed;
        }

        return false;
    }

    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_KEYDOWN)
        {
            KeyTable[(Keys)m.WParam] = true;

            m_keyPressed = true;
        }

        if (m.Msg == WM_KEYUP)
        {
            KeyTable[(Keys)m.WParam] = false;

            m_keyPressed = false;
        }

        return false;
    }
}

回答by g.g

if (Form.ModifierKeys == Keys.Shift)

does work for a text box if the above code is in the form's keydown event and no other control captures the keydown event for the key down.

如果上面的代码在表单的 keydown 事件中并且没有其他控件捕获 keydown 的 keydown 事件,则它确实适用于文本框。

Also one may wish stop further key processing with:

也可能希望停止进一步的密钥处理:

e.Handled = true;

回答by Mahdi

if ((ModifierKeys == Keys.Control) && ((e.KeyChar & (char)Keys.F) != 0))
{
     // CTRL+F pressed !
}

回答by Hardryv

The best way I have found to manage keyboard input on a Windows Forms form is to process it after the keystroke and before the focused control receives the event. Microsoft maintains a built-in Form-level property named .KeyPreviewto facilitate this precise thing:

我发现在 Windows 窗体窗体上管理键盘输入的最佳方法是在击键之后和焦点控件接收事件之前处理它。Microsoft 维护了一个Form名为.KeyPreview的内置级别属性来促进这一精确的事情:

public frmForm()
{
    // ...
    frmForm.KeyPreview = true;
    // ...
}

Then the form's _KeyDown, _KeyPress, and / or _KeyUp events can be marshaled to access input events before the focused form control ever sees them, and you can apply handler logic to capture the event there or allow it to pass through to the focused form control.

然后表单的 _KeyDown、_KeyPress 和/或 _KeyUp 事件可以在焦点表单控件看到它们之前被编组以访问输入事件,并且您可以应用处理程序逻辑来捕获那里的事件或允许它传递到焦点表单控件.

Although not as structurally graceful as XAML'sevent-routing architecture, it makes management of form-level functions in Winforms far simpler. See the MSDN notes on KeyPreviewfor caveats.

尽管在结构上不如XAML 的事件路由体系结构优雅,但它使 Winforms 中表单级功能的管理变得更加简单。有关注意事项,请参阅有关 KeyPreviewMSDN 说明

回答by parsley72

Most of these answers are either far too complicated or don't seem to work for me (e.g. System.Windows.Input doesn't seem to exist). Then I found some sample code which works fine: http://www.switchonthecode.com/tutorials/winforms-accessing-mouse-and-keyboard-state

大多数这些答案要么太复杂,要么似乎对我不起作用(例如 System.Windows.Input 似乎不存在)。然后我找到了一些工作正常的示例代码:http: //www.switchonthecode.com/tutorials/winforms-accessing-mouse-and-keyboard-state

In case the page disappears in the future I am posting the relevant source code below:

如果页面将来消失,我将在下面发布相关的源代码:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MouseKeyboardStateTest
{
  public abstract class Keyboard
  {
    [Flags]
    private enum KeyStates
    {
      None = 0,
      Down = 1,
      Toggled = 2
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    private static extern short GetKeyState(int keyCode);

    private static KeyStates GetKeyState(Keys key)
    {
      KeyStates state = KeyStates.None;

      short retVal = GetKeyState((int)key);

      //If the high-order bit is 1, the key is down
      //otherwise, it is up.
      if ((retVal & 0x8000) == 0x8000)
        state |= KeyStates.Down;

      //If the low-order bit is 1, the key is toggled.
      if ((retVal & 1) == 1)
        state |= KeyStates.Toggled;

      return state;
    }

    public static bool IsKeyDown(Keys key)
    { 
      return KeyStates.Down == (GetKeyState(key) & KeyStates.Down);
    }

    public static bool IsKeyToggled(Keys key)
    { 
      return KeyStates.Toggled == (GetKeyState(key) & KeyStates.Toggled);
    }
  }
}