Capture multiple key downs in C#
I think you'll be best off when you use the GetKeyboardState API function.
[DllImport ("user32.dll")]
public static extern int GetKeyboardState( byte[] keystate );
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
byte[] keys = new byte[256];
GetKeyboardState (keys);
if ((keys[(int)Keys.Up] & keys[(int)Keys.Right] & 128 ) == 128)
{
Console.WriteLine ("Up Arrow key and Right Arrow key down.");
}
}
In the KeyDown event, you just ask for the 'state' of the keyboard.
The GetKeyboardState will populate the byte array that you give, and every element in this array represents the state of a key.
You can access each keystate by using the numerical value of each virtual key code. When the byte for that key is set to 129 or 128, it means that the key is down (pressed). If the value for that key is 1 or 0, the key is up (not pressed). The value 1 is meant for toggled key state (for example, caps lock state).
For details see the Microsoft documentation for GetKeyboardState.
Capturing ctrl + multiple key downs
The article in the comment may have been for WPF but the idea in it can still be used
Construct a class such as
public class MultiKeyGesture
{
private List<Keys> _keys;
private Keys _modifiers;
public MultiKeyGesture(IEnumerable<Keys> keys, Keys modifiers)
{
_keys = new List<Keys>(keys);
_modifiers = modifiers;
if (_keys.Count == 0)
{
throw new ArgumentException("At least one key must be specified.", "keys");
}
}
private int currentindex;
public bool Matches(KeyEventArgs e)
{
if (e.Modifiers == _modifiers && _keys[currentindex] == e.KeyCode)
//at least a partial match
currentindex++;
else
//No Match
currentindex = 0;
if (currentindex + 1 > _keys.Count)
{
//Matched last key
currentindex = 0;
return true;
}
return false;
}
}
but ignore the inheritance.
to use it
private MultiKeyGesture Shortcut1 = new MultiKeyGesture(new List<Keys> { Keys.A, Keys.B }, Keys.Control);
private MultiKeyGesture Shortcut2 = new MultiKeyGesture(new List<Keys> { Keys.C, Keys.D }, Keys.Control);
private MultiKeyGesture Shortcut3 = new MultiKeyGesture(new List<Keys> { Keys.E, Keys.F }, Keys.Control);
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (Shortcut1.Matches(e))
BackColor = Color.Green;
if (Shortcut2.Matches(e))
BackColor = Color.Blue;
if (Shortcut3.Matches(e))
BackColor = Color.Red;
}
Multiple keys in KeyDown
Key
enumeration is not marked with Flags
and so cannot hold multiple values. And there is just one Key
property in that event args, so just one key. Hence, your if
can never be true because 3 of your &&
conditions are mutually exclusive.
What you can do instead is this:
if ((Keyboard.Modifiers == ModifierKeys.Control)
&& (Keyboard.IsKeyDown(Key.R))
&& (Keyboard.IsKeyDown(Key.S))
&& (Keyboard.IsKeyDown(Key.V))) {
}
Note that if you want to allow other modifier keys to be pressed at the same time (so, if you don't care if both ALT and CONTROL might be pressed together for example), then you should use
Keyboard.Modifiers.HasFlag(ModifierKeys.Control)
instead.
multiple keys keydown on keyboard at once time in c#
You can't get a KeyDown
event with multiple keys.
However, you can either check for keys that are currently pressed, or you can keep track of all those that are Down
at the moment (record them when you get KeyDown
and remove when you get KeyUp
).
There is a fixed limit to keys being pressed simultaneously based on the hardware keyboard. It may very well be that some key combinations only allow you to register two keys simultaneously, while others are more useable. And of course, there's gaming keyboards that can easily keep track of 20 or more at a time.
How to detect if multiple keys are pressed in C# forms
The source of the problems is that this simple request is simply not supported under Winforms.
Sounds weird? It is. Winforms is often painfully close to the hardware layers and while this may be quite interesting at times, it also may be just a pita..
((One hidden hint by Hans should be noted: In the KeyUp
you get told which key was released so you can keep track of as many keys as you want..))
But now for a direct solution that desn't require you to keep a bunch of bools
around and manage them in the KeyDown
and KeyUp
events..: Enter Keyboard.IsKeyDown.
With it code like this works:
Uses the
Keyboard.IsKeyDown
to determine if a key is down.
e
is an instance ofKeyEventArgs
.if (Keyboard.IsKeyDown(Key.Return)) {
btnIsDown.Background = Brushes.Red; }
...
Of course you can ceck for multiple key as well:
if (Keyboard.IsKeyDown(Key.A) && Keyboard.IsKeyDown(Key.W)) ...
The only requirement is that you borrow this from WPF
:
First: Add the namespace:
using System.Windows.Input;
Then: Add two references to the project:
PresentationCore
WindowsBase
Now you can test the keyboard at any time, including the KeyPress
event..
Tracking KeyUp and KeyDown of multiple keys at once
I'm not sure whether I understand your question, but I would use a Dictionary<Keys, Stopwatch>
to track the times. As keys for the Dictionary I would use the lower-case character of each pressed key.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private readonly Dictionary<Keys, Stopwatch> _stopwatches = new Dictionary<Keys, Stopwatch>();
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
_stopwatches[e.KeyCode] = Stopwatch.StartNew();
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
textBox2.Text += e.KeyCode;
Stopwatch stopwatch;
if (_stopwatches.TryGetValue(e.KeyCode, out stopwatch))
{
stopwatch.Stop();
textBox2.Text += " " + stopwatch.ElapsedMilliseconds + "ms";
}
textBox2.Text += Environment.NewLine;
}
}
textBox1 is the input box.
textBox2 is the output box, but you could use your text file here as well.
Related Topics
String Concatenation VS String Builder. Performance
Why Does C# (4.0) Not Allow Co- and Contravariance in Generic Class Types
How to Set Up HTML/Email Templates with ASP.NET
Check If Instance Is of a Type
Fast Creation of Objects Instead of Activator.Createinstance(Type)
How to Make a Call to My Wcf Service Asynchronous
What Is the Easiest Way to Subtract Time in C#
Serialize a Container of Enums as Strings Using JSON.Net
How to Save Image in Database Using C#
How to Execute Task in the Wpf Background While Able to Provide Report and Allow Cancellation
Best Way to Implement Multi-Language/Globalization in Large .Net Project
Performance of Static Methods VS Instance Methods
How to Provide Custom Cast Support for My Class
How to Programmatic Disable C# Console Application's Quick Edit Mode