views:

9928

answers:

6

In WinForms, you can know, at any time, the current position of the cursor thanks to the Cursor 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)?

Thank you.

A: 

In WinForms:

if( Form.ModifierKeys == Keys.Shift )

Sounds like a duplicate of this question

Will Eddins
I don't think that wont work if you are in a textbox
Joe
He may not care, but I just wanted to pont it out :p
Joe
+2  A: 

You can P/Invoke down to the Win32 GetAsyncKeyState to test any key on the keyboard. 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.

Jason Williams
+4  A: 

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.

Jeff Wain
Actually Keyboard.Modifiers do not always work properly. Had to find the hard way: http://discoveringdotnet.alexeyev.org/2008/09/keyboardmodifiers-sometimes-doesnt-work.html
Maxim Alexeyev
Except this is not using Forms modifiers, System.Windows.Input modifiers is a different namespace and has worked fine for us every time.
Jeff Wain
+22  A: 
if ((Control.ModifierKeys & Keys.Shift) != 0)

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

if (Control.ModifierKeys == Keys.Shift)

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

SLaks
Unless I'm missing something, you haven't answered the question properly. The OP is asking about all keys and used the Shift key as an example only. So how do you detect other keys such as A to Z, 0 to 9 etc.
Ash
Given that he accepted the answer, it appears that he only needed modifier keys. If you want other keys, you'll need to call the `GetKeyState` API function.
SLaks
@SLaks, no need for GetKeyState. You just need to add a message filter. See my answer.
Ash
+1  A: 
if (Control.ModifierKeys == Keys.Shift)
    //Shift is pressed

The cursor x/y position is a property, 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.

Rob Elliott
+5  A: 

It's a bit late, but the code below is how to detect almost all currently pressed keys, not just the Shift key.

I noticed most of the other answers don't actually answer the question properly.

private KeyMessageFilter m_filter = new KeyMessageFilter();

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

}


public class KeyMessageFilter : IMessageFilter
{
    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; 
    }

    private const int WM_KEYDOWN = 0x0100;

    private const int WM_KEYUP = 0x0101;

    private bool m_keyPressed = 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;
    }
}
Ash
`GetKeyState` would be more efficient. There's no point in tracking all of the keys when Windows does it for you already.
SLaks
@Slaks, unless you have some benchmark data, you're guessing. Moreover GetKeyState will tell you the state of a key, *if* you can trap that keyboard event in the first place. My reading of the question is that the OP wants to know how to get the state of a key at *any time*. So GetKeyState by itself is useless.
Ash
Correct. I'm just guessing.
SLaks