Having the 0x100 bit set won't work with any Win32 functions; that's just AutoHotkey's method of encoding the "extended" flag, and allowing scan codes to be used to index into certain internal arrays.
Code: Select all
// MapVirtualKey() does *not* include 0xE0 in HIBYTE if key is extended. In case it ever
// does in the future (or if event.scanCode ever does), force sc to be an 8-bit value
// so that it's guaranteed consistent and to ensure it won't exceed SC_MAX (which might cause
// array indexes to be out-of-bounds). The 9th bit is later set to 1 if the key is extended:
sc &= 0xFF;
// Change sc to be extended if indicated. But avoid doing so for VK_RSHIFT, which is
// apparently considered extended by the API when it shouldn't be. Update: Well, it looks like
// VK_RSHIFT really is an extended key, at least on WinXP (and probably be extension on the other
// NT based OSes as well). What little info I could find on the 'net about this is contradictory,
// but it's clear that some things just don't work right if the non-extended scan code is sent. For
// example, the shift key will appear to get stuck down in the foreground app if the non-extended
// scan code is sent with VK_RSHIFT key-up event:
if ((event.flags & LLKHF_EXTENDED)) // && vk != VK_RSHIFT)
sc |= 0x100;
The SC_ constants need to correspond to the values
sc can have after this point, within the keyboard hook.
In other words, the real scan code and extended-key flag are translated into an AutoHotkey-SC value, so when you call any Win32 function generally you need to translate the AutoHotkey-SC value back to a real scan code and extended-key flag (although sometimes you just need to discard the flag).
I don't see anything in SetModifierLRState that would be dependent on the scan code or extended-key flag.
I think at the hardware or driver level, scan codes are always 8-bit plus a possible 0xE0 prefix, but for the keyboard hook there are some exceptions:
Code: Select all
// The system injects events with these scan codes:
// - For Shift-up prior to a Numpad keydown or keyup if Numlock is on and Shift is down;
// e.g. to translate Shift+Numpad1 to unshifted-NumpadEnd.
// - For Shift-down prior to a non-Numpad keydown if a Numpad key is still held down
// after the above; e.g. for Shift+Numpad1+Esc.
// - For LCtrl generated by AltGr.
// Note that the system uses the normal scan codes (0x2A or 0x36) for Shift-down following
// the Numpad keyup if no other keys were pushed. Our hook filters out the second byte to
// simplify the code, so these values can only be found in KBDLLHOOKSTRUCT::scanCode.
// Find "fake shift-key events" for older and more detailed comments.
// Note that 0x0200 corresponds to SCANCODE_SIMULATED in kbd.h (DDK).
#define SC_FAKE_FLAG 0x200
#define SC_FAKE_LSHIFT 0x22A
#define SC_FAKE_RSHIFT 0x236 // This is the actual scancode received by the hook, excluding the 0x100 we add for "extended" keys.
// Testing with the KbdEdit Demo preview mode indicates that AltGr will send this SC
// even if the VK assigned to 0x1D is changed. It is a combination of SCANCODE_CTRL
// and SCANCODE_SIMULATED, which are defined in kbd.h (Windows DDK).
#define SC_FAKE_LCTRL 0x21D
You won't see these in KeyHistory because the hook code filters out the upper bytes early.
Also, VK_PACKET overloads the "scan code" field to contain a 16-bit character code.