Capturing Multiple Key presses

A customer wants to quiz his students on many different key combinations for the Mac platform. For instance, the answer to question one might be ctrl-opt.-3 or the answer to another might be cmd-opt-ctrl-up arrow. I am struggling with how to capture those simultaneous key presses so as to determine the answer to be right or wrong. I have set a timer and using Keyboard.AsyncOptionKey etc, can capture cmd, opt, ctrl, and shift. But the problem is that, for instance, if option is depressed when you hit ‘g’ you don’t get ‘g’ passed to keydown, but rather ©.
Any insight as to how to make this work would be greatly appreciated.

Have you looked at the Keyboard module. It has special properties to check for Control, Option, Shift, Command keys etc. The async versions tells you the immediate state of the key… The non-Async versions tell you if the key was depressed at the time a method is queued for execution. This should probably get you on your way.

as stated in another topic… on the Mac, pressing the Option Key with most any other “character” key, will generate a “symbol” such as the “G”=“©” that you noticed.

lowercase “G” is CHRB(103), uppercase “G” is CHRB(71), option “G” is CHRB(194), control “G” is CHRB(7)
so each modifier key does just that… it modifies the result
and without more research, there may be no mathematical correlation between the “character” and the “symbol” when “Option” is involved… There IS when SHIFT is involved, [uppercase+32], and control is [uppercase-64]

might be best to create a lookup table… check out the KEYCODE info in the LangRef.

Use Keyboard.AsyncKeyDown instead of the KeyDown event parameter.

AsyncKeyDown uses KeyCodes, not ascii or unicode values, so you’ll want to make a mapping of the KeyCode list here http://documentation.xojo.com/index.php/Keyboard

Thanks Harrie, Dave, and Will. I will look into mapping of the KeyCode list.

what is a bummer about AsyncKeyDown
is it doesn’t tell you WHAT the keycode is…
You have to ASK it if it a specific keycode or not

Yea, Dave. I was thinking I couldn’t possibly poll every possible key within the bounds of a short timer. Key mapping is probably the way to go.

You can, I made a key logger this way.

But if you’re using a KeyDown event I don’t see a need for the timer, just process with asyncs when a key comes in.

Here’s a demo using AsyncKeyDown. Add a Timer (period 10) and a Label (sized wide) to a window with this code. Keys pressed show up in the Label. The map was auto generated from the docs but I didn’t include the numeric keypad section.

[code]Private lastKeyPresses As String //Window property

Sub Action() //Timer1 with Period 10, mode multiple

dim hits() As String

if Keyboard.AsyncCommandKey then hits.Append “Command”
if Keyboard.AsyncOptionKey then hits.Append “Option”
if Keyboard.AsyncControlKey then hits.Append “Control”
if Keyboard.AsyncShiftKey then hits.Append “Shift”

static map As Pair = buildMap
dim k() As String = map.Left
dim v() As integer = map.Right
for i As integer = 0 to k.Ubound
if Keyboard.AsyncKeyDown(v(i)) then hits.Append k(i)
next

dim s As String = Join(hits, “+”)

if s <> lastKeyPresses then
lastKeyPresses = s
Label1.Text = lastKeyPresses
end

End Sub

Private Function buildMap() As Pair //Window method
dim k() As String, v() As integer
dim map As new Pair(k, v)
k.Append “a”
v.Append &h00
k.Append “b”
v.Append &h0B
k.Append “c”
v.Append &h08
k.Append “d”
v.Append &h02
k.Append “e”
v.Append &h0E
k.Append “f”
v.Append &h03
k.Append “g”
v.Append &h05
k.Append “h”
v.Append &h04
k.Append “i”
v.Append &h22
k.Append “j”
v.Append &h26
k.Append “k”
v.Append &h28
k.Append “l”
v.Append &h25
k.Append “m”
v.Append &h2E
k.Append “n”
v.Append &h2D
k.Append “o”
v.Append &h1F
k.Append “p”
v.Append &h23
k.Append “q”
v.Append &h0C
k.Append “r”
v.Append &h0F
k.Append “s”
v.Append &h01
k.Append “t”
v.Append &h11
k.Append “u”
v.Append &h20
k.Append “v”
v.Append &h09
k.Append “w”
v.Append &h0D
k.Append “x”
v.Append &h07
k.Append “y”
v.Append &h10
k.Append “z”
v.Append &h06
k.Append “0”
v.Append &h1D
k.Append “1”
v.Append &h12
k.Append “2”
v.Append &h13
k.Append “3”
v.Append &h14
k.Append “4”
v.Append &h15
k.Append “5”
v.Append &h17
k.Append “6”
v.Append &h16
k.Append “7”
v.Append &h1A
k.Append “8”
v.Append &h1C
k.Append “9”
v.Append &h19
k.Append “F1”
v.Append &h7A
k.Append “F2”
v.Append &h78
k.Append “F3”
v.Append &h63
k.Append “F4”
v.Append &h76
k.Append “F5”
v.Append &h60
k.Append “F6”
v.Append &h61
k.Append “F7”
v.Append &h62
k.Append “F8”
v.Append &h64
k.Append “F9”
v.Append &h65
k.Append “F10”
v.Append &h6D
k.Append “F11”
v.Append &h67
k.Append “F12”
v.Append &h6F
k.Append “F13”
v.Append &h69
k.Append “F14”
v.Append &h6B
k.Append “F15”
v.Append &h71
k.Append “ESC”
v.Append &h35
k.Append “Space”
v.Append &h31
k.Append “Tab”
v.Append &h30
k.Append “Home”
v.Append &h73
k.Append “Backspace”
v.Append &h33
k.Append “End”
v.Append &h77
k.Append “Page Up”
v.Append &h74
k.Append “Page Down”
v.Append &h79
k.Append “Delete”
v.Append &h75
k.Append “Help”
v.Append &h72
k.Append “Left”
v.Append &h7B
k.Append “Right”
v.Append &h7C
k.Append “Up”
v.Append &h7E
k.Append “Down”
v.Append &h7D
k.Append “=”
v.Append &h18
k.Append “–”
v.Append &h1B
k.Append “[”
v.Append &h21
k.Append “]”
v.Append &h1E
k.Append “”
v.Append &h2A
k.Append “’”
v.Append &h32
k.Append “’”
v.Append &h27
k.Append “;”
v.Append &h29
k.Append “/”
v.Append &h2C
k.Append “,”
v.Append &h2B
k.Append “.”
v.Append &h2F
k.Append “,”
v.Append &h2B
return map
End Function

Function KeyDown(Key As String) As Boolean //Window event, prevents beeps
return true
End Function[/code]

CarbonHotKeyMBS class may help as it can register hotkeys, so you get an event if a keyboard combination is pressed.

@Will Shank. This is a tremendously helpful step toward what I need to achieve. Many, many thanks for your generosity.

Just remember that the key codes are specific to a US Keyboard

Actually, on Mac the codes are the same for all keyboard layouts. On Window, they vary with the layout.
https://forum.xojo.com/20849-use-keycode-without-having-to-read-docs