I am trying to bind multiple keys on a KeyDown event to change a bool variable, but I can't seem to figure out how to trigger the asterisk/star key (*) with the Left Shift key in the following code:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Multiply || keyData == (Keys.LShiftKey | Keys.OemQuotes))
{
Valgt = true;
}
}
This answer will not be keyboard layout invariant but this would do the trick on a US-EN keyboard. It's not robust but can be adapted to your local layout.
if (keyData == Keys.Multiply || keyData == (Keys.Shift | Keys.D8))
{
Valgt = true;
}
Alternatively you can use Control_KeyPress event
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '*')
{
Valgt = true;
}
}
Related
The arrow keys should scroll only pictureBox (placed in panel). It works fine.
But it also scroll through comboBox items though it is closed (droppedUp).
How to disable it?
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.DropDownStyle = ComboBoxStyle.DropDown;
comboBox1.DroppedDown = false;
comboBox1.Items.Add("111");
comboBox1.Items.Add("222");
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Down)
{
Point current = panel1.AutoScrollPosition;
Point scrolled = new Point(current.X, -current.Y + 50);
panel1.AutoScrollPosition = scrolled;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I had read about Control.PreviewKeyDown event:
preview key event
and also found another example:
preview key event
but I cannot understand how it used in my case.
As Hans Passant commented, you must return true. Also, add some other keys that maybe change the selected item in the combobox:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Down ||
keyData == Keys.Up ||
keyData == Keys.PageDown ||
keyData == Keys.PageUp)
{
Point current = panel1.AutoScrollPosition;
Point scrolled = new Point(current.X, -current.Y + 50);
panel1.AutoScrollPosition = scrolled;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I have the following code in my project which disables arrow keys completely:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (!msg.HWnd.Equals(Handle) &&
(keyData == Keys.Left || keyData == Keys.Right ||
keyData == Keys.Up || keyData == Keys.Down))
return true;
if (keyData == Keys.Escape)
{
this.Close();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I also have this code after it which I need in order to make it such that the up arrow key counts up.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
{
int count;
if (count_lbl.Text.Equals(""))
count = 0;
else
count = Convert.ToInt32(count_lbl.Text);
count++;
count_lbl.Text = count.ToString();
}
}
I don't want the arrow keys to change focus to any control, other than the one I initialized my form to, but I still want to be able to use them later on in order to be able to do other things. Is there a way to do this?
Thanks.
Just put the "counting" code in ProcessCmdKey()?
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (!msg.HWnd.Equals(Handle) &&
(keyData == Keys.Left || keyData == Keys.Right ||
keyData == Keys.Up || keyData == Keys.Down)) {
if (keyData == Keys.Up) {
int count;
if (count_lbl.Text.Equals(""))
count = 0;
else
count = Convert.ToInt32(count_lbl.Text);
count++;
count_lbl.Text = count.ToString();
}
return true;
}
if (keyData == Keys.Escape)
{
this.Close();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I have a class that catches keyboard keys and I want to catch a specific combination:
Alt + 1
And in case this combination is detected to do my stuff.
This is what I have try:
private bool isAltPressed;
private bool isOnePressed;
private bool bothPressed;
private void HookManager_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.LMenu)
isAltPressed = true;
if (e.KeyCode == Keys.D1)
isOnePressed = true;
if (isAltPressed & isOnePressed)
bothPressed = true;
}
private void HookManager_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (bothPressed)
// Do something...
if (e.KeyCode == Keys.LMenu)
{
isAltPressed = false;
bothPressed = false;
}
if (e.KeyCode == Keys.D1)
{
isOnePressed = false;
bothPressed = false;
}
}
So where do I need to verify that both keys are pressed and released and then do my stuff?
Try this:
if ( e.KeyData == (Keys.Alt | Keys.D1) )
Keys is a struct having a flag attribute.
It means that several key codes can be combinated with the logic or operator to form the result.
[Flags]
public enum Keys ...
You should not wait for alt key to be released to perform your action. Unless you can explain why you need to make sure both the alt key and the key pressed must be released before 'doing something', the following code should suffice in either your KeyUp or KeyDown event.
if (e.Modifiers == Keys.Alt && e.KeyCode == Keys.D1)
{
// Do Something
}
I need to capture a kepress combo on the keyboard so i can override the standard function, i've tried the following:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A)
{
MessageBox.Show("Hello");
}
}
But when pressing Ctrl+A the message is not triggered. The end aim is to override the windows shortcut 'select all' in a DataGridView within the Form1 to ensure only certain rows are selected when Ctrl+A is pressed in the form window.
First, ensure that Form1 property
KeyPreview = true
Next, do not forget to handle the message (you don't want DataGridView process the message and do SelectAll)
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A)
{
e.Handled = true; // <- do not pass the event to DataGridView
MessageBox.Show("Hello");
}
}
So you preview KeyDown on the Form1 (KeyPreview = true), perform the required action, and prevent DataGridView from executing select all (e.Handled = true)
In general to handle a shortcut key, you can override ProcessCmdKey. By overriding this method, you can handle the key combination:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.A))
{
MessageBox.Show("Control + A");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
Returning true, means it's handled by your code and the key will not pass to the child control. So it's enough to override this method at form level.
But if you are talking specifically about DataGridView to customize the Ctrl + A combination, you can override ProcessDataGridViewKey method of the DataGridView:
public class MyDataGridView : DataGridView
{
protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
if (e.KeyData == (Keys.A | Keys.Control))
{
MessageBox.Show("Handled");
return true;
}
return base.ProcessDataGridViewKey(e);
}
}
Just for the records: This can be done with KeyPress too, because the Ctrl+Letter keys are "special":
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar=='\u0001') //Ctrl+A, B=2, C=3 ...
{
MessageBox.Show("Control + A");
}
}
This question already has an answer here:
Capture Key Sequence via ProcessCmdKey
(1 answer)
Closed 7 years ago.
I need to make a shortcut key combination of three letters (Ctrl+L+I)
I tried a lot to do so but no luck .
I tried it in this way
private void MDIParent2HOME_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.Keycode==Keys.L && e.KeyCode == Keys.I)
{//login
Form1 chilform = new Form1();
chilform.MdiParent = this;
chilform.Show();
}
}
but this didn't work.
then I changed my key combination (ctrl+ALt+L) and tried it in same way
private void MDIParent2HOME_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.Alt && e.KeyCode == Keys.L)
{//login
{
Form1 chilform = new Form1();
chilform.MdiParent = this;
chilform.Show();
}
}
}
and I am wondering that worked perfect .I couldn't get the reason do anyone know about this behaviour of KeyDown event.Also help me if I can do the same with (ctrl+L+I) . Thanks
Hmmm...I think my solution works
private bool IfSeen;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (IfSeen)
{
if (keyData == (Keys.Control | Keys.I))
{
MessageBox.Show("You pressed Ctrl+L+I");
}
IfSeen= false;
return true;
}
if (keyData == (Keys.Control | Keys.L))
{
IfSeen= true;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
You are checking for e.Keycode==Keys.L && e.KeyCode == Keys.I. I think e.Keycode contains only the value of a single key, L or I, but not both at the same time, so your check will always fail.
Note that Alt, Shift and Ctrl are modifiers and are handled a bit differently than other keys.