Is there a way of mapping a key combination of a computer type a character?

M keyboard key "h" as failed to work and I want to be able to override any key combination to be able type it. In the meantime.

An example would be

Alt+P to return h and maybe
Alt+shift+h to return H

Solution 1:

Keyboard Remapping

The value Scancode Map at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout allows keys to behave as if another key (or no key) have been pressed. It is normally not present.

This structure maps one key to another (or to no key).

To read what is set: Each pair of characters is a byte. Each 4 pairs of characters is a dword (32 bit). The first dword is a header and is all zeros. The second dword is flags and is generally all zeros. The third dword is the number of remaped keys plus one. Each remapped key is one dword. The first word (two pairs of characters) of these dwords is what the key will do and the second word is what key to remap (the first word will be zeros to disable the key) . Finally there is a dword of zeros (why the number of remapped keys recorded is the number plus one).

Intel processors store numbers in byte order reversed. In the third dword which is the number of remapped keys a number of two would be stored as 02,00,00,00. Dwords are read in pairs of characters from right to left. However the dwords themselves, rather than the bytes in a dword, are in conventional order - first to last.

"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,43,00,1d,00,00,00,00,00

To decode the above entry, which swaps the F9 key with the Left Control key, break it up into dwords.

00,00,00,00, (Header)
00,00,00,00, (Flags)
02,00,00,00, (Number of records of remapped keys and the end marker)
43,00,1d,00, (Record 1 - second key - Left Control (001d) becomes first key - F9 (0043) and vice versa)
00,00,00,00  (End Marker)

Another example is to disable both Windows keys.

"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,00,00,5B,E0,00,00,5C,E0,00,00,00,00

To decode the above entry.

00,00,00,00, (Header)
00,00,00,00, (Flags)
03,00,00,00, (Number of records of remapped keys and the end marker)
00,00,5B,E0, (Record 1 - second key - Left Winkey (e05b) becomes first key which is nothing (0000))
00,00,5C,E0, (Record 2 - second key - Right Winkey (e05c) becomes first key which is nothing (0000))
00,00,00,00, (End Marker)

As the early keyboards didn't have all the keys on a modern keyboard there are two ways of expressing scan codes, normal and extended. Normal is one byte which we pad out with leading zeros to a word (2 bytes). Extended are two bytes and for this purpose are the scan codes starting with E0. Others which aren't relevent in this context start with 00. E0 or 00 tell a program to reread from the keyboard when the code will be available. Single keys all start with E0. They are basically the cursor keys, right hand side modifier keys Control and Alt, and F11/F12. These keys were not on the original keyboard. One moved the cursor with the number pad. References to grey keys are to the number pad as once number pad keys were grey and other keys beige.

Esc 1   0x1
1 or !  2   0x2
2 or @  3   0x3
3 or #  4   0x4
4 or $  5   0x5
5 or %  6   0x6
6 or ^  7   0x7
7 or &  8   0x8
8 or *  9   0x9
9 or (  10  0xa
0 or )  11  0xb
- or _  12  0xc
= or +  13  0xd
Bksp    14  0xe
Tab 15  0xf
Q   16  0x10
W   17  0x11
E   18  0x12
R   19  0x13
T   20  0x14
Y   21  0x15
U   22  0x16
I   23  0x17
O   24  0x18
P   25  0x19
[ or {  26  0x1a
] or }  27  0x1b
Enter   28  0x1c
Left Ctrl   29  0x1d
A   30  0x1e
S   31  0x1f
D   32  0x20
F   33  0x21
G   34  0x22
H   35  0x23
J   36  0x24
K   37  0x25
L   38  0x26
; or :  39  0x27
' or "  40  0x28
` or ~  41  0x29
Left Shift  42  0x2a
\ or |  43  0x2b
Z   44  0x2c
X   45  0x2d
C   46  0x2e
V   47  0x2f
B   48  0x30
N   49  0x31
M   50  0x32
, or <  51  0x33
. or >  52  0x34
/ or ?  53  0x35
Right Shift 54  0x36
Prtsc
This is a special case  55  0x37
Left Alt    56  0x38
Space   57  0x39
Caps Lock   58  0x3a
F1  59  0x3b
F2  60  0x3c
F3  61  0x3d
F4  62  0x3e
F5  63  0x3f
F6  64  0x40
F7  65  0x41
F8  66  0x42
F9  67  0x43
F10 68  0x44
Num Lock    69  0x45
Scroll Lock 70  0x46
Home (Number Pad)   71  0x47
Up Arrow (Number Pad)   72  0x48
Pgup (Number Pad)   73  0x49
Grey - (Number Pad) 74  0x4a
Left Arrow (Number Pad) 75  0x4b
Center (The 5 key on the number pad?)   76  0x4c
Right Arrow (Number Pad)    77  0x4d
Grey + (Number Pad) 78  0x4e
End (Number Pad)    79  0x4f
Down Arrow (Number Pad) 80  0x50
Pgdn (Number Pad)   81  0x51
Ins (Number Pad)    82  0x52
Del (Number Pad)    83  0x53
Enter (Number Pad)  57372   0xe01c
Right Ctrl  57373   0xe01d
Grey / (Number Pad) 57397   0xe035
Right Alt   57400   0xe038
Home    57415   0xe047
Up Arrow    57416   0xe048
Pgup    57417   0xe049
Left Arrow  57419   0xe04b
Right Arrow 57421   0xe04d
End 57423   0xe04f
Down Arrow  57424   0xe050
Pgdn    57425   0xe051
Ins 57426   0xe052
Del 57427   0xe053
F11 57431   0xe057
F12 57432   0xe058
Left Winkey 57435   0xe05b
Right Winkey    57436   0xe05c

Note: Programs use 16 bit values to either represent positive numbers (0 to 65 536) or positive and negative numbers (-32 768 to 32 787). For the larger numbers in the list I've assumed them to be unsigned integers as this is likely what most other programs will treat them as. Some programming languages only support signed integers. To convert subtract the number in the table from 65 536 and make it a negative. E.G. The Right Winkey is 57 436. 65 536 - 57 436 = 8100 then make it a negative, -8100.

These codes date from Dos so I call them integers as MS-Dos was 16 bit. However an integer equals the processor size so an integer in Windows is 32 bit (approx 0 to 4 billion or -2 billion to 2 billion).