Important: The information in this document is obsolete and should not be used for new development.
Special Uses for the KeyTranslate Function
In normal key translation, the Event ManagerKeyTranslate
function performs the conversion from virtual key code to character code and passes the result to your application in themessage
field of the event record for a key-down event. The script management system providesKeyTranslate
with a pointer to the proper keyboard-layout resource to use, based on the current script.There may be situations, however, in which you may want to explicitly call
KeyTranslate
, either to install your own keyboard layout or to perform special processing.Installing a Custom Keyboard-Layout Resource
The script management system loads and uses only those keyboard-layout resources that are installed in the System file. It cannot load a keyboard-layout resource that is, for example, in the resource fork of your application. However, if your application needs to modify the keyboard layout temporarily without forcing users to install a new keyboard layout, you can load a keyboard-layout resource from your own application resource fork and callKeyTranslate
directly after each key-down event, passing it a pointer to that keyboard-layout resource and using the same virtual key code and modifiers that you received in the event message.To more permanently replace a script system's keyboard layout, you can have the user install a keyboard-layout resource and a keyboard-icon family in the System file. Both resources must have identical ID numbers, in the range for the script system for which they will be used. You call the Script Manager
SetScriptVariable
procedure twice, to make those IDs the defaults for the given script system. You then call the Script ManagerKeyScript
procedure to load the resources and make them available to the system. Listing C-1 demonstrates the calls for a Dvorak keyboard layout in the Roman script system.Listing C-1 Loading a non-system keyboard-layout resource
CONST DvorakID = 500; VAR err: OSErr; BEGIN err := SetScriptVariable(smRoman, smScriptKeys, DvorakID); err := SetScriptVariable(smRoman, smScriptIcon, DvorakID); KeyScript(smRoman); END;In this example you do not need to callKeyTranslate
to get character codes for the new keyboard layout, and the new keyboard layout will be in effect until the system is restarted or until your application restores the original keyboard layout.The most permanent way to replace the keyboard layout is to make the system use your keyboard layout as its default. To do that you must modify the itlbKeys field of the target script system's international bundle (
'itlb'
) resource. The international bundle resource is described in the appendix "International Resources" in this book.
You can inspect and edit any keyboard-layout resource by using a resource editor such as ResEdit.
- IMPORTANT
- Apple Computer's system software licensing policy forbids shipping a modified System file. If you want to modify the System file, it is best to have the user either run the Installer to install your resources, or drag a file consisting of those resources onto the System Folder. Contact Macintosh Developer Technical Support for information on the Installer.
Using KeyTranslate for Command-Key Equivalents
In some cases you may need to callKeyTranslate
to regenerate a different character code using the same keyboard-layout resource. For example, the U.S.'KCHR'
and some other Roman keyboard layouts ignore the Shift modifier key if the Command modifier key is also pressed. That means you cannot directly use uppercase characters or shifted symbols as Command equivalents. Furthermore, for those keyboard layouts where the period is a shifted key, it means that the standard Macintosh command to cancel an operation (Command-period) cannot be generated. As another example, some applications that accept Command-? as a request for Help simply assume that "?" is a shifted version of "/", and thus bring up a Help window whenever the Command key and "/" are pressed simultaneously. This gives incorrect behavior on keyboards in which "?" is not generated by Shift-/.To overcome this and similar difficulties, you can use the virtual key code you receive in the key-down event record, and call
KeyTranslate
to run it back through the same keyboard-layout resource, but without the modifier(s) that applied when the character code was first generated. If the resulting character code is one that is significant for a command equivalent, you can use it plus the modifier state that originally applied to decide what action to take.Listing C-2 is a routine that removes the Command-key bit from the modifiers field of an event record and runs the same virtual key code through
KeyTranslate
, using the same keyboard-layout resource, to see if a different character code results.Listing C-2 Regenerating a character code with
KeyTranslate
FUNCTION TryAgain(myEvent: EventRecord): LongInt; CONST newModifierMask = $FE00; {turn off cmdKey bit} VAR Modifiers: Integer; VirtualCode: Integer; KeyCode: Integer; someState: LongInt; KCHRPtr: Ptr; BEGIN {don't keep cmdKey bit} Modifiers := BAnd(myEvent.modifiers, newModifierMask); {keep virtual key code, put in low byte} VirtualCode := BSR(BAnd(myEvent.message, keyCodeMask), 8); {assemble new key code for KeyTranslate} KeyCode := BOr(Modifiers, VirtualCode); {get pointer to current 'KCHR'} KCHRPtr := Ptr(GetScriptManagerMVariable(smKCHRCache)); someState := 0; {initialize KeyTranslate dead-key state} {see what ascii code is returned} TryAgain := KeyTranslate(KCHRPtr, KeyCode, someState); {look for returned values in both } { high and low word of result} END;In designing Command equivalents for your application, keep in mind that there may be less chance of inconsistency and confusion if you present Command equivalents to the user--and interpret them yourself--as grouped modifiers applied to the basic (unshifted) character you want to use for the command. (Note, however, that to do so you would have to write your own custom menu-definition resource.) For example, you might show "Command-Option-P" in the menu rather than "Command-\xBA"; when interpreting it, you could useKeyTranslate
and the virtual key code in the event record to make sure that the key for "p" was pressed, rather than just assuming that "\xBA" is produced by Option-P.Another possibility is to define few Commmand-key equivalents yourself, and to let the user create as many equivalents as desired.