It should be simple enough, but for some reason it isn’t. Quite simply, I’m trying to get the appropriate key code for a particular letter.
Example:
on clicked theObject
set i to 1
set theResult to "{"
set myInput to the contents of text field "theInput" of window 1
repeat (length of myInput) times
set theResult to theResult & (get key code of (character i of myInput)) & " "
set i to i + 1
end repeat
set contents of text field "theOutput" of window 1 to theResult
end clicked
Of course, I get an error. I tried “get key code of (keystroke(character i of myInput))”, thinking it required an event, but that didn’t work either. So, how would I go about getting the key code of a particular character?
Do you really want the key code or just the ASCII code for it?
If ASCII:
set tChars to {}
set myInput to "Hello World!"
repeat with aChar in characters of myInput
set end of tChars to ASCII number of aChar
end repeat
tChars --> {72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33}
Obviously, I’m making a tiny app to just spit out the appropriate key codes for a string letters for use in the “key code” command. I could, of course, use a very large if-else routine and chug through every single character on the keyboard, but I was hoping I could use the “get key code” statement to achieve the same thing.
'Key code" is an event property, used to describe hardware… not represent actual glyphs, or letters, in a particular character set. Since keyboards and the keys on them can change, it’s not wise to assume that a particular key code ALWAYS represents a certain “letter”.
The best way to evaluate a keyCode, is to catch it from an appropriate object as it’s sent with an event… such as a key down event. To do this from a list of characters derived from a string, aside from focusing a control, sending it events, and recording the resulting key code of each event is not possible using the event class. Instead, you’ll have to manually make up a dictionary of chars and keycodes and access the list to find your matches. In your case, you have a finite list of letters and corresponding key codes, which you should adhere to. It seems to match typical key codes for basic keyboards, but since you’re looking for compatibility with a specific third-party specification, I’d go with their list to be sure. Either way, the process of getting a keycode out of a character is the same, regardless of the source of your key code dictionary. Below is a simple demonstration. I put the code that generates the dictionary of keys/values into a subroutines so you don’t have a huge dictionary declared in the head of your script file. It inserts a “-” in place of keycodes it knows not of. PS… I didn’t feel like typing in all of the keycodes into the list, so it only goes up to ‘e’… you’ll have to add the rest
on awake from nib theObject --> Connected to the FIle's Owner
initKeyCodeList()
end awake from nib
on clicked theObject
if name of theObject is "log" then
set theInput to content of text field "input" of (window of theObject)
set theKeyCodes to {} --> Output as a list
--set theKeyCodes to "" --> Output as a string
repeat with tmpChar in characters of theInput
set tmpKeyCode to getKeyCodeForChar(tmpChar) --> Output as list
copy tmpKeyCode to the end of theKeyCodes
--set tmpKeyCode to tmpKeyCode & "." & getKeyCodeForChar(tmpChar) --> Output as string
end repeat
log theKeyCodes
end if
end clicked
to getKeyCodeForChar(theChar)
try
set theKeyCode to run script "on run(theChar,keyCodeList)
return " & theChar & " of keyCodeList
end run" with parameters {theChar, keyCodeList}
on error
set theKeyCode to "-"
end try
return theKeyCode
end getKeyCodeForChar
to initKeyCodeList()
set keyCodeList to {a:"0", b:"11", c:"8", d:"2", e:"14"}
end initKeyCodeList
In a quick search on the interweb, all of the techniques I found that do this sort of thing use this same type of approach.
here a small script (far from being perfect, but does it’s job) that gives you the keycode and the character when typing on the keyboard or by entering keycodes or characters in a dialog box (you can easily modify it to generate a keycode list by entering a repeat loop …):
You need a button (connect it to ‘on clicked’ and to ‘on keyboard up’)
and a text view (text view “tv” of scroll view “sv” of window “main”
property listeningToKeyboard : true
on keyboard up theObject event theEvent
if (listeningToKeyboard) then
tell window "main"
tell text view "tv" of scroll view "sv"
set modifierKeys to ""
if (control key down of theEvent) then set modifierKeys to modifierKeys & "control+"
if (option key down of theEvent) then set modifierKeys to modifierKeys & "option+"
if (shift key down of theEvent) then set modifierKeys to modifierKeys & "shift+"
set it's contents to it's contents & "Character: \"" & (character of theEvent) & "\" Key(s): " & modifierKeys & "key code " & (key code of theEvent) & return
end tell
end tell
end if
end keyboard up
on clicked theObject
set listeningToKeyboard to false
set input to (display dialog "enter key code or character(s)" default answer "" buttons {"key code", "character", "cancel"})
if button returned of input = "key code" then
set keyCode to text returned of input as integer
try
delay 0.1
set listeningToKeyboard to true
call method "MyKeyboardEvent:" of class "postKey" with parameter (keyCode)
on error
set listeningToKeyboard to true
end try
else if button returned of input = "character" then
try
delay 0.1
set listeningToKeyboard to true
tell application "System Events"
tell process (my name)
keystroke (text returned of input)
end tell
end tell
on error
set listeningToKeyboard to true
end try
end if
end clicked
And here the class ‘postKey’ files (for generating virtual keyboard events):
Thanks for feedback. I just ended up writing a utility that’ll break down a string into a series of “key code” statements. If, for example, you had a whacky case-sensitive registration key (something like: qlX92CDdk-dF#kd@#kaZfk0f2j-dns-LRt) that you needed to send to all the computers via Remote Desktop, you can feed that into the little utility, and it’ll spit out for you:
Hence the resounding slap. It was a bunch of needlessly wasted time.
[edit]
Okay, correction, it wasn’t a COMPLETE waste of time. I’ll find a use for it if I need to send sensitive things over the network (like admin password) and don’t want people who are hovering about the lab to know what exactly it is I’m sending.