The virtual key code is precisely not based on the user's keyboard layout. It indicates which key was pressed, not what character that key would produce nor how it's labeled.
For example, kVK_ANSI_A
(from Carbon/HIToolbox/Events.h, value 0x00
) does not mean the key which produces the 'A' character, it means the key which is in the position that the 'A' key is in an ANSI standard keyboard. If a French keyboard layout is active, that key will produce 'Q'. If the physical keyboard is a French keyboard, that key will probably be labeled 'Q', too.
So, the virtual key code is sort of akin to a scan code, but from an idealized, standard keyboard. It is, as noted, hardware-independent. It is also independent of the keyboard layout.
To translate from the virtual key code to a character, you can use UCKeyTranslate()
. You need the 'uchr' data for the current keyboard layout. You can get that using TISCopyCurrentKeyboardLayoutInputSource()
and then TISGetInputSourceProperty()
with kTISPropertyUnicodeKeyLayoutData
as the property key.
You also need the keyboard type code. I believe it's still supported to use LMGetKbdType()
to get that, even though it's no longer documented except in the legacy section. If you don't like that, you can obtain a CGEvent
from the NSEvent
, create a CGEventSource
from that using CGEventCreateSourceFromEvent()
, and then use CGEventSourceGetKeyboardType()
and call CGEventGetIntegerValueField()
with kCGKeyboardEventKeyboardType
to get the keyboard type.
Of course, it's much easier to simply use -[NSEvent characters]
or -[NSEvent charactersIgnoringModifiers]
. Or, if you're implementing a text view, send key-down events to -[NSResponder interpretKeyEvents:]
(as discussed in Cocoa Event Handling Guide: Handling Key Events) or -[NSTextInputContext handleEvent:]
(as discussed in Cocoa Text Architecture Guide:Text Editing). Either of those will call back to the view with the appropriate action selector, like moveBackward:
, or with -insertText:
if the keystroke (in context of recent events and the input source) would produce text.