How to detect Ctrl+Shift+Numeric Keypad in WinForms application - c#

I would like to be able to allow users of my application to press Ctrl+Shift+numeric keypad keys to act as a navigational shortcut in an application I am developing. To my surprise it appears to be impossible to recognise this key combination.
Pressing Shift+keypad activates the extended functions displayed on most keyboards, such as cursor keys (on 2, 4, 6 and 8), page down/up (on 3 and 9), end/home (on 1 and 7), etc.
The various key events in WinForms report these exactly as if they were the actual cursor keys etc. being pressed. I'm therefore unable to distinguish between e.g. Shift+KeyPad4 and CursorLeft. I can't simply look for Ctrl+CursorLeft instead of Ctrl+Shift+KeyPad4, as people may be using Ctrl+CursorLeft for text editing purposes.
Is there any way I can properly detect these shifted numeric keypad keyboard combinations?
Thanks!

Use a class to keep track of what keys are pressed.
When you receive an OnKeyDown event, store that key as down and then when you come to When you receive an OnKeyUp event, remove that key from the store.
Then on the same OnKeyDown event, after storing the key press, do a check to see if all three keys that you expect are down.
It would look something like so:
public void OnKeyDown(EventArgs ...) {
_keyStore.KeyDown(eventArgs.keyPress);
if(_keyStore.AltCtrlKeyPad4IsDown()) { //Abstract this so you can perform multiple checks.
//Do shortcut.
}
}
public void OnKeyUp(EventArgs ...) {
_keyStore.KeyUp(eventArgs.keyPress);
}
Note that this is sudo code and will not compile.

Related

Custom OSK: Listen to TextBox Focus

I have written a custom OnScreen Keyboard as an UserControl to have a better control over what the user can type (Alphanumeric/Numpad/Navigation Keys - stuff like that) and to have a better control over the screen layout at design time.
The OSK works by manipulating the text- and selection-properties/functions of a textbox-control.
My main Problem is how to find the right TextBox to inject text into.
My first, naive approach was to register every TextBox I want to use with the OSK Control manually and use the GotFocus/LostFocus of those registered TextBoxes to determine the active control:
public void RegisterInput(TextBox text) {
if (!_listeners.ContainsKey(text)) {
_listeners.Add(text, modes);
text.GotFocus += Input_OnGotFocus;
text.LostFocus += Input_OnLostFocus;
}
}
private void Input_OnLostFocus(object sender, RoutedEventArgs routedEventArgs) {
if (_focused == sender) {
_focused = null;
IsEnabled = false;
UpdateKeyboardMode(); // << Updates Keyboard layout (Alphanumerical vs Numpad) based on focused control
}
}
private void Input_OnGotFocus(object sender, RoutedEventArgs routedEventArgs) {
_focused = (TextBox) sender;
IsEnabled = true;
UpdateKeyboardMode();
Bindings.Update();
}
I work with Focus here, because I need to determine which kind of keyboard (full-size alphanumerical vs. short numpad) to display for each TextBox. The _focused TextBox is then used to directly inject the pressed keys into it. In the constructor of my Page which also contains the OSK-control I would call RegisterInput() with a reference of each and every TextBox I defined on the page. This works just fine — if I have those references.
But now I am working with UserControls. That also removes the TextBoxes out of reach for direct referencing, but I could write some kind of VisualTree-Scan after InitializeComponent() to find all references and call RegisterInput() on each reference I found. If I only need to do this once, it isn't a problem (altough it is still ugly).
One step further - ListBoxes with dynamicly changing contents and DataTemplates. Now I'd need to rescan the whole VisualTree explicitly everytime something changes. But how to detect those changes?
The question is: Can I get an event as soon as $any element in my VisualTree gets/looses focus, without knowing all those elements beforehand (thus replacing RegisterInput() completely)? Or can I listen to changes to the VisualTree to rescan all controls and then call RegisterInput() manually for every TextBox I found?
The goal is to get a handler called everytime a GetFocus/LostFocus event on any TextBox/Control in the UI is raised so that I can update the keyboard to either display a full-sized alphanumerical keyboard (for default textboxes) or a shortened numpad (e.g. for textboxes bound to numerical backing fields).
Alternatively: Is there any other way to inject text and call UpdateKeyboardMode() to update the keyboard layout as soon as the selected textbox changes?
Other options I thought about include:
Build a custom control which derives from a TextBox and let it register itself to the OSK. I'll probably resort to this method, if I don't find any better way. But this will destroy support for 3rd party libraries in which my control is not present and thus does not use the "special magical textbox with osk support".
Don't use events at all. Get the currently focused TextBox with the FocusManager as soon as the user presses a key on my OSK and inject text into the focused instance. Problem with this approach is, that it completely destroys the capability to adapt the OSK to different input types (alphanumerical vs only Numpad), because I cannot determine the keyboard type I need before pressing a key.
Rescan the VisualTree with a timer. Won't do that, thats simply too much of a hack.
Use the OnScreen-Keyboard supplied by Win10 IoT. Two problems: It has no designtime support and is displayed above elements, even if the focused element is directly underneath the keyboard (acceptable if neccessary), but I don't know of a way to change the keyboard "layout" between a full-sized alphanumeric keyboard and a shortened Numpad which only contains numbers and some keys. Also it does not allow to use custom keys (e.g. arrow keys for navigation, custom return key handling).
After a discussion in the chat forum, the actual problem isn't to create a Custom OSK control and use that to interact with the TextBoxs but instead, it's "being bound to use custom control" wrapping a textbox everywhere a OSK needs to be shown.
The Solution would be to listen to the OS-OSK events and when they are triggered, pop up the Custom OSK this ways you won't have to wrap a Textbox in a user control and use that throughout your project.
Link to the Documentation: - respond to the presence of the touch keyboard

perform a hotkey when press a graphical button

I got a thought experiment with a graphical user interface for writing a command.
There are buttons for saving, writing cursive and so on.....
Now when i press the button save, i want to that the compiler perform Ctrl+S like in every textdocument, or change the marked one to cursive with Ctrl+Shift+K.
I tried to set the variable to the value of the ascii code, but this ain´t worked. Now i need help that the compiler perform the hotkey.
Is there a function in C# or is there another way to realize that.
Actually those hotkeys are implemented functions of the programs you use (e.g. word). The hotkey just executes the same function as the button you can press - the compiler doesn't know the hotkey Ctrl+Shift+K.
Just think about it: If the compiler knew about those hotkeys, it would have to know how to make the selected text in the focused textbox cursive - wouldn't this be kind of strange?
I might misunderstand your question, maybe you just wanted to ask how to type text with a simulated keyboard for the form, because you already implemented the shortcut functionability. In that case you'd have two options:
Call the function called when you press the specified shortcut
Actually simulate keypresses to the form
The second one is done like that:
SendKeys.Send("^S"); //For Ctrl+S - ^ is the Control button
For other special keys with the SendKeys function take a look at this: https://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx.

How to make another Key acting like Enter

my question is kinda simple but I didn't find any answer.
I have a WPF application and I want to remap the behaviour of Tab and Enter keys onto other keys, because I need them to be close on the keyboard.
I already managed to make a letter key (for example J) acting like Tab Key, but I can't find a way to make a close button (for example K or H) acting like Enter!
For instance, I need this because the application works only with keyboard, so when an element (for example a button) has focus, I would like to press K or H to act like Enter key and do something. All works fine if I press the real Enter key but as I said, I would like to remap this function to another Key.
Is this possible? If so, how to do it in a WPF application?

C# Programmatically send two keys when you are already pressing another one

I'm making my own multiple clipboard copy/paste tool which runs in background, and I've finally achieved it, it's working.
this is how it works,
when Capslock it's pressed, if I press CTRL+1 I make a CTRL+C programmatically ( with SendKeys) and save the clipboard on my list with correct position
when capslock it's not pressed, if I press CTRL+1 I make a CTRL+V programmatically ( with send keys) by using the latest data in clipboard on the correct list position.
Now it's fine, but I want to make a little change, I don't want to use capslock, but I want to press another key, like ALT or SHIFT, but if you keep pressing a key which is not the CTRL and then you do a CTRL+C, it does not work.
Anyone have any advice to this dumb thing?
Thanks guy
If you don't mind using WinApi functions, you can use RegisterHotKey and UnregisterHotKey functions.
They allow you to register and unregister global shortcuts of your choice. This way you'll get notified about a shortcut being pressed even if your application is running in background and doesn't have the focus on itself.
You can find more information about both functions on pinvoke here and here. There is even some sample application code so you can see how to use them.
NOTE: Remember to unregister all the shortcuts that you've registered on application exit.
You can use a flag for the select key. When you check to see what keys are pressed then:
something like the following pseudo code should do the trick:
if(select key)
{
this.selectKey = true;
}
else
{
if(ctrl key)
{
//do whatever you would normally do here
}
this.selectKey = false;
}

Silverlight handling multiple key press combinations

I have a Silverlight application in which I catch certain key presses such as Tab or Ctrl to perform some action. However, I want to be able to handle multiple keys pressed at the same time such as Ctrl + R or something like that. Is there any way to do that in Silverlight, and if so, how?
Take a look at the ModifierKeys Enumeration to check for multiple key press combinations. See Silverlight Keyboard Support for code samples and more information.
void Canvas_KeyUp(object sender, KeyEventArgs e)
{
//check for the specific 'v' key, then check modifiers
if (e.Key==Key.V) {
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) {
//specific Ctrl+V action here
}
} // else ignore the keystroke
}
Handling key combinations like Cntrl+X is very problematic with Silverlight as your running in a browser which will, probably, use most Cntrl combinations itself. Then given that you probably need to support multiple browsers such as IE, Firefox, etc I recommend you give up.
Hence I limit Silverlight key combinations to shift only.

Categories