Virtual Keys

Earlier this week, Wolf posted about Virtual Key Codes. His main points are that (a) virtual key codes are a level of detail that you should almost never care about, and that (b) they can be handy if you need to use some lower level key handling.

But one thing I really want to reiterate is that virtual key codes do NOT constantly map to a given character. Wolf used ‘Z’ as an example - the ‘Z’ key on a US English keyboard layout is attached to the key that generates key code 6. But the key for virtual key code 6 generates a ‘Y’ when using a German keyboard layout. The important thing to note here is that virtual key codes are constant for a given physical key, but characters are not. In most cases, no matter what keyboard you plug in to your Mac - whether it’s Apple’s Shift-JIS Japanese keyboard, a third-party product, or Apple’s US English keyboard, there will be a key near the lower left that generates virtual key code 6. Now, there are some minor differences - especially when you get toward the outside of a keyboard. Different languages tend to lay out the Return and several other keys differently, and Apple’s Shift-JIS Japanese keyboard has virtual key codes that don’t even exist on Apple’s US English keyboard. So, virtual key codes are always constant on a given keyboard, regardless of the layout you’re using in the OS, and virtual key codes tend to be in the same location across different physical keyboards, but there are exceptions to those rules. Confused yet?

But How Do I Get a Character?!?

To turn a virtual key code into a character, you need to know the current keyboard layout, the current script, and several other factors. The simplest method to get a character from a key is KeyTranslate(). But unfortunately, it doesn’t handle some high-ASCII characters well, and doesn’t handle Unicode characters at all. For those, you’ll need UCKeyTranslate(). The latter method is much more complicated, but will give you a result for characters that don’t exist on a US English keyboard. Dealing with virtual keys - especially if you just want to turn them into character values, isn’t simple - I recommend relying on Cocoa to do it for you, if possible.

Key Codes, HEH! What are they good for?

So what good are virtual key codes? The first thought that springs to mind is keyboard commands and key equivalents. But if you’re using Cocoa, most of this is handled for you. And it’s important to note that keyboard equivalents in Cocoa are character-based, once again hiding the virtual key code complexity. For example, if you assign Command-Z as a keyboard equivalent to a menu item, it doesn’t matter what keyboard layout you’re using or where the ‘Z’ key is - Cocoa automatically translates the incoming key code into a character and looks for a match.

But there is some utility to virtual key codes - and it comes from their somewhat constant location on your keyboard. So if you’re an application like Final Cut Pro that uses JKL-editing, then you may want the ‘J’, ‘K’, and ‘L’ keys to perform certain actions. And importantly, you may want those physical keys to perform the actions regardless of the user’s keyboard- even if those physical keys are no longer ‘J’, ‘K’, and ‘L’. So, virtual key codes can be very useful if your application needs geographical, rather than character-based, key equivalents.

The End

To recap, virtual key codes are the numbers assigned to individual keys on a keyboard, they do not map constantly to a character, and are generally in the same location on every keyboard. You should almost never need to care about virtual key codes, but if you’re looking to implement a key equivalent system where the equivalents stay in the same location regardless of keyboard layout, then virtual key codes are what you’re looking for.

1 Response to “Virtual Keys”


  1. 1 Peter Maurer Sep 27th, 2006 at 11:57 pm

    There’s one possible use for virtual key codes you forgot to mention: simulating keystrokes. This is something a lot of applications do — e.g., those applications that use the clipboard for inserting content by simulating a [command]-[v] keystroke.

    While that’s not a perfect approach — given the editability of keyboard shortcuts such as [command]-[v] — it is indeed a wide-spread way of triggering a paste action. And it’s the most reliable way of doing so I’m aware of.

    The interesting part here is that most developers tend to forget what you’ve mentioned near the beginning of your article: The [v] key isn’t always in the same place, and it might even change its position depending on the modifier key state. Think Dvorak-Qwerty. Unfortunately, finding out the virtual key code for a given character during runtime is not fun on Mac OS.

    It took me a while to find a way around these problems when I was faced with them for the first time; and I just wanted to say “thank you” for the memories.

Comments are currently closed.