The three modifier keys are Control, Alt and Shift.
In the keys enumeration, there are Control and ControlKey, Shift and ShiftKey and Alt, but AltKey is missing.
Keys.ControlKey refers to the actual Ctrl key while Keys.Control refers to the control modification.
Similarly,Keys.ShiftKey refers to the actual Shift key while Keys.Shift refers to the shift modification.
What about the actual Alt key?
It can be pressed by itself and the corresponding element in the Keys enumeration should be Keys.AltKey!
Can you please explain the lack of the vlaue Keys.AltKey in the Keys enumeration?
Actually, the real key (not modifier) enumeration value for Alt key is Keys.Menu with the value of 18. That's just a naming convention. They decided to use the Alt name just for the modifer, and Menu for the non-modifier. Interestingly, the documentation for the Keys.Menu says "The ALT key". We also have Keys.LMenu and Keys.RMenu.
At a guess I'd say that the lack of the Alt key is due to the fact that in WinForms development, the paradigm used for setting shortcut keys is to prefix a letter with the & character, e.g., E&xit. When the application is run, this is automatically set up as a shortcut command Alt+X. Most windows shortcut keys are set up this way in development pretty much removing any reason why you'd want to detect it in code - or at least a KeyDown event. That said, I personally would have expected the Alt key to be available.
Related
I'm currently learning C# in University and I was wondering where you would use KeyValue. From this question (https://stackoverflow.com/a/318177), I found that "KeyCode is an enumeration that represents all the possible keys on the keyboard. KeyData is the KeyCode combined with the modifiers (Ctrl, Alt and/or Shift).", but I could find nothing about KeyValue.
KeyValue is an property of KeyEventArgs.
It is the integer representation of the KeyCode property.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.keyeventargs.keyvalue?view=net-5.0
It should be on the first page when you google for: c# KeyValue
When would you use it?
Pretty rarely I would say. It could be somewhat easier to store in a database instead of an enum value.
It's possible once Ctrl was pressed, get all keys pressed before until a non-digit was found? valid inputs:
Ctrl + 1 // do something with 1
Ctrl + 2 // do something with 2
//..
Ctrl + 30 // do something with 30
it's a will works as the FN keys, but instead of it, I wan to use Ctrl and extend the range from 0-9 to 0-50. I hope this is clean. Thanks in advance.
Note: I tagged C# and C languages because either of these languages is valid for my use case.
A low level keyboard hook should be able to do this. Use SetWindowsHookEx with WH_KEYBOARD_LL. You can find some C# implementations on the Internet.
I generally discourage the use of keyboard hooks due to their global side effects, but I can't think of anything else that fulfills your requirements.
I have been searching around for an answer to this but I can't seem to find anything. Does anyone know if you can determine the letter casing in Keys?
For example:
if (System.Windows.Forms.Keys.A.ToString() == "A")
{
// Upper or Lower?
}
Thanks.
There is no casing, it represents a physical key on your keyboard. Do you see an 'a' and an 'A' on your keyboard?
You can check and see if a Shift key is depressed.
System.Windows.Forms.Keys.A represents the physical key A on your keyboard. It does not have a case. Thus, your question does not make sense.
If you want to check whether the user holds the Shift key on the keybord, there's also System.Windows.Forms.Keys.Shift.
There is no simple mapping between keys and characters. Keyboard layouts can work differently. One example are dead keys. And once you get to IMEs it gets even more complicated. Do not try to duplicate a keyboard layout manually in your application.
If you want to get what character a user entered, handle WM_CHAR, not WM_KEY_DOWN/UP. It's exposed as Control.KeyPress event in winforms.
I override ProcessCmdKey in my application and can get any single keypress with modifiers (eg. Alt+Ctrl+X). What I want to do is mimic the short cut handling of say ReSharper where the user holds down the control key and then R, M to open the refactor dialog
I have found plenty of references to capture key plus modifier combinations but not much for the sequence. There is this Capture multiple key downs in C# but it uses the KeyDown Event.
There are also key mining examples such as this http://www.codeproject.com/KB/system/simple_key_log.aspx that capture everything and use native calls.
Am I able to extend my ProcessCmdKey to handle the key sequences or do I need to look elsewhere? Since I have a large number of shortcuts captured in ProcessCmdKey I would rather not have to start again if possible
Thanks
In order to achieve the functionality you want you simply need to keep track of the sequence of KeyPress events.
You can create a class to keep track of the last key combination that was pressed in ProcessCmdKey. If that particular combination does not match a mapped command but it is the first element of a sequence you can store it in your class. Then the next time ProcessCmdKey is activated check your new KeyPressTracker class to determine if a sequence has been started. If it has then check if the newly pressed key combination is the second element of one you specify. Please see the pseudocode example below:
Step 1: ProcessCmdKey is activated. The key combination is Ctrl+R, this does not match a command that you want to process but it is the first element of a sequence that you want to use (Ctrl+R+M).
Step 2: Store this key-press in a new class you created to keep track of the last key-press.
KeyPressTracker.Store(KeyCode, Modifiers);
Step 3: ProcessCmdKey is activated a second time. This time, the key combination is Ctrl+M which is not a key-press we're looking for but is the second element of a sequence. We check the last stored keypress using the new KeyPressTracker class. This will allow you to match a "sequence" such as Ctrl+R and Ctrl+M.
var lastKeyPress = KeyPressTracker.GetLastKeyPress();
if (lastKeyPress == "Ctrl+R" && currentKeyPress == "Ctrl+M")
{
// Show Refactor dialog
}
I was trying to test whether the Alt key was pressed.
I had a check similar to:
private void ProcessCmdKey(Keys keyData)
{
if (keyData == Keys.Alt)
{
System.Console.WriteLine ("Alt Key Pressed");
}
}
Anyways needless to say when I breakpointed when I had pressed the Alt key the debugger told me the key that was pressed was actually Keys.RButton | Keys.ShiftKey | Keys.Alt
Can anyone shed some light on what is going on or perhaps point me to an article that can explain?
Thanks
FZ
Edit:
I am still a bit lost as to why the ENUM would have have other bit values set and not simply the Alt key? I understand that the enum can include more than 1 state with the flags attrivbute but I am not sure why it does if all I pressed was Alt?
If you want to test whether Alt is part of the pressed keys, you can perform a bitwise test;
if((keyData & Keys.Alt) == Keys.Alt) {...}
Keys is a Flags Enumeration. This means it can have more than one value at a given time. You should check it like so:
if ( (keyData & Keys.Alt) == Keys.Alt)
{
// Alt was pressed!
}
Enum with FlagsAttribute are implemented using bits.
See this link for a good start - http://msdn.microsoft.com/en-us/library/cc138362.aspx
EDIT: Are you pressing RIGHT (mouse button) with Shift key during the operation, to select/highlight something, while debugging?
Mark's technique (the accepted answer) works for modifier keys, but it caught me by surprise that some keys (e.g. arrows) are combinations of bits, and won't work. For example the following test turns out to be true:
((Keys.Right & Keys.Left) == Keys.Left)
I have posted some useful little functions for key handling on a related StackOverflow post regarding arrow key handling.