Virtual Keys
You can see the virtual keys for the US English keyboard layout in Figure 1. The decision of how scan codes and virtual keys map to each other is made in the keyboard layout.
Figure 1: Virtual keys in the US English keyboard
Unfortunately for the implementer, the bulk of the most important VKs are not officially defined but are implied in the comments:
/*
* VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
* 0x40 : unassigned
* VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
*/
The rest of the virtual keys in use are explicitly defined constants, and there is no rule that keeps all virtual keys with the same keys on the keyboard; as you change keyboard layout, those values can change between different layouts. Note that in Figure 1, the implicit keys are all light gray, while the explicit "OEM" keys are white. You can obtain an array containing the state of every VK by calling the GetKeyboardState API.
The VK values are important for the window messages that have to deal with keystrokes before they are processed by the USER subsystem in Windows, such as WM_KEYDOWN. Although there are minor changes in position between different keyboards even when the character values are the same, they do not change much between different keyboard layouts. Here is an example of a typical change: the letter "Q" is represented by the VK_Q on both the French and US English keyboards though on the French keyboard the "Q" and "A" keys are in reversed positions relative to the US keyboard (see the VK map for the French keyboard in Figure 2 for comparison with the US layout in Figure 1).
Figure 2: Virtual keys in the French (France) keyboard
The position of the OEM keys often changes between different layouts as well. Most of the other VK positions are static. The changes are all quite minor when compared with the next step -- where those keystrokes are processed.