Sending “ARROW KEY” key through serial port - c#

In the same way that the question Sending “ENTER” key through serial port
how can i send the "ARROW key" through the serial port? Most particuly the UP arrow key.

Cursor keys are a relatively new feature of keyboards. They didn't yet exist at the time the ASCII codes were chosen. Which was largely based on the capabilities of teletypes that were used at that time. Like the widely used ASR-33, its keyboard layout looked like this:
No cursor keys. Note how line-feed was a separate key back then, '\n' in ASCII. Easier to get to and affecting the choice for the line-end control character in Unix. The Return key was the equivalent of the Enter key on a modern keyboard, '\r' in ASCII.
So there are no standard codes to pick for the cursor keys. You'll have to encode them yourself. ANSI escape codes were a common standard. Emulation of the DEC VT-52 and VT-100 were very common as well.

Since ARROW keys are scan codes (not defined in ASCII table), it is necessary to send a sequence of bytes to represent arrow keys (See https://en.wikipedia.org/wiki/ANSI_escape_code for details). Unfortunately, this sequence may vary between different platforms and targets, so you need to experiment for what is correct for your target.
Tested on a Ubuntu 16.04 target from a serial console on Windows, the ARROW UP sequence is three bytes (0x1b, 0x5b, 0x41), or on keyboard: ‘Esc’ ‘[‘ ‘A’

Related

c# SendKeys.SendWait function, send numpad digits

so I was working on an application which supposed executes digit keys for another application which isn't made by me, this application only supports numpad digits and it doesn't support the digits below F1-12s so whenever I execute "{number}" or just "number" ex:
SendKeys.SendWait("{1}");
or
SendKeys.SendWait("1");
just simple nothing happens, any one got idea on how to send number as numpad digit?
I've found my answer on this topic
How to simulate a Ctrl A + Ctrl C using keybd_event
here's the area to find keys:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx

Translating Windows.forms.Keys to real local keyboard value

I use the namespace Windows.Forms.Keys
I would like to be able to catch and use some special like characters like é,è,à,ç, but when the program fire the event KeyDown, the KeyEventArg just return me the value "D1" to "D9".
What could I do to get the real char associated to these keys ?
Short answer: use KeyPress instead of KeyDown.
KeyDown is really designed to work with the physical layout of the keyboard (well, the logical layout of the physica... forget it :D). This is very different from the character that given physical key represents.
On the other hand KeyPress is all about characters being input from the keyboard, rather than keys being pressed, really. Note how KeyPress supports features like AltGr + someKey and char repetition etc.
If you really need to use KeyDown/KeyUp, you'll have to emulate the way windows keyboard system works to determine the char to output (for example, if you're making a keyboard mapping screen for a game or something like that). You can use the ToAscii WinAPI method (https://msdn.microsoft.com/en-us/library/ms646316.aspx).
Apart from that, you still have to understand the meaning of the key combinations - for example, on my keyboard, if I press 1, I get +. If I press Shift+1, I get 1. If I press AltGr + 1, I get !. Which of those do you care about? Maybe Shift + 1 should be interpreted as 1 (what KeyPress does). Maybe it should be interpreted as Shift + 1 (the easiest, you already have that). And maybe it should be interpreted as Shift + +, the way it's usually used for hotkey bindings or keyboard mappings in games.
It should be pretty obvious by now that this is actually far from trivial. You need some mechanism to interpret the "raw" input data - and different interpretations make different sense for different initial conditions. You're basically asking for a mixed approach between the two obvious options - you're mixing virtual keys and "real" characters.

SendInput function handled in notepad/wordpad as if CTRL modifier is down

BACKGROUND:
I am writing a 32 bit WPF (C#) application which functions as an on-screen keyboard. It publishes the selected key strokes to the focused window as if physical keys had been pressed, exactly as the Microsoft On-Screen Keyboard, OSK.exe behaves.
PROBLEM:
I was using the InputSimulator library with some success (code here: InputSimulator class which builds the INPUT array), but found that certain key strokes were not being recognised by Notepad as expected, e.g. the arrow keys were behaving as if CTRL was being held down. Similarly, the WIN key was not working as expected, which could also be explained if Windows was treating the input as Ctrl+Win.
ATTEMPTED SOLUTION:
I ported the InputSimulator source into my project and made some modifications to how keystrokes are sent to SendInput, based on the calls to SendInput that OSK.exe sends (captured using API Monitor). The key differences I observed (and replicated in my code) for a KeyDown/KeyUp are:
InputSimulator passes a Keycode, and an ExtendedKey flag (if the key is extended), plus the KeyUp flag when releasing the key.
OSK adds the key's Scancode, and the ScanCode flag for the majority of keys.
OSK also has some other differences; individual keys where the KeyCode is not passed at all, where the ScanCode is not passed at all, and differences in which keys require the ExtendedKey flag.
The result of my changing the code to replicate how OSK calls SendInput was that even more keys now behave as if CTRL is being detected by my target/focussed application (typically Notepad or Wordpad). However, from direct comparison of my app and OSK in API Monitor I believe that my calls to SendInput are identical to OSK's calls.
N.B. OSK works flawlessly on my Windows 8.1 (64 bit) laptop.
ISOLATED PROBLEM SPACE:
To minimise the problem space I simulated a single key down/key up combination of the 'S' key from my application on a newly restarted PC (so that I can be sure the key down states were not contaminated from previous runs or physical key strokes). The target was Notepad and then WordPad - both reacted by opening the 'Save As' dialog, suggesting that they had interpreted my keystrokes as CTRL+S. API Monitor detected only 2 calls to SendInput (the KeyDown and then KeyUp), and these calls matched the same experiment using OSK. Here is the log;
2014-12-10 21:29:54,650 Calling native method SendInput with params:
nInputs:1
pInputs[0]:
Type:1(Keyboard)
Data:
MOUSEINPUT:
X:2031699
Y:8
MouseData:0
Flags:0 ()
Time:0
KEYBDINPUT:
KeyCode:83(VK_S)
Scan:31
Flags:8 (KEYEVENTF_SCANCODE)
Time:0
ExtraInfo:0
HARDWAREINPUT:
Msg:2031699
ParamL:8
ParamH:0
cbSize:28
2014-12-10 21:29:54,651 Calling native method SendInput with params:
nInputs:1
pInputs[0]:
Type:1(Keyboard)
Data:
MOUSEINPUT:
X:2031699
Y:10
MouseData:0
Flags:0 ()
Time:0
KEYBDINPUT:
KeyCode:83(VK_S)
Scan:31
Flags:10 (KEYEVENTF_KEYUP | KEYEVENTF_SCANCODE)
Time:0
ExtraInfo:0
HARDWAREINPUT:
Msg:2031699
ParamL:10
ParamH:0
cbSize:28
The only noticeable difference is that OSK passes the cbSize param as 40, which I cannot fake (the call fails if I manually pass 40). My size is 28, which I get by passing the below. I have no idea why the sizes differ as my structure definitions match the MSDN documentation (I have not modified these from the original InputSimulator code).
var cbSize = Marshal.SizeOf(typeof (INPUT));
OTHER ATTEMPTED FIXES:
I have tried leaving the VirtualCode param blank (0) when a ScanCode (and ScanCode flag) are specified, but this does not change the result. Idea from here: SO question
I have tried adding a trailing call to keybd_event, but this does not change the result. Idea from here: MSDN thread
(keybd_event(0x41, 0, 0, 0);)
I have tried adding a thread sleep between each call to SendInput, i.e. a delay between the KeyDown and KeyUp calls.
I have modified my structs and winapi function definitions to match PINVOKE.net
I have recompiled my application as 64 bit (on my 64 bit machine) - this corrected the cbSize to 40, but did not change the behaviour.
Any help would be GREATLY appreciated. Also any suggestions regarding other debugging tools I could use? I have attempted to debug all Keyboard functions which OSK may be calling (to detect other calls to keybd_event, for example), but none are logged besides the calls to SendInput.
Right, so the issue was PEBCAK.
I missed the most obvious thing imaginable - the trigger signal that I have been using while testing (i.e. the signal to say that I want to press the currently focused an on-screen key) is the left CTRL key. I've been pressing the CTRL key and then wondering why Windows thinks the CTRL key is pressed. Shoot me now.
I've been using it for so long, and have been so focused on the details of the potentially misbehaving WinAPI calls that I missed the most obvious cause.
I will leave this here to remind myself to use Occam's Razor.
Some of the debugging journey above may be useful to someone; my altered version of the InputSimulator code works fine, as does the original, unaltered code.

vb.net or c#.net console.readkey shift+number chars

I've been having some trouble getting the correct code for incoming keystrokes on the console for shift+number characters. For example, using:
cki = Console.ReadKey(True)
Console.WriteLine("You pressed the '{0}' key.", cki.Key)
If I press shift+2, I'm hoping to get the ascii 64 (for the '#' character), but instead I get 50 (for the '2' character).
Now, I know you can get the modifiers for the key pressed, but that would mean I'd have to program all the special cases for keys like that, and that doesn't seem right.
I need this function, or something like unto it, because of its ability to read keys as they are pressed, without the need to press enter, otherwise I'd just use console.read. Surely I've missed something. Could anyone tell me what it is I've missed?
You're looking for the KeyChar property, which returns the actual character rather than the physical key pressed.
You may want to cast it to int.
It is pretty important to distinguish between keys and characters. The key is the same anywhere in the world, the one on the top row at the left. You can rely on that key always producing ConsoleKey.D2
The character is however very different, it greatly depends on the active keyboard layout. A Northern American user presses Shift+2. A French user presses AltGr+0. A German user presses AltGr+Q. A Spanish user presses AltGr+2. Etcetera.
If you care only about the key then use ConsoleKeyInfo.Key, you do so for all non-typing keys like the function keys for example. Perhaps the typical gaming WASD keys. If you care only about the character, like #, then use ConsoleKeyInfo.KeyChar.

ConsoleKeyInfo, the Question Mark and Portability

I have a little C# console application that reads a key and checks to see if the key was a question mark:
ConsoleKeyInfo ki = System.Console.ReadKey();
if (ki.ConsoleKey.Oem2) // Do something
I arrived at Oem2 by seeing what value is actually assigned in the debugger, because there is no ConsoleKey code for question mark.
Now I could certainly use ki.KeyChar instead, but the application also needs to respond to certain keys (e.g. media keys) that do not map to characters. It feels inelegant to check both ConsoleKey and KeyChar to determine which key has in fact been pressed. On the other hand, it does not feel safe to rely on Oem2 to always map to ? in all circumstances and regions.
Is it best practice to check both properties to determine which key was in fact pressed?
Any insight into why ConsoleKeyInfo was designed this way is appreciated.
In this case, you will have to check KeyChar == '?'. From MSDN:
Oem2: The OEM 2 key (OEM specific).
So you're just getting lucky in that it happens to be a ? on your equipment.
The ConsoleKeyInfo structure provides KeyChar (a Char value) as well as Modifiers (an enumeration) to help you decide what keys the user had pressed.
I think you should consider what happens when someone has different keyboard layout.
If you want to check for “the key with question mark on my computer”, then use ConsoleKey. But that's probably not a good idea and you should probably adhere to the user's settings and use KeyChar.
But for keys that don't map to to characters (and the user can't remap them by using different keyboard layout), you have to use ConsoleKey.
So, yes, I think you should check both properties in this case.
I guess the reason for this design is that Console.ReadKey() relies on a native function (ReadConsoleInput) that returns an array of KEY_EVENT_RECORD structures in case of a keypress, where each key event has an ASCII/Unicode character representation and a virtual key code. Notice the VK_OEM_2 in my previous link - this is where the ConsoleKey.Oem2 value comes from.

Categories