1

SCENARIO

I wrote a simple method that acts as a wrapper of PostMessage function to send keystrokes to a non-active window. This method takes a virtual-key code as one of its parameters.

PROBLEM

Theorycally, modifier keys and extended keys can't be sent through this function (as commented by many professional programmers, for example this comment by @Hans Passant), so, I would like to programmatically determine whether the virtual-key code argument that my method receives it belongs to a "normal" key, a modifier key or a extended key, this way I would be able to treat these last two key types with keybd_event or SendInput function instead of PostMessage.

QUESTION

How can achieve this in C# or VB.NET?. I always could write a small if or switch to detect the modifier keys because they are only few, but I can't find any Win32 function that can tell me whether a virtual-key code is a extended key or isn't.

To be honest, I don't know exactly what "extended" key stands for, the only information I found about this terminology is on WM_KEYDOWN / WM_KEYUP docs, where it says something very superficially:

an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard.

ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
  • 1
    An extended key is one of the extra keys on an extended (also known as _enhanced_) keyboard. These are keys like RCTRL, RALT, Insert, Delete, Num Lock, etc. I've worked a bit with simulating keyboard input myself, but I don't think I've heard of a built-in way to check for extended keys. I think an `If` statement would be the best way to go... By the way have you seen this: [Extended-Key Flag - About Keyboard Input](https://learn.microsoft.com/en-us/windows/desktop/inputdev/about-keyboard-input#extended-key-flag)? – Visual Vincent Jan 12 '19 at 14:47
  • If you're using `ProcessCmdKey` to trap the Message on `WM_KEYDOWN`, test `lParam` with `bool IsExtended = ((int)msg.LParam & 0x1000000) > 0;`. You might have *disagreements* with some keys, ALT GR, for example. You might want to also trap `WM_SYSCOMMAND`. – Jimi Jan 12 '19 at 16:26

2 Answers2

1

AFAIK, modifier keys on PC keyboards that have VK constants are the Control, Alt, Shift, and Windows keys.

Extended keys aren't properly documented anywhere, but testing confirms that, aside from the ones listed here:

ALT and CTRL keys on the right-hand side of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad; the NUM LOCK key; the BREAK (CTRL+PAUSE) key; the PRINT SCRN key; and the divide (/) and ENTER keys in the numeric keypad

they are VK_APPS, VK_LWIN, VK_RWIN, VK_BROWSER_*, VK_VOLUME_*, VK_MEDIA_*, and VK_LAUNCH_*.

1

Windows and IBM PC has a long history which caused the inconsistency in many aspects of the APIs...

Scan codes can be extended. It means that scan code value has 0xE0 or 0xE1 as a prefix byte.

You can detect if scan code mapped to VK_ code is extended by a MapVirtualKey call with MAPVK_VK_TO_VSC_EX flag (available since Windows Vista) and check returned value for a prefix byte.

So in result for SendInput you can do something like this:

WORD scanCode = LOWORD(MapVirtualKey(vk, MAPVK_VK_TO_VSC_EX));

INPUT input = {};
input.type = INPUT_KEYBOARD;
input.ki.wVk = vk;
input.ki.wScan = LOBYTE(scanCode);
input.ki.dwFlags = (HIBYTE(scanCode) & 0xE0) != 0 ? KEYEVENTF_EXTENDEDKEY : 0;

SendInput(1, &input, sizeof(INPUT));

PS: If you really wonder the full list of such VK codes - look at the US keyboard layout file code for keys with a KBDEXT flag. But be aware that it is for US keyboard layout only and things may be different on other keyboard layouts. Yes, this stuff is messed up.

DJm00n
  • 1,083
  • 5
  • 18