Learn the Difference Between AutoHotkey Keyboard Scan Codes (SCnnn) and Virtual Key Codes (VKnn) and When to Use Them for Hotkeys
Not all keyboards are equal. Detached desktop keyboards may include many extra keys while smaller laptop keyboards might be shortened versions of their larger cousins. When setting up Hotkeys, you must work with the keyboard you own. That means using the available keys and the usual AutoHotkey key names and techniques. However, you will likely find key action names in the AutoHotkey Key List with no corresponding key on your particular keyboard (e.g. AppsKey). At other times, you may find keys on your keyboard which don’t appear in the AutoHotkey list. These situations may call for a unique approach to setting up Hotkeys.
* * *
This beginning Hotkey blog builds upon the discussions in the previous parts. If you find any of the information too confusing, then reviewing earlier blogs may be worthwhile.
New to AutoHotkey? See “Introduction to AutoHotkey: A Review and Guide for Beginners.”
For people who want this entire series in one updated e-book, see AutoHotkey Hotkey Techniques at ComputorEdge E-Books.
* * *
Regardless of the situation, there is usually a method in AutoHotkey for taking advantage of these extra or missing keys by using the listed special key names. But for unusual situations or unique applications, the Scan Codes hardwired into your keyboard or the Microsoft assigned Virtual Key Codes may be the best way to implement special Hotkeys or remap your keyboard. AutoHotkey Scan Codes and Virtual Key Codes can give your Hotkey scripts that additional flexibility and power. But, you need to understand what they are and how they work.
Scan Codes (SCnnn) Versus Virtual Keys Codes (VKnn)
Keyboard Scan Codes (SCnnn) and Virtual Key Codes (VKnnn)—discussed in the Special Keys section at the bottom of the AutoHotkey Key List—offer alternative methods for changing key assignments and reconfiguring your keyboard to suit your needs. But, before considering techniques, let’s look at the differences between Scan Codes and Virtual Key Codes.
Think of keyboard Scan Codes as hardware and Virtual Keys Codes as software. Scan Codes are hardwired into the keyboard. Each physical key has a unique Scan Code which is always associated with that particular button on the keyboard. Even if you change the function of that key through software, the original Scan Code does not change. You can change the Scan Code through AutoHotkey, but that merely translates the original hardwired code to the new code.
Look upon Virtual Key Codes as the action software which sends the input commands. For the Windows operating system, Microsoft assigned each of these Virtual Key action codes corresponding with a keyboard hardware Scan Code. In AutoHotkey, the action for each Virtual Key Code, in hexadecimal ASCII code, conforms to one of the key action names assigned in the Key List (e.g. Enter, Tab, Space, NumLock, etc.) and can be mapped to any key on the keyboard. When pressing a key, the key is first identified by its Scan Code—then, Windows acts based upon the Virtual Key Code assigned to that hardware Scan Code.
Keyboard Scan Codes
The main reason that most keyboards can be used with any type of computer is that they are built to a standard set of codes, assigning one code to each individual key. As long as the same Scan Code is used for each key, the keyboard is interchangeable with any computer operating system which uses those same codes. It is up to the operating system (Windows for AutoHotkey) to interpret the Scan Code sent by the keyboard and make the computer act appropriately.
For most keyboards, the Scan Codes (known as “Keyboard Scan Codes: Set 1”) are well documented— Common Keyboard Scan Codes. Each key sends one code to the system when the key is pressed (MAKE column on the linked chart) and another when the key is released (BREAK column on the linked chart).
Note: There are other sets of Scan Codes for different types of keyboards, but generally the BIOS in PCs recognizes the keyboard type and uses firmware to translate those other Scan Codes (e.g. Set 2, IBM PC AT) to the Set 1 codes (IBM PC XT). To Windows, the Scan Codes always appear as if the keyboard is hardwired with Set 1 codes.
When using AutoHotkey, the codes in the MAKE column from the linked chart, expressed in hexadecimal, display the appropriate Scan Codes for each key. However, in AutoHotkey, the Scan Code is called with three digits (SCnnn). The last two digits are made up of the primary the code (hexadecimal number appearing after any comma) found in the chart’s MAKE column. The first digit is either a “0” for most keys or “1” for those special extended keyboard keys which show a preceding “E0” and comma in the chart’s MAKE column.
For example, SC04D is the Scan Code for the number 6 on the keypad—which also acts as the right cursor arrow with NumLock turned off. But, the separate right arrow key uses SC14D as its Scan Code as indicated by the “E0, 4D” on the chart. Those Scan Codes are unique for each key and never change regardless of their function (i.e. with NumLock on or off).
To set up a Hotkey with the keyboard Scan Code use the following format:
SC04D::MsgBox, The number pad 6 key is blocked!
This line blocks the “number pad 6/number pad right arrow” key on the keyboard itself, regardless of the NumLock mode.
Microsoft Virtual Key Codes
Windows translates the received keyboard Scan Code into Microsoft Virtual Key Codes which then tell Windows what to do when a key is pressed. (Windows Virtual Key Codes use the standard set of ASCII characters for letters, numbers, punctuation and other actions, whereas, keyboard manufacturers usually number the Scan Codes consecutively from left to right across the keyboard.) This standard set of ASCII codes used by Windows produces the characters and actions printed on each keyboard key. Virtual Key Codes can be thought of as the software side of the keyboard.
Virtual Key Codes are the commands issued by the keyboard. They are assigned to specific keyboard Scan Codes but may change with other keyboard actions such as pressing and holding down the SHIFT key for uppercase characters. As a rule, each Virtual Key Code correspond to an AutoHotkey key action name (e.g. Home, Left, Numpad6) found in the AutoHotkey Key List.
You can use Virtual Key Codes to directly set up Hotkeys:
VK66::MsgBox, This blocks the number 6 key!
but, this one only works on the number pad when NumLock is on. However, since the 6 key in the second row uses the same Virtual Key Code, the same line of code also blocks the number 6 key on in the number row of keys (without the SHIFT key held down).
If you need to change all uses for a particular hardware key, use the Scan Code. If you need to change an action which can be initiated by more than one key on the keyboard, use the Virtual Key Code.
Identifying Scan Codes and Virtual Key Codes
There will be times when using keyboard Scan Codes or Virtual Key Codes will be your best option. Maybe you want to take advantage of an extra key you found on your keyboard. Or more commonly, you might want to either restore a feature missing from your keyboard or change the action of rarely used keys. Many of both types of codes can be found in the linked lists above, but using AutoHotkey will help you quickly identify them and yield more comprehensive results for your keyboard—especially for extra keys or missing actions (e.g. F13, F14, F15, …).
Every loaded .ahk file (not the compiled .exe files) includes a main program window available to monitor the running script. Opening the main window and viewing the history gives you access to both the Virtual Key Codes and the keyboard Scan Codes.
Open a running .ahk file’s main window with either a double-click on System Tray icon or a right-click on that same icon, then select Open from the context menu. Next, select “Key history and script info” from the View menu at the top of the main AutoHotkey script window.

Tip: To quickly identify codes for any keyboard key, press the key, then press F5 while in the active main window’s Key History. There will be two entries for each key: one for key down (press) and one for key up (release).
In the image above, the main AutoHotkey script window for a running .ahk file shows a history of keys pressed. In this example, the Numpad7 key is highlighted to illustrate the difference between Scan Codes and Virtual Key Codes.
Notice that the Scan Code remains SC047 regardless of whether NumLock is on or off. The Scan Code is hardwired into the keyboard and unique for the each key regardless of its current function. When setting up a Hotkey for the keypad number 7 key with the Scan Code, AutoHotkey ignores the position of NumLock (on or off):
SC047::MsgBox, Both Numpad7 and NumpadHome are blocked!
Use the Scan Code to override changing conditions such as NumLock and Shift.
In the first column, the Virtual Key Codes for NumpadHome (VK24) and Numpad7 (VK67) change depending upon whether NumLock is on or off—even though each action uses the same key on the keyboard. The Virtual Key Code changes with NumLock either on or off because the Virtual Keys are mapped to the action—not the key on the keyboard.
Which type of code should be used depends on the situation. The previous Scan Code AutoHotkey line of code blocks any use of that keyboard key. But, if you want to block all Home key actions, then use the single Virtual Key Code valid for both Home and NumpadHome:
VK24::MsgBox, All Home keys are blocked!
Most full keyboards have two Home keys, one on the number pad when NumLock is off (number pad 7—SC047) and another separate Home key (SC147). Since the Home key has a separate hardware Scan Code, using Scan Codes would require two Hotkey definitions—one for each key (plus the Numpad7 key would also get blocked). However, since both keys use the same Virtual Key Code (VK24), the above line of code would block any key which attempts to initiate the Home action. If you only want to block one of the Home keys:
NumpadHome::MsgBox, The NumpadHome key is blocked!
In this case, Home is only blocked on the number pad 7 key when NumLock is off. If you want to block both Home keys with this approach, then an additional line of code must be included:
Home::MsgBox, The Home key is blocked!
Using Scan Codes and Virtual Keys Codes with AutoHotkey
In AutoHotkey, whether you should use Scan Codes or Virtual Key Codes depends on what you want to make happen. Most often remapping of keys does not require either one of these special codes. Keys can be remapped with simple Hotkey definitions:
c::b b::c
This AutoHotkey code swaps the letter b and c on the keyboard. This technique is a by far the simplest way to remap keyboard keys. However, there are times when the use of either Scan Codes or Virtual Keys may produce a more desirable result, such as when a key is missing on your keyboard, you have an extra unidentified key, or merely wish to change the action of some keys, such as, a number pad key regardless of the position of NumLock (on or off).
Next time, we’ll discuss specific situations where using either the Scan Code or Virtual Key Code may a better choice than using standard AutoHotkey Hotkey methods.
Thank you so much for creating & sharing this marvelous set of such well-written AHK tutorials!
I’ve been enjoying then very much.
I just wanted to alert you that the link to common scan codes is broken. Looks like the domain gone…
What I’m actually looking for is the scan code most frequently associated with VK_OEM_8 (usually producing section sign). For some reason this tidbit of computer knowledge is remarkably more challenging to verify that I would have ever imagined!
LikeLike
I replaced the “common scan codes” with a new link—maybe a little more cryptic but more information.
It sounds like the VK_OEM_8 key only appears on special keyboards. In any case, you should be able to use the “Identifying Scan Codes and Virtual Key Codes” technique described in this same blog. If that doesn’t work, I’m not sure where to look because AutoHotkey is not recognizing it.
LikeLike
FYI, I wrote an AHK wrapper for the Interception keyboard/mouse driver, which you can use to register a hotkey for any ScanCode, and *mutate it at the driver level* (BEFORE windows sees it)
https://autohotkey.com/boards/viewtopic.php?f=6&t=45307
LikeLike