Skipping KeyDown On Override ProcessCmdKey EventHandller - c#

I have a simple increment on textbox by pressing down arrow key which are as below.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Down)
{
int c = int.Parse(textBox1.Text);
c++;
textBox1.Text = c.ToString();
}
}
The above works on pressing double down arrow key instead of single pressing down arrow key.
Note: The above code is on UserControl. And I have tried it on simple winform application on form keydown EventHandller and the same is works fine.
How to overcome?.

You'll need to handle other commands that existed before and return when you handle ones you are looking for. Try changing it to this and see if that helps:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (msg.WParam.ToInt32() == (int)Keys.Down)
{
int c = int.Parse(textBox1.Text);
c++;
textBox1.Text = c.ToString();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}

Related

How to disable scrolling of comboBox from keys arrow Up\Down when it closed?

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);
}

C# - Implementing Hotkeys in WinForms

I tried following code:
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Control)
{
// Show the hotkey on the buttons with ctrl hotkeys
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
switch (keyData)
{
case Keys.Control | Keys.S:
// Execute the Ctrl + S button action
btnSettingsSave_Click(this, null);
return true;
default:
break;
}
return base.ProcessCmdKey(ref msg, keyData);
}
to save my setting in the GUI by pressing CTRL+S. Now that works fine but I wanted to put in more hot keys (for example CTRL+F). How can I do that?

Stop a key from firing an event in C# using ProcessCmdKey?

So I'm making a form, and I want the left and right keys to ONLY correspond to a numericUpDown box that I have on the form. So the code I wrote is the following :
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Right)
{
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value + 1);
}
if (keyData == Keys.Left)
{
try
{
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value - 1);
}
catch { }
}
return base.ProcessCmdKey(ref msg, keyData);
}
However it seems to still do the default action of moving between different objects on the form if that's what the selected view is currently. How do I stop the default action?
You need to return true when you don't want the default action to be carried out.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Right)
{
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value + 1);
return true;
}
if (keyData == Keys.Left)
{
try
{
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value - 1);
return true;
}
catch { }
}
}
Maybe you should return true to indicate you have processed the key stroke message so that no other controls get it.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Right){
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value + 1);
return true;
}
else if (keyData == Keys.Left){
try {
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value - 1);
}
catch { }
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
NOTE: It looks like that you didn't post the code you run? I highly recommend you to post the actual code of yours, your code doesn't even compile because lacking of return. And your code lacks the return base.ProcessCmdKey(ref msg, keyData); which is required to process other keys.
you can add an event hanlder and do this:
private void keypressed(Object o, KeyPressEventArgs e)
{
if (e.KeyCode == Keys.Right || e.KeyCode == Keys.Left)
{
e.Handled = true; //this line will do the trick
//add the rest of your code here.
}
}

How to detect key down/up when a second key is already held down

In my application I allow the user to scroll a movie by holding down the Right arrow key by using ProcessCmdKey. Now I would like to give the user the ability to increase the scrolling speed whenever desired. Ideally the user should be able to hold down the Right arrow key, then when he decides to increase the speed he should, without releasing the Right arrow key, hold down also the Shift key and when he decides to go back to the normal speed he should simply release back the Shift key. So the difference in the scrolling speed should be given only from Shift key modifier that should be added or removed to the Right arrow key pressure.
I tried a code like this but with no success (I've a simple label in my form in this test example):
int count = 0;
bool keyRightDown = false;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Right)
{
keyRightDown = true;
count++;
label.Text = "count = " + count.ToString();
return true;
}
if (keyData == (Keys.Shift | Keys.ShiftKey) && keyRightDown)
{
count += 10;
label.Text = "count = " + count.ToString();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
protected override bool ProcessKeyMessage(ref Message m)
{
if ((Keys)m.WParam == Keys.Right)
{
if (m.Msg == 0x101) // KEYUP
{
keyDown = false;
return true;
}
}
return base.ProcessKeyMessage(ref m);
}
When the user add the Shift key to the Right arrow the keyData does not contain (Keys.Shift | Keys.Right) as I was expecting but (Keys.Shift | Keys.ShiftKey). However this issue can still be solved by the boolean keyRightDown. The main problem is that when the user release back the Shift key by having at this point only the Right arrow pressed, no other calls to neither ProcessCmdKey nor ProcessKeyMessage are triggered. How can I achieve my goal?
The only way I found was to use a combination of calling the GetKeyState API function (user32.dll) and of a Timer. Here is as it works on the test app:
System.Windows.Forms.Timer keyManagerTimer = new System.Windows.Forms.Timer();
int count = 0;
public Form1()
{
InitializeComponent();
this.keyManagerTimer.Tick += (s, e) => ProcessKeys();
this.keyManagerTimer.Interval = 25;
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if ((keyData & Keys.Right) != 0)
{
keyManagerTimer.Enabled = true;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void ProcessKeys()
{
bool isShiftKeyPressed = IsKeyPressed(Keys.ShiftKey);
bool isRightKeyPressed = IsKeyPressed(Keys.Right);
if (isRightKeyPressed && !isShiftKeyPressed)
{
count++;
}
else if (isRightKeyPressed && isShiftKeyPressed)
{
count += 10;
}
label.Text = "count = " + count.ToString();
}
public static bool IsKeyPressed(Keys key)
{
return BitConverter.GetBytes(GetKeyState((int)key))[1] > 0;
}
[DllImport("user32")]
private static extern short GetKeyState(int vKey);
In my real code then I disable the Timer on the Leave event of the Control where I have the video. Possibly another solution might have been to use the IMessageFilter (see here).
A possible solution is to store all possible key presses in a bool array then check the bool array if certain values are true. In the case of holding down your button you'd set the button key to true and back to false when the key is released. This is an option I ussualy tend to use when I need to check for multiple key presses.

How to detect Alt + left key in ToolStripTextBox

In C# - WinForms, how to detect Alt + left key when it is pressed in ToolStripTextBox?
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (this.ActiveControl == toolStripTextBox1.Control && keyData == (Keys.Alt | Keys.Left)) {
MessageBox.Show("it's special");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}

Categories

Resources