Is there some global constructs that I can use whenever I need to access whether the Control, Shift, Alt buttons are down? For instance inside MouseDown event of a TreeView.
If so how?
Use class Keyboard. Using Keyboard.IsKeyDown you can check if Control, Shift, Alt is down now.
For Shift:
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{ /* Your code */ }
For Control:
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{ /* Your code */ }
For Alt:
if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ /* Your code */ }
There's also:
// Have to get this value before opening a dialog, or user will have released the control key
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
}
private bool IsShiftKey { get; set; }
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
IsShiftKey = Keyboard.Modifiers == ModifierKeys.Shift ? true : false;
if ((Key.Oem3 == e.Key || ((IsShiftKey && Key.Oem4 == e.Key) || (IsShiftKey && Key.Oem6 == e.Key) || (IsShiftKey && Key.Oem5 == e.Key)) && (validatorDefn as FormatValidatorDefinition).format == "packedascii"))
{
e.Handled = true;
}
}
This is how I handle it (using PreviewKeyDown), let's say we are looking for Alt + R...
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)
&& e.SystemKey == Key.R)
{
//do whatever
}
}
Maybe someone can clear up why I had to use e.SystemKey and not just e.Key, maybe due to the modifier? but this has worked flawlessly for me when searching for modifier+key.
Partly borrowing from #Josh, and somewhat similar to #Krushik, and also referencing a question about the Difference between KeyEventArgs.systemKey and KeyEventArgs.Key (answering why Josh has to use SystemKey); wherein, with modifier keys (such as Alt), e.Key returns Key.System, and thus the 'real' key is within e.SystemKey.
A way around this, is to first fetch the 'real' key, and then do your conditional:
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
// Fetch the real key.
var key = e.Key == Key.System ? e.SystemKey : e.Key;
if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
&& key == Key.Return)
{
// Execute your code.
}
}
and as well:
if My.Computer.Keyboard.ShiftKeyDown then ...
My.Computer.Keyboard.CtrlKeyDown
My.Computer.Keyboard.AltKeyDown
Related
I have a textbox in my application which I only want the user to be able to choose the "minus", "comma", "digits" and "back" from the keyboard. Can only make the user use digits and the back key, the rest doesn't work.
private void BoxMaxY_KeyPress(object sender, KeyPressEventArgs e)
{
if (!(Char.IsDigit(e.KeyChar) || e.KeyChar == (char)Keys.Back ||
!(e.KeyChar == (char)Keys.OemMinus || !(e.KeyChar == (char)Keys.Oemcomma))))
{
e.Handled = true;
}
}
Because your code says: handle if it's not minus or not comma, remove the "!" from those checks.
I have to catch user's input to send a shortcut to my WPF application.I found on internet that I have to do something like this: Catch when a key is pressed:
void keyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers.HasFlag(Modifiers.Shift))
KeyPressed.SetShift(true);
if (Key.Shift != e.Key && Key.LeftAlt != e.Key && ....)
KeyPressed.SetKey(e.Key);
}
where KeyPressed is a class with static boolean variables to catch if ⇧Shift, Alt or Ctrl and another key are pressed (with Alt and Ctrl instead of ⇧Shift in the if clause). The second if is to catch a key different from Alt, ⇧Shift, Control for the shortcut. For example, for the shortcut Alt+C we have:
KeyPressed.Shift = false;
KeyPressed.Alt = true;
KeyPressed.Ctrl = false;
KeyPressed.key = Key;
Where the last element is of type System.Window.Input.Key.Catch when a key is released:
void keyUp(object sender, KeyEventArgs e)
{
if (KeyPressed.getShift())
this.textField.Text += "+Shift";
if (KeyPressed.getKeyCode())
this.textField.Text += "+" + KeyPressed.k.toString();
KeyPressed.SetShift(false);
}
and here simply I append to a textField the input received, after that I set all keys to false to catch the next shortcut correctly. This code works fine for all shortcuts like Ctrl+A, Ctrl+Alt+C, ⇧Shift+L, Alt, but when I press the shortcut like Alt+V, it catchs only Alt, not the other key.
How can I manage this? Is there a way to handle shortcuts in a better manner?
You need to get the actual key when in case of a SystemKey (Alt etc), you can use this helper function to get the real key behind the system key.
public static Key RealKey(this KeyEventArgs e)
{
switch (e.Key)
{
case Key.System:
return e.SystemKey;
case Key.ImeProcessed:
return e.ImeProcessedKey;
case Key.DeadCharProcessed:
return e.DeadCharProcessedKey;
default:
return e.Key;
}
}
You could check my answer here for more info.
Store the Alt-modifier state in a local variable. I'm unsure of the reasons why but this made it work for me.
private bool _altModifierPressed = false;
private void Window_KeyDown(object sender, KeyEventArgs e)
{
_altModifierPressed = (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt));
if (_altModifierPressed && Keyboard.IsKeyDown(Key.V))
{
// code to handle Alt + V
}
}
UPDATE:
Alternatively, you could do something like this (no need for local variable)
if (((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) && Keyboard.IsKeyDown(Key.V))
{
// code to handle Alt + V
}
But I noticed that with either approach (since the enum has the Flag attribute) any combination of keys including Alt & V will work. So both execute if I for example press Alt+G+V. Good luck.
If you want to use [Alt + A] in KeyboardHook in Office VSTO, this is how it's used.
if (IsKeyDown(Keys.Menu) &&
keyData == Keys.A &&
KeyWasAlreadyPressed == false &&
!IsKeyDown(Keys.Controlkey) &&
!IsKeyDown(Keys.ShiftKey))
{
//Enter your code here
}
Note:
Key.Menu denotes Alt Keys
Also condition says, Alt+A (and do not invoke when control or shift key is pressed in addition to Alt + A)
switch (e.Key)
{
case Key.System:
if (((KeyboardEventArgs)e).KeyboardDevice.Modifiers == ModifierKeys.Alt)
{
if (e.SystemKey == Key.Left)
moiveVideoPsition(-30);
else if (e.SystemKey == Key.Right)
moiveVideoPsition(30);
}
break;
This work well for me
This:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress.aspx
...indicates that I should have access to e.KeyCode in the KeyPress event, but I don't seem to. I'm trying to allow only 1,2,3, and backspace:
private void textBoxQH1_KeyPress(object sender, KeyPressEventArgs e) {
if ((e.KeyChar != '1') &&
(e.KeyChar != '2') &&
(e.KeyChar != '3') &&
(e.KeyChar != (Keys.Back))) {
e.Handled = true;
}
}
...but "e." does not show a "KeyCode" value like the example shows, and trying KeyChar with Keys.Back scolds me with, "Operator '!=' cannot be applied to operands of type 'char' and 'System.Windows.Forms.Keys'"
So how can I accomplish this?
try comparing e.KeyChar != (char)Keys.Back, you should cast it to char since Keys is an enumeration
see this: KeyPressEventArgs.KeyChar
I'm pretty sure I've only ever solved this by using the KeyDown event instead; it has different event arguments.
Try to put a condition like this:
Code :
if (e.KeyCode == (Keys.Back))
{
if(textBox1.Text.Length >=3)
{
if (textBox1.Text.Contains("-"))
{
textBox1.Text.Replace("-", "");
}
}
}
im working on a simple game like "space invaders",and i got into a problem.
Im trying to give the user, the possiblity to move as much as he want from Left to Right, and in the same time have the possiblty to shot using the "Space bar".
My problem is: when i pressed more then 1 key, only 1 function run.
here a few stuff i tried:
Storing the keys in a List<Keys> (but i didnt find any good way to excute the functions and everything become messy)
2.normal handling of the key_down event like this:
protected void Form1_keysDown(object obj, KeyEventArgs e)
{
(e.KeyData == Keys.Space)
spaceShip.FireBullets();
if (e.KeyCode == Keys.Left)
spaceShip.MoveLeft();
if (e.KeyCode == Keys.Right)
spaceShip.MoveRight();
}
my qustion is: what is a good way to make this work?
(sorry for my english)
You are relying on the keyboard controller repeating the key when you hold it down. That stops working when you press another key. This requires a different approach.
First you need an enum that indicates the motion state of the spaceship with values like NotMoving, MovingLeft and MovingRight. Add a variable of that type to your class. You'll need both the KeyDown and KeyUp events. When you get a KeyDown for, say, Keys.Left then set the variable to MovingLeft. When you get the KeyUp event for Keys.Left then first check if the state variable is still MovingLeft and, if it is, change it NotMoving.
In your game loop, use the variable value to move the spaceship. Some sample code:
private enum ShipMotionState { NotMoving, MovingLeft, MovingRight };
private ShipMotionState shipMotion = ShipMotionState.NotMoving;
protected override void OnKeyDown(KeyEventArgs e) {
if (e.KeyData == Keys.Left) shipMotion = ShipMotionState.MovingLeft;
if (e.KeyData == Keys.Right) shipMotion = ShipMotionState.MovingRight;
base.OnKeyDown(e);
}
protected override void OnKeyUp(KeyEventArgs e) {
if ((e.KeyData == Keys.Left && shipMotion == ShipMotionState.MovingLeft) ||
(e.KeyData == Keys.Right && shipMotion == ShipMotionState.MovingRight) {
shipMotion = ShipMotionState.NotMoving;
}
base.OnKeyUp(e);
}
private void GameLoop_Tick(object sender, EventArgs e) {
if (shipMotion == ShipMotionState.MovingLeft) spaceShip.MoveLeft();
if (shipMotion == ShipMotionState.MovingRight) spaceShip.MoveRight();
// etc..
}
I am having trouble capturing Ctrl+PageUp keystroke in a ListView control in WinForms application.
I am using this code to capture keystrokes -
private void ListViewEx_KeyDown(object sender, KeyEventArgs e)
{
...
if(e.Control){
if((e.KeyCode ^ Keys.Left) == 0)
MessageBox.Show("Left"); //shows messagebox
else if((e.KeyCode ^ Keys.PageUp) == 0)
MessageBox.Show("PageUp"); //does not
...
}
Do I need to dive into WndProc to process this key? Thanks.
Edit: I've found out that this works, the problem was in enclosing TabControl handling these keys before ListControl got to them.
No need for WndProc:
if ((e.Modifiers & ModifierKeys) == Keys.Control && e.KeyCode == Keys.PageUp)
{
// ctrl + page up was pressed
}
The e.KeyData argument includes the modifier keys. Make it look like this:
if (e.KeyData == (Keys.Control | Keys.PageDown)) {
// Do your stuff
Console.WriteLine("Ctrl+PgDn");
}
check for
Keys.Control | Keys.PageUp