You have to deal with Hebrew periods where they come up

by Michael S. Kaplan, published on 2010/12/27 07:01 -05:00, original URI:

Over in the Suggestion Box, Maurice asked:

Hi Michael,

while working on sending key input via scan codes to a different process (with possibly different keyboard layout) I found two behaviors I can't really explain. Maybe you can shed some light on these.

First, if the target window uses a Hebrew keyboad layout and I want to enter a '.' I get a ? (Final Tsadi). I've looked at the keyboard layout with MSKLC and found that the key with this character is assigned to VK_OEM_PERIOD and the '.' is actually VK_OEM_2. If I use VkKeyScanEx('.', hkl) I get VK_OEM_PERIOD which is the wrong value. Is there any way to get the correct value or do I have to handle this case myself?

The second problem I've encountered is that I can't seem to release the right shift key with SendInput when it's pressed on the physical keyboard. All characters will still be upper case but GetKeyState says neither shift key is pressed. Releasing the left shift, both control or alt keys works however. So what's so special about the right shift key?



Interesting couple of questions there....

If you look at the Hebrew keyboard layout, you'll see Maurice appears to be right:


Clearly U+002e, aka FULL STOP, aka PERIOD, is on VK_OEM_2.

So what is going on here?

Well, the important thing to keep in mind is that the Hebrew keyboard layout has SGCAPS support, so the CAPS LOCK changes everything.

MSKLC lets you look at this, so if you click on that CAPS LOCK checkbox and look at the layout:


So there are multiple places that the keyboard layout has U+002e in it, and one of them is indeed VK_OEM_PERIOD.

And as I originally said back in 2006 in What the %$#!* is wrong with VkKeyScan[Ex]?, when a character is on the keyboard more than once, VkKeyScan and VkKeyScanEx will grab the first one it finds based on the way the keyboard layout's data tables are organized/enumerated, and there iws no way to control if from those functions....

These two function just continue to suck and I know of no plans to fix them in any way that would make them suck less, unfortunately.

This also points to a general limitation in the architecture of the basic keyboards created by MSKLC/kbdutool/kbdtool -- you can't change the VK values when you move to alternate shift states, which is very inconvenient for cases like this when you will have a VK_OEM_PERIOD that may or may not be a period.

Now Maurice's second question is something I am not entirely sure about the repro scenario, but when calling SendInput with anything even remotely complicated (like left vs. right keys, etc.), you have to know when to |= in the KEYEVENTF_EXTENDEDKEY flag so it knows that it an extended scan key (for almost every real world case you would only use VK_SHIFT and you would not specify the right or left key).

I suspect that is what is going on here, though if that does not solve the problem then perhaps Maurice can provide more info on his repro scenario....

Maurice on 3 Jan 2011 1:48 AM:

Thanks for the clarification about VkKeyScan. Should have thought about checking the caps lock state. That also explains why I get the wrong key for ']'.

Now for my the second question. I'm working on a remote support software for which any local keypress should be translated to a similar key on the remote side if that key is available. It should also distinguish between left and right modifier keys because some programs may need that. Now there are two problems with this. If I want to, for example, enter a '#' and I have US layout on the local and German layout on the remote side the following happens: local: I press the right shift key, remote: the app does a SendInput for the right shift key, local: I press VK_3, remote: should send a VK_OEM_2 (or more precisely the scan code of that key), but first the right shift key has to be released which the app does. This works perfectly fine but I noticed that when I press the physical right shift key on the remote side releasing it via SendInput doesn't work. This is of course not a very likely scenario but I was curious if there's a reason behind it. I've checked if adding the extended flag changes anything but that doesn't seem to be the case. But I think I've found a solution to it. I was using MapVirtualKey to get the scan code of most keys, including the rshift key. If I change that to use the vkey code however it seems to work. Still don't know why though...

Michael S. Kaplan on 3 Jan 2011 2:50 AM:

Unfortunately there are not simple 1-to-1 mappings between all scan codes and virtual keys; the interactions between extended scan codes vs. non extended ones and also between function that strip those bits and those that do not make it impossible to assume you will be able to do a simple mapping that will catch all cases....

go to newer or older post, or back to index or month or day