Question

Trying to define a CTRL-\ (Backslash) keybinding for our WPF command, but we're running into two issues:

  1. There isn't any pre-defined constant for the backslash key, only OemBackslash, and

  2. There doesn't seem to be a consistent numeric code for OemBackslash either

For instance, a Dell returns a different value for e.Key if you're on a Dell vs. if you're booted into Windows on a Mac. Yet both do correctly type a backslash.

The thing that frustrates me is rather than going on what those codes map to in the driver--i.e. what's actually on the key face--MS based their keyboard shortcuts on the key code, which as explained above, isn't necessarily consistent.

My thought was instead of using the key bindings, to use the PreviewKeyDown event, then inspect the key code, somehow pass it to the driver to determine what typed key that would represent (i.e. that driver would say keycode X represents the backslash key face) then use that value for our logic. However, I don't know how to go from KeyCode to key-face so to speak.

So... Thoughts on how to do/handle this?

Was it helpful?

Solution

EDIT

I highly suggest you to refrain yourself from scrolling down to the end of the edit, I know the keyboard picture is very tempting but read everything in order for a better experience :D

As I said, there is no point in absolutely trying, this method is unreliable so how can you expect something unreliable to work reliably ? There is absolutely no point in even trying to reverse-engineer a driver or decipher USB streams just for that, anyone sane would tell you this :D

Even you'd achieve any of these (which IMO is highly unsure), you'd have it done for a particular brand of keyboard. The other thing is the time factor, it's a huge waste of time for the outcome.

The closest thing to metal in C# I've found is this :

Using Raw Input from C# to handle multiple keyboards

RawInputProcess.RawKeyboard.ProcessRawInput calls GetRawInputData from User32 And even this low-level stuff does return 0xDC or 220 (i.e. the terrific Oem5). This calls VirtualKeyCorrection which corrects some keys, you could do something there though it's pretty ugly as well and as unreliable as it can be.

Additionally, there's a bunch of links about HID libraries here

My definitive answer :

You absolutely want to be able to bind ?

And there you will have your default binding to Ctrl+\.

Now a bit of history and something you probably haven't caught yet !

If you closely look at the MSDN docs -> Keys Enumeration

OemBackslash

The OEM angle bracket or backslash key on the RT 102 key keyboard (Windows 2000 or later).

I'm pretty sure you know this thing but did not even pay attention to it.

enter image description here

enter image description here

I've personally been playing with it on an IBM XT clone back in '86 when I was 5.

Now you're probably starting to understand but I'll just make it crystal clear :

The OemBackslash is a vestige from the 80's pretty much like many other things in Windows (though most if not all have been removed in current versions)

So unless you do have one of these keyboards, you will never receive this KeyCode !

I cannot be 100% certain unless someone tests the RT-102 with a DIN to PS/2 adapter under 2000/XP, it'd be interesting to see the result; but what makes me confident in saying this is, 1st the docs, 2nd generally people at Microsoft know what they do, they wrote that thing. I would eat my hat if this came to be false.

I hope you will be satisfied with my edit and finally mourn OemBackslash, I perfectly understand your desire of seeing such thing on your screen but nothing is perfect, especially in computing. I gave you a pseudo workaround which is literally equivalent, give it a try !

Credits for the pictures goes to :


I've been reading your previous question, I'd tell you as Hans said: not a good idea to bind to it because it won't necessarily be a backslash.

For example in the French keyboard to get the backslash you have to press AltGr and 8, AltGris nothing more than Alt+Ctrl which implies additionally pressing Alt for this layout to execute your command.

http://en.wikipedia.org/wiki/AltGr_key

In short this shortcut is unreliable as it is not constant according layout and/or manufacturer.

In WPF there is KeyInterop.VirtualKeyFromKey but it returns Oem5 as well :(

Looking at the docs give the definitive answer : Virtual-Key Codes

VK_OEM_5
0xDC
Used for miscellaneous characters; it can vary by keyboard.
For the US standard keyboard, the '\|' key

But here's a solution :D

Hitting \ will bring Oem5 but by sending an event to a TextBox for instance your system will do all the magic to transform it to a \. You can then grab the TextBox.Text and act accordingly depending the key that's been typed along with the modifiers.

enter image description here

private bool _done;
private void MainWindow_OnKeyDown(object sender, KeyEventArgs e)
{
    if (_done) return;
    _done = true;

    var presentationSource = PresentationSource.FromDependencyObject(this);
    var keyEventArgs = new KeyEventArgs(Keyboard.PrimaryDevice, presentationSource, 0, e.Key)
    {
        RoutedEvent = KeyDownEvent
    };
    TextBox1.Focus();
    TextBox1.RaiseEvent(keyEventArgs);
}

private void TextBox1_OnTextChanged(object sender, TextChangedEventArgs e)
{
    var text = TextBox1.Text;
}

NOTE 1 : the boolean is here to prevent a StackOverflow :D

NOTE 2 : this is probably as unreliable as the key is, what if the user has Shift on ? I didn't try

This is just a proof on concept that it is possible but personally I would not take this path, it's too ugly IMO; I'd rather allow the user to map commands to whatever gesture he wishes. And obviously not allow him to bind to \ :)

EDIT

I have an MS keyboard and there is mskey.exe that allows to diagnose your keyboard :

enter image description here

It does import HID.DLL functions such as HidP_GetValueCaps so you might be able to achieve this in a cleaner manner through some P/Invoke but it seems a lot of work though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top