Check to see if 3 keys are pressed - c#

I'm making an application in C# With Visual Studio 2010. It is an Windows Forms Application
What I want to do is to trigger an function when 3 keys are pressed. The keys are CTRL, SHIFT and X.
I have this code right now:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
Console.WriteLine(e.KeyValue);
/*
*KeyValue:
*CTRL = 17
*Shift = 16
*X = 88
*/
}
And as you can see, its pretty empty. This is because I don't know it anymore.
I've found on the internet this piece of code, but don't know how to implement it:
[DllImport("user32.dll")]
public static extern int GetKeyboardState(byte[] keystate);
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
byte[] keys = new byte[255];
GetKeyboardState(keys);
if (keys[(int)Keys.Up] == 129 && keys[(int)Keys.Right] == 129)
{
Console.WriteLine("Up Arrow key and Right Arrow key down.");
}
}
So my question to you guys is, how can i check if all the tree keys are pressed at the same time?
Or if you know an better way to make such an hot key, how would that be than?

In the case of CTRL+SHIFT+X, only X is really a proper key; the others are "modifier" keys. So no need to break out the P/Invoke :-) Just do this in your Key_Down handler:
if (e.KeyCode == Keys.X && e.Control && e.Shift) {
// CTRL+SHIFT+X was pressed!
}

Related

Keypress detection and sending in c#

So what im looking to do is find if i have the space bar pressed at all and while it is i would like to have the space bar be released and then pressed again mutiple times with a delay of about 10 ms. i have tried to read and understand this link (https://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress.aspx) but it is still confusing any help? im brand new to c# but i have some experience with pascal of which i have found very similar
(using visual studio 2015 due to my computer not allowing me to update to windows 8.1)
10ms delay mean 100 times per second, no one could do it.
Key events occur in the following order:
KeyDown
KeyPress
KeyUp
Events KeyDown and KeyUp use KeyEventArgs, while KeyPress is KeyPressEventArgs,
KeyEventArgs could details how many keys are pressed at same time. KeyEventArgs.KeyCode is Keys which is a [Flags] enum, it could contains multiple keys, like CTRL+SHift+F+G
if your hotkey is Ctrl+Shift+Space, you can check with:
var hotkeyPressed = e.Control && e.Shift && e.KeyCode == Keys.Space;
if your hotkey is Ctrl+F10+Space, you can check with:
var hotkeyPressed = e.Control && e.KeyCode == (Keys.Space | Keys.F10);
but do not use:
var hotkeyPressed = e.Control && e.KeyCode.HasFlag(Keys.F10) && e.KeyCode.HasFlag(Keys.Space); // e.KeyCode probably contains other flags
KeyPressEventArgs.KeyChar is a string, take a look source code, focus on its comments
[ComVisible(true)]
public class KeyPressEventArgs : EventArgs
{
...
/// <summary>Gets or sets the character corresponding to the key pressed.</summary>
/// <returns>The ASCII character that is composed. For example, if the user presses SHIFT + K, this property returns an uppercase K.</returns>
public char KeyChar { get; set; }
...
}
to use which event, it depends on your requirement.
here is sample code in KeyDown:
private int counting = 0, limit = 10;
private void txt_KeyDown(object sender, KeyEventArgs e)
{
if (!e.KeyCode.HasFlag(Keys.Space)) //check if your expected key is pressed
{
counting = 0;
return;
}
//start counting
counting++;
if (counting > limit)
{
e.Handled = true;
//do you business work, like: Send something somewhere
}
else
{
//do something else, like: show the number 'counting' in GUI
}
}
if you want limit timespan with next space, use a Timer
private void txt_KeyDown(object sender, KeyEventArgs e)
{
timer1.Stop();
if (!e.KeyCode.HasFlag(Keys.Space))
{
counting = 0;
return;
}
//start counting
timer1.Start();
counting++;
if (counting > limit)
{
e.Handled = true;
//do you business work, like: Send something somewhere
}
else
{
//do something else, like: show the number 'counting' in GUI
}
}
//timer1.Interval = 100; //100ms timeout. user has to press space again within 100ms
private void timer1_Tick(object sender, EventArgs e)
{
counting = 0;
}

Can't get Windows Forms Key combinations if one of the Keys is Alt, Control, or Shift [duplicate]

This question already has answers here:
WinForms - Capturing the combination of key presses using ProcessCmdKey VS KeyDown
(3 answers)
Closed 8 years ago.
My program has several key combinations, but whenever Shift, Alt or Control is pressed, they override any other keys that are not one of those 3, even though they don't override each other. Can someone please help me find a way to make sure the KeyEventArgs (or some equivalent function) gets both, like for example Shift + W? In the code below, I only every get the shift writeline, never the combo, regardless if I started by holding down the W or the Shift.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Shift)
{
if (e.KeyData == Keys.W || e.KeyData == Keys.S)
{
Console.WriteLine("combination");
}
Console.WriteLine("shift");
}
}
The KeyData property exposes the key that was pressed as well as the modifiers that are active. So you'd use it like this:
private void Form1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyData == (Keys.Shift | Keys.W) || e.KeyData == (Keys.Shift | Keys.S)) {
Console.WriteLine("combination");
}
}
You can do it your way as well, but then you have to use a different property, KeyCode. It exposes only the key code without the modifier keys:
private void Form1_KeyDown(object sender, KeyEventArgs e) {
if (e.Shift) {
Console.WriteLine("shift");
if (e.KeyCode == Keys.W || e.KeyCode == Keys.S) {
Console.WriteLine("combination");
}
}
}
Which one you'd use is entirely up to you. Do however keep in mind that using the form's KeyDown event is not very correct. It also requires setting the KeyPreview property to true. That's a pretty ugly VB6 compatibility property, you cannot see every possible keystroke. The navigation keys are filtered, like it was done in VB6. The native Winforms way is to override the ProcessCmdKey() method instead. Which does require you to work with KeyData.

How to capture combination of Insert+Tab in WinForms?

This is not a duplicate. Many similar threads discuss capturing a combination involving a modifier key.
I need to get something triggered when a shortcut key (a combination of Insert+Tab) is pressed from a control, say Button.
Catch:
This involves no modifier key like Alt or Shift for which .NET has built in checking.
This has Tab key which is not caught so easily.
What I tried and came close:
1) KeyDown Event but doesnt capture Tabs..
[DllImport("user32.dll")]
public static extern int GetKeyboardState(byte[] keystate);
static void form_KeyDown(object sender, KeyEventArgs e)
{
if (!(((Form)sender).ActiveControl is Button))
return;
byte[] keys = new byte[255];
GetKeyboardState(keys);
if (keys[(int)Keys.Insert] == 129 && keys[(int)Keys.Tab] == 129)
{
// doesn't work
}
if (keys[(int)Keys.Insert] == 129 && keys[(int)Keys.J] == 129)
{
// works, since here this doesnt involve Tab
}
}
This works with regular combinations, doesnt fire along with Tab.
2) KeyPreview Event which captures Tab key, but I do not know how to get a combination of keys pressed
static void form_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (!(((Form)sender).ActiveControl is Button))
return;
if (e.KeyCode == Keys.Tab)
//works
if (e.KeyCode == Keys.Insert && e.KeyCode == Keys.Tab)
//doesn't hit.
}
Requirement:
1) I am not registering the event from Form class. Instead I have a utility class which creates all required events (along with other shortcuts). I just pass the instance of form to a static function. So I am quite unsure how I should utilize the various key overriding calls. Here is how I do it:
public frmLogin()
{
InitializeComponent();
Utility.SetFormEvents(this);
}
static void SetFormEvents(Form f){
//foreach control...........
}
But I can give up on this..
Thanks..
Tab is considered a command key, you don't actually get notified of it being pressed directly. You could PInvoke the GetKeyState method, but I think it's just easier to recognize that tab is a command key (and override ProcessCmdKey) and keep track of whether the Insert key is up or down. For example:
static bool insertPressed;
static bool tabPressed;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if(keyData == Keys.Tab)
{
tabPressed = true;
CheckForTabAndInsert();
}
return base.ProcessCmdKey(ref msg, keyData);
}
static void form_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Insert)
{
insertPressed = true;
CheckForTabAndInsert();
insertPressed = false;
}
}
static void form_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Insert) insertPressed = false;
}
The drawback is that you only really get a KeyPress for tab with ProcessCmdKey, so you can only really support Insert+Tab (not Tab+Insert). This is because Tab is used to switch context from one control to another. Depending on your situation (i.e. in the context of a text box), you could make use of the AcceptTab property to possibly just use KeyUp and KeyDown... But, from what you posted, that doesn't appear to be the case.

How can I send a single Downkey key when my user taps the numpad Enter key?

This is purely for a usability request my clients have asked me.
They work with a datagridview typing in grades for students. So they pretty much go into zombie mode and start tapping in numbers, and they've told me that it would be easier if they could tap the numpad enter key to have the next vertical select focused.
Here's what I've tried to use:
private void dataGridView1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
SendKeys.Send("{DOWN}");
}
}
Unfortunately, it doesn't work as expected. Sometimes it seems to fire that key many times, causing the focus to scroll 2 or 3 or 4 cells downwards and really shaking up the users focus.
How can I make this work and make my clients happy?
private void datagridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
bindingsource.MoveNext();
}
}
Try this - I have tested it and it works.
private void datagridView12_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
int col = dataGridView12.CurrentCell.ColumnIndex;
int row = dataGridView12.CurrentCell.RowIndex;
if (row != dataGridView12.NewRowIndex)
{
if (col == (dataGridView12.Columns.Count - 1))
{
col = -1;
row++;
}
dataGridView12.CurrentCell = dataGridView12[col, row + 1];
}
e.Handled = true;
base.OnKeyDown(e);
}
}
You could use a boolean that is set to true on keyDown and set to false on keyUp.
Only run your sendKeys.Send when the boolean is true. That should ensure that the event is only fired once for every key press.
That's often how I've seen it done in other languages, I'm not sure if there is a better way to do it in C#.
When you press Enter key in the DataGridView (whether in edit mode or not) it goes one cell down by default (in .NET framework 3.5 and 4.0).
Isn't it the functionality you needed in the first place?
Can you not set the focus on the next textbox when the user presses enter?
You can use the TextBox.Focus() method to move the next textbox.

Keydown event capturing number keys

VS 2008 SP1
I want to capture the number keys 0 to 9. And perform some action if those number are clicked.
I am using the code below. However, it doesn't seem to be working right. However, the code doesn't go into the switch as when I use the debugger to see what key value has been captured in the e.KeyValue it comes up with "LButton | ShiftKey | Space".
However, should it not display NumPad1?
Many thanks for the advice,
private void CATDialer_KeyDown(object sender, KeyEventArgs e)
{
// Play sound when use kits number key
switch (e.KeyValue)
{
case Keys.NumPad1:
// Do something here
break;
.
.
.
}
I'm using this Code
private void tb_mds_port_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 8) // do something if backspace is pressed
{
// ACTION
e.Handled = true;
}
}
For your code use something like this
if(e.KeyChar == (char)Keys.Return) // do something if return is pressed
{
//ACTION
e.Handled = true;
}

Categories

Resources