How to detect the currently pressed key?

2018-12-31 20:35发布

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

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

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

11条回答
千与千寻千般痛.
2楼-- · 2018-12-31 20:38
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.

Also one may wish stop further key processing with:

e.Handled = true;
查看更多
千与千寻千般痛.
3楼-- · 2018-12-31 20:38

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 .KeyPreview to facilitate this precise thing:

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.

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

查看更多
人间绝色
4楼-- · 2018-12-31 20:38

In 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?.

查看更多
旧时光的记忆
5楼-- · 2018-12-31 20:39

Since .NET Framework version 3.0, it is possible to use the Keyboard.IsKeyDown method from the new System.Windows.Input namespace. For instance:

if (((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) && Keyboard.IsKeyDown(Key.F))
{
    // CTRL + F is currently pressed
}

Even though it's part of WPF, that method works fine for WinForm applications (provided that you add references to PresentationCore.dll and WindowsBase.dll). Unfortunately, however, the 3.0 and 3.5 versions of the Keyboard.IsKeyDown method did not work for WinForm applications. Therefore, if you do want to use it in a WinForm application, you'll need to be targeting .NET Framework 4.0 or later in order for it to work.

查看更多
路过你的时光
6楼-- · 2018-12-31 20:41

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

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;
    }
}
查看更多
萌妹纸的霸气范
7楼-- · 2018-12-31 20:41

You can also look at the following if you reference 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.

查看更多
登录 后发表回答