Community Pick: Many members of our community have endorsed this article.
Editor's Choice: This article has been selected by our editors as an exceptional contribution.

Keyboard Remapping: CAPSLOCK to Ctrl and Beyond

In this article, I'll describe how to make registry changes that will remap low-level keyboard scancodes and I'll also show you how to set/change the functions of the extended-function buttons and controls that may be on your keyboard.

I'm having to retrain myself on a new keyboard.  No big deal, right?  In my case, it is.  I've been using the same IBM 84-key PC/AT keyboard for over 25 years.  Those keyboards were built to last (and last, and last...).  Even on secondary computers, like the ones at work, I've always been able to find keyboards that were finger-memory-compatible, such as the NorthGate OmniKey which has the function keys on the left side, where God intended them.  In fact, when I heard that NorthGate was discontinuing that line in the mid 90's, I bought five of them.  Well those OmniKey keyboards all eventually died; the original IBM keyboard outlasted them all.  It had taken more abuse that you can imagine over the years, but it finally had one too many cups of coffee spilled on it.  So I had to switch to one of the half-dozen "new" keyboards that were gathering dust in a closet.

In short:  For common keystrokes such as Ctrl+C, Ctrl+V, I invariably hit CapsLock and it irritates me beyond belief.  Not only does the desired action not happen, but CapsLock turns on and the current selection is replaced by one letter.  Arrggggh!

Who among us has not hit that totally useless CapsLock key by accident?  In 35 years of keyboarding, I've had a need for the CapsLock key perhaps twice.  Among other irritations, it has caused endless tech-support grief relating to user-entry of passwords.  That key should have been moved away from the home row decades ago.  It's right next to the A key! Sheesh.

I first thought of just popping the key out and sticking a wad of chewing gum in there.  But I found a way to remap it -- make it into a clone of the Ctrl key.

Remapping CapsLock to be Ctrl

There is a little-known entry in the system registry that is checked by the lowest-level keyboard driver before the keystrokes get sent to the rest of the system:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout
           Scancode Map  REG_BINARY <binary data, in hex>

The Scancode Map value probably does not exist on your computer.  So it needs to be added.  The format is very specific.  First, I'll show an example, then I'll provide a full description.  Here's a .REG file that remaps CapsLock to Ctrl:
[step="" title="CapsLockToCtrl.REG"]
Windows Registry Editor Version 5.00
                      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
                      "Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00, 00,00,00,00

Open in new window

The hex data is in five groups of four bytes:
   00,00,00,00  -- header version (always 00000000)
   00,00,00,00  -- header flags (always 00000000)
   02,00,00,00  -- number of entries (including terminating NULL)
   1d,00,3a,00  -- map entry: desired scancode, key to remap
   00,00,00,00  -- NULL terminator

The desired scancode is "Left-Ctrl" (scancode 0x1d) and the key to remap is CapsLock (scancode 0x3a).

Just copy that text to a text file named, for instance, CapsLockToCtrl.REG, then double-click that file.  Note:  The change will not go into effect until you reboot.
Reassign CapsLock to be CtrlTo undo the change, just use RegEdit to drill down to that Keyboard Layout key and delete the Scancode Map entry.

Remapping Other Keys
First, I want to point out that most of the time it's unwise to make permanent changes to your keyboard mapping.  It's just not necessary because there are lots of programs that will let you set up macros so that a Shift-, Ctrl-, and/or Alt-key combination will make the computer take a desired action.  For instance, you can write a short program (one or two lines of script), create a shortcut to it, and edit the properties of that shortcut to assign it a keyboard combination.

This registry remapping technique is awkward, since it requires a reboot, and I only recommend it in unique situations (such as attempting to avoiding insanity or suicide if you hit CapsLock even one more time :-)

That, said...
If you want to map more than one key, then you need to change the third item (number of entries) to a higher value and include more of the map entry values.  Some scancodes are two bytes, with the lead-in byte being e0 or e1; this is usually used to distinguish keys that are duplicated; for instance, the R-Alt key is 0e,38.  But, as we will see, it also appears for dedicated keyboard buttons.

At the bottom of this article, I've included an image of a standard keyboard, followed by a scancode list.  You can use this registry technique to map any keys to any other.  

A few candidate useless keys you might consider remapping are:
   Caps Lock    3a
   Num Lock     45
   Scroll Lock    46
   R-Alt              e0,38
   R-Ctrl            e0,1d
   Num /            e0,35
   Num *           37
   Num 5          4c

If you want to make a key totally dead, set the desired scancode to 00,00.

AppCommand keys: Reprogramming Dedicated Buttons

Your keyboard may have a set of "dedicated" buttons that are designed to control multimedia devices.  For instance, mine has a bunch that let me set the volume, skip to the next track, etc.  These work regardless of what media player I use.  

I also have a set of buttons with labels like "Internet" "E-mail" "Search" and even one oddity named "Calculator."  In writing this article, I became curious about these keys.  It turns out that there is another section of the registry that defines what these keys do.  

    HKLM\ Software\ Microsoft\ Windows\ CurrentVersion\ Explorer\ AppKey \ num
    HKCU\ Software\ Microsoft\ Windows\ CurrentVersion\ Explorer\ AppKey \ num

The HKCU version affects the key-handling of only the current user, while the HKLM setting sets a default for all users.

You probably already have a set of these defined.  When I looked into that key, I saw:
...Explorer\Appkey -- sets actions for dedicated keyboard buttonsThe key numbers under AppKey are not scancodes, but don't worry, I'll provide a list of valid values.

Each of the AppKey\num entries can have just one item.  Its name decides what to do and its value must be set depending on that name.  For instance, in the figure above, the item name under AppKey number 18 is ShellExecute and the value is the command to execute.

Possible values for the item name are:

The value is any command that you can execute by typing in at a DOS prompt or in the Start / Run input box.  You can pass arguments to the program, but be sure to wrap the whole thing in quotes.  For instance,

    ShellExecute   REG_SZ "Notepad.Exe MyToDoList.Txt"
The value entry is a file extension or MIME type.  For instance, the item that's associated with my dedicated "Internet" button is:

    Association  REG_SZ http

The system will run whatever program is associated with that file type or MIME type.
It's not clear how this is (was?) supposed to work.  The example in the docs set the value to "mail" which would supposedly open up the application that is registered to handle mail.  However, in Vista and Win7, the value for AppKey 15 is association to "mailto" (a MIME handler). My thinking is that "RegisteredApp" must have been deprecated.  Another possibility:  The registry key HKLM\Software\Clients seems to provide a means for applications to register themselves as the "default app" for some things.  If you want to explore this, that's one direction to go (see this blog for some related information).  But since you can use ShellExecute to do most anything you want, it seems unnecessary.

Re-tasking the "Browser Favorites" Dedicated Button

That's one of the dedicated buttons that I never use, so  I thought I'd have it do something that might be handy:  Show the "3DFlip" that was a big deal in Vista, but since Win7 has the more functional Aero Peek, nobody talks much about anymore.

Anyway, the way to bring up 3DFlip is by executing this run command:

   Rundll32 dwmApi #105

To re-task my "Browser Favorites" button, I modified the registry like this:
Assign Appkey 6 to show the (well hidden) Flip3D toolAnd now when I press that button, I get something like this:
3D flip -- Yes, it's available in Win7Here's the .Reg script that sets the dedicated "Favorites" button so that it executes the 3DFlip:
[step="" title="FavsTo3dFlip.REG"]
Windows Registry Editor Version 5.00
                      "ShellExecute"="Rundll32 dwmApi #105"

Open in new window

Notice that I reassigned AppKey 6... which would be a mystery (why 6?) except that I found that these AppKey values correspond to WM_APPCOMMAND message parameter values in a Windows programming header file.  Here's the entire list:

AppCommand values from Winuser.h
   1  APPCOMMAND_BROWSER_BACKWARD                    
                         2  APPCOMMAND_BROWSER_FORWARD                     
                         3  APPCOMMAND_BROWSER_REFRESH                     
                         4  APPCOMMAND_BROWSER_STOP                        
                         5  APPCOMMAND_BROWSER_SEARCH                      
                         6  APPCOMMAND_BROWSER_FAVORITES                   
                         7  APPCOMMAND_BROWSER_HOME                        
                         8  APPCOMMAND_VOLUME_MUTE                         
                         9  APPCOMMAND_VOLUME_DOWN                         
                        10  APPCOMMAND_VOLUME_UP                           
                        11  APPCOMMAND_MEDIA_NEXTTRACK                     
                        12  APPCOMMAND_MEDIA_PREVIOUSTRACK                 
                        13  APPCOMMAND_MEDIA_STOP                          
                        14  APPCOMMAND_MEDIA_PLAY_PAUSE                    
                        15  APPCOMMAND_LAUNCH_MAIL                         
                        16  APPCOMMAND_LAUNCH_MEDIA_SELECT                 
                        17  APPCOMMAND_LAUNCH_APP1                         
                        18  APPCOMMAND_LAUNCH_APP2                         
                        19  APPCOMMAND_BASS_DOWN                           
                        20  APPCOMMAND_BASS_BOOST                          
                        21  APPCOMMAND_BASS_UP                             
                        22  APPCOMMAND_TREBLE_DOWN                         
                        23  APPCOMMAND_TREBLE_UP                           
                        24  APPCOMMAND_MICROPHONE_VOLUME_MUTE              
                        25  APPCOMMAND_MICROPHONE_VOLUME_DOWN              
                        26  APPCOMMAND_MICROPHONE_VOLUME_UP                
                        27  APPCOMMAND_HELP                                
                        28  APPCOMMAND_FIND                                
                        29  APPCOMMAND_NEW                                 
                        30  APPCOMMAND_OPEN                                
                        31  APPCOMMAND_CLOSE                               
                        32  APPCOMMAND_SAVE                                
                        33  APPCOMMAND_PRINT                               
                        34  APPCOMMAND_UNDO                                
                        35  APPCOMMAND_REDO                                
                        36  APPCOMMAND_COPY                                
                        37  APPCOMMAND_CUT                                 
                        38  APPCOMMAND_PASTE                               
                        39  APPCOMMAND_REPLY_TO_MAIL                       
                        40  APPCOMMAND_FORWARD_MAIL                        
                        41  APPCOMMAND_SEND_MAIL                           
                        42  APPCOMMAND_SPELL_CHECK                         
                        44  APPCOMMAND_MIC_ON_OFF_TOGGLE                   
                        45  APPCOMMAND_CORRECTION_LIST                     
                        46  APPCOMMAND_MEDIA_PLAY                          
                        47  APPCOMMAND_MEDIA_PAUSE                         
                        48  APPCOMMAND_MEDIA_RECORD                        
                        49  APPCOMMAND_MEDIA_FAST_FORWARD                  
                        50  APPCOMMAND_MEDIA_REWIND                        
                        51  APPCOMMAND_MEDIA_CHANNEL_UP                    
                        52  APPCOMMAND_MEDIA_CHANNEL_DOWN                  
                        53  APPCOMMAND_DELETE                              
                        54  APPCOMMAND_DWM_FLIP3D                          

Open in new window

After some experimentation, I found that only some of the AppKey values work.  Your keyboard would need to have the dedicated key and/or you would need to be running an application program that knows what to do when it gets a WM_APPCOMMAND message.

On the upside, you can experiment with these settings without needing to reboot.  The system appears to checks the registry with each keystroke.

So... That's how to make a dedicated key take a special action.  What if your keyboard does not have dedicated keys for remapping?  Read on!

Putting It All Together
We now have a method to remap one low-level scancode to another one.  Might we not remap one of the useless standard keys to do something that would normally be assigned to a dedicated key?  Sure!

For conciseness of the example, let's reassign one of those keys to execute the action of the newly-minted AppKey 6. On my keyboard, the * key on the numeric keypad is virtually untouched, so I replaced its scancode with the one that the system expects to have come from the dedicated "Favorites" key.

[step="" title="NumStarToFav.REG"]
Windows Registry Editor Version 5.00
                      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
                      "Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,66,e0,37,00,00,00,00,00

Open in new window

That RegEdit script sets the NumPad * key to equate to keyboard scancode 66 E0.  Alas, 66 e0 does not equate to anything much, but I found it in yet another Microsoft document (see references) and I've listed those dedicated button values at the end of the Scancodes Table, below.

Note that the above .REG file will reset your CapsLock back to CapsLock, since the Scancode Map defines just the one key.  Here's how a .REG file that sets both will look:

[step="" title="MapMyKeys.REG"]
Windows Registry Editor Version 5.00
                      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
                      "Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,1d,00,3a,00,66,e0,37,00,00,00,00,00

Open in new window

The third set of four bytes is set to 03, indicating that two keys will be mapped.

It's a real pain to experiment with reassigning key codes like this since a reboot is required for every change.  But digging around beneath the surface can be fun and educational and I found it worthwhile.

Keyboard Layout
(Use a Key Number from the image to find Scancode in the Table Below)
Use Key Number to find key label and scancodeAnd here's a legend that shows the key name/label and scancodes for the numbers in the image.  For fun, I've added a couple of columns showing the Symbolic constants that programs should use when handling these keys.

Keyboard Scancode & Symbolic Constant Table
   Key            Scan                  
                      Num Label         Code   Symbolic Constant      Value
                      --- ------------- ----   ---------------------- --------  
                        1  ~ `          29     VK_OEM_3               0xC0  
                        2  ! 1          02                            0x31    
                        3  @ 2          03                            0x32    
                        4  # 3          04                            0x33    
                        5  $ 4          05                            0x34    
                        6  % 5          06                            0x35    
                        7  ^ 6          07                            0x36    
                        8  & 7          08                            0x37    
                        9  * 8          09                            0x38    
                       10  ( 9          0A                            0x39    
                       11  ) 0          0B                            0x30    
                       12  _ -          0C     VK_OEM_MINUS           0xBD
                       13  + =          0D     VK_OEM_PLUS            0xBB
                       15  Backspace    0E     VK_BACK                0x08
                       16  Tab          0F     VK_TAB                 0x09
                       17  Q            10                            0x51    
                       18  W            11                            0x57
                       19  E            12                            0x45    
                       20  R            13                            0x52
                       21  T            14                            0x54
                       22  Y            15                            0x59
                       23  U            16                            0x55
                       24  I            17                            0x49
                       25  O            18                            0x4F
                       26  P            19                            0x50
                       27  { [          1A     VK_OEM_4               0xDB  
                       28  } ]          1B     VK_OEM_6               0xDD
                       29  | \          2B     VK_OEM_5               0xDC
                       30  Caps Lock    3A     VK_CAPITAL             0x14
                       31  A            1E                            0x41
                       32  S            1F                            0x53
                       33  D            20                            0x44
                       34  F            21                            0x46
                       35  G            22                            0x47
                       36  H            23                            0x48    
                       37  J            24                            0x4A
                       38  K            25                            0x4B
                       39  L            26                            0x4C
                       40  : ;          27     VK_OEM_1               0xBA
                       41  " '          28     VK_OEM_7               0xDE
                       42  (in'tl )     2B     
                       43  Enter        1C     VK_RETURN              0x0D
                       44  L SHIFT      2A     VK_SHIFT               0x10
                       45  (in'tl )     56    
                       46  Z            2C                            0x5A
                       47  X            2D                            0x58
                       48  C            2E                            0x43
                       49  V            2F                            0x56
                       50  B            30                            0x42    
                       51  N            31                            0x4E
                       52  M            32                            0x4D    
                       53  < ,          33     VK_OEM_COMMA           0xBC 
                       54  > .          34     VK_OEM_PERIOD          0xBE 
                       55  ? /          35     VK_OEM_2               0xBF
                       56  (in'tl )     73    
                       57  R SHIFT      36    
                       58  L CTRL       1D     VK_CONTROL             0x11
                       60  L ALT        38     VK_MENU                0x12
                       61  Space Bar    39     VK_SPACE               0x20
                       62  R ALT        E0 38    
                       64  R CTRL       E0 1D                                  
                       75  Insert       E0 52  VK_INSERT              0x2D
                       76  Delete       E0 53  VK_DELETE              0x2E
                       79  L Arrow      E0 4B  VK_LEFT                0x25
                       80  Home         E0 47  VK_HOME                0x24
                       81  End          E0 4F  VK_END                 0x23
                       83  Up Arrow     E0 48  VK_UP                  0x26
                       84  Dn Arrow     E0 50  VK_DOWN                0x28
                       85  Page Up      E0 49  VK_PRIOR               0x21
                       86  Page Down    E0 51  VK_NEXT                0x22
                       89  R Arrow      E0 4D  VK_RIGHT               0x27
                       90  Num Lock     45     VK_NUMLOCK             0x90
                       91  Numeric 7    47     VK_NUMPAD7             0x67 
                       92  Numeric 4    4B     VK_NUMPAD4             0x64
                       93  Numeric 1    4F     VK_NUMPAD1             0x61
                       95  Num /        E0 35  VK_DIVIDE              0x6F
                       95  LS+Num /     E0 B5 
                       95  RS+Num /     E0 B6 
                       96  Numeric 8    48     VK_NUMPAD8             0x68
                       97  Numeric 5    4C     VK_NUMPAD5             0x65 
                       98  Numeric 2    50     VK_NUMPAD2             0x62
                       99  Numeric 0    52     VK_NUMPAD0             0x60
                      100  Numeric *    37     VK_MULTIPLY            0x6A
                      101  Numeric 9    49     VK_NUMPAD9             0x69 
                      102  Numeric 6    4D     VK_NUMPAD6             0x66
                      103  Numeric 3    51     VK_NUMPAD3             0x63
                      104  Numeric .    53     VK_DECIMAL             0x6E
                      105  Numeric -    4A     VK_SUBTRACT            0x6D
                      106  Numeric +    4E     VK_ADD                 0x6B
                      107  (in'tl )     7E  
                      108  NumEnter     E0 1C  VK_SEPARATOR           0x6C
                      110  Esc          01     VK_ESCAPE              0x1B
                      112  F1           3B     VK_F1                  0x70
                      113  F2           3C     VK_F2                  0x71
                      114  F3           3D     VK_F3                  0x72
                      115  F4           3E     VK_F4                  0x73
                      116  F5           3F     VK_F5                  0x74
                      117  F6           40     VK_F6                  0x75
                      118  F7           41     VK_F7                  0x76
                      119  F8           42     VK_F8                  0x77
                      120  F9           43     VK_F9                  0x78
                      121  F10          44     VK_F10                 0x79
                      122  F11          57     VK_F11                 0x7A
                      123  F12          58     VK_F12                 0x7B
                      124  PrintScreen  E0 A2  VK_SNAPSHOT            0x2C
                      124  Ctl+PrtScrn  E0 37
                      124  Shft+PrtScrn E0 37
                      124  Alt+PrtScrn  54
                      125  Scroll Lock  46     VK_SCROLL              0x91 
                      126  Pause        (??)   VK_PAUSE               0x13
                      L-Win             E0 5B  VK_LWIN                0x5B
                      R-Win             E0 5C  VK_RWIN                0x5C
                      Apps              E0 5D  VK_APPS                0x5D
                      ------------ dedicated button scancodes ------------
                                        E0 6A  VK_BROWSER_BACK        0xA6
                                        E0 69  VK_BROWSER_FORWARD     0xA7
                                        E0 67  VK_BROWSER_REFRESH     0xA8
                                        E0 68  VK_BROWSER_STOP        0xA9
                                        E0 65  VK_BROWSER_SEARCH      0xAA
                                        E0 66  VK_BROWSER_FAVORITES   0xAB
                                        E0 32  VK_BROWSER_HOME        0xAC
                                        E0 20  VK_VOLUME_MUTE         0xAD
                                        E0 2E  VK_VOLUME_DOWN         0xAE
                                        E0 30  VK_VOLUME_UP           0xAF
                                        E0 19  VK_MEDIA_NEXT_TRACK    0xB0
                                        E0 10  VK_MEDIA_PREV_TRACK    0xB1
                                        E0 24  VK_MEDIA_STOP          0xB2
                                        E0 22  VK_MEDIA_PLAY_PAUSE    0xB3
                                        E0 6C  VK_LAUNCH_MAIL         0xB4
                                        E0 6D  VK_LAUNCH_MEDIA_SELECT 0xB5
                      compMgmtLauncher  E0 6B  VK_LAUNCH_APP1         0xB6
                      calc.exe          E0 21  VK_LAUNCH_APP2         0xB7

Open in new window

In this article we saw how to remap keyboard scancodes at the lowest level:  We set the useless CapsLock key so that it would act like the Ctrl key.  We also saw how to modify the "dedicated" browser and multimedia buttons that might be on your keyboard.  Finally, we put the two together so that we could remap any key to act as one of the dedicated keys.

The information here has been verified to be accurate for Windows 7 and Vista.  Microsoft documentation indicates that it is also valid for Windows XP and Windows 2000, but I did not test that.  Also, keyboard device drivers may vary in handling some keys, but will usually adhere to the specifications for common dedicated keyboard buttons.


Archive: Scan Code Mapper for Windows

Keyboard Scan Code Specification

Enhanced Keyboards and Windows

If you liked this article and want to see more from this author, please click the Yes button near the:
      Was this article helpful?
label that is just below and to the right of this text.   Thanks!

Comments (16)

Hello there
This was one of the best simple yet an explanatory article i had come across regarding keyboard mapping. I have a query which i was not able to find any solution so far.
I work in a organization where  the Printscreen is disabled via registry in the OU . When i run the scan code entry( .reg file ) for disabling the F1 or swapping it , it over rides the existing scan code value . When i restart the system it will revert back to the printscreen file as it gets updated by the Group Policy . Would really appreciate more help on this

does the 02,00,00,00  -- number of entries (including terminating NULL) need to be in Hex when the count goes 10 and above ie 0A ?

0x5F — [Sleep] key; 5E — Power OFF
How to remap AltGr to Right Alt ? Oh no, 'dupliKEY' Left Alt (Windows Registry):
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,06,00,00,00,38,00,38,e0,00,00,00,00
I don't like .ahk scripts, but I need to replace AppKey\8 (vol_mute: 0xAD) with AppKey\38 (paste: ?x??), or other. I tried to map Right Alt [E0 38] to [E0 0A] – I got a <dead key>! I tried to remap the mouse Volume_Mute/Down/Up, but remapping [E0 20], [E0 2E], [E0 30] has no results – the mouse still control OS sound :(not a media player):!

This Scancode table doesn't contain [AppKeys after 19] (like CLOSE, CUT, COPY, REPLY_TO_MAIL, SPELL_CHECK, etc.).
Resounding YES!  This is extremely helpful!  Thank you so much for collecting and posting all this great info in such a clear and concise manner.

BTW, your 1st & 3rd links under References are dead... :(

A couple things...   First, you didn't give any explanation at all about the last column of the key list "Value".  How/where/when is this used?  Any clues would be helpful!

It would be very helpful if you were able to add a bit more about the international keys.  Any of the other values beyond just the scan code and the same vague "(in'tl)" label for all of them.

In case you are not familiar with it, there is a powerful piece of software called KbdEdit which can do ALL of key switching you discussed- and it doesn't require a reboot to activate (although I believe it requires logging out).  It is not free, but it is well worth the price IMO!  The premium version can produce both a proprietary format, as well as a standard Windows .klc and .dll that is installable on any Windows system.  It allows very detailed and full customization on the keyboard to the extent supported by the MS specification.
There is a list similar to yours in the documentation for KbdEdit- although it is missing the scan codes.
I'm going to do some experimentation to with the international keys to link up the scan codes you provide with the rest of the data in that documentation.
Dan... You truly are THE MAN! :,)
This breakdown should become the Hoyle's Guide to Key Remapping.
You just saved this IT Pro a week's worth of learning and condensed it into an hour and a half of work start to finish. If you have a donation bank hit me up I'm putting money in your pocket for this one!!!
(I don't got much, but it will at least buy you a beer or two!)

View More

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.