PDA

View Full Version : Carbon Keyboard Events


IBethune
2002.10.13, 01:32 PM
I'm wanting to detect key presses in carbon, and currently I have an event handler that deals with kEventClassKeyboard and kEventRawKeyDown.

Basically the handler takes the EventRef parameter 'event' and gets the charCode associated with the event.


char theKey;
GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &theKey);


What I want to do is extend this to be able to catch all key presses ( i.e. shift, control, option, command etc), not just the keys which have corresponding ASCII codes. Is there an easy way to do this, or do I also have to catch events of type kEventRawKeyModifiersChanged, and then get the modifier bits, check for which modifiers are down, and translate this into some key values that I defined myself. If this is the only way, can someone tell me where I can find what the different modifier codes are when I get an UInt32 back for the modifiers from GetEventParameter.

Thanks,

- Iain

Hog
2002.10.13, 02:26 PM
from an antique think-reference, modifiers are:
activateFlag | btnState | cmdKey | shiftKey | alphaLock | optionKey | controlKey
but i'd double check on that (the keys work for sure).

OneSadCookie
2002.10.13, 03:18 PM
I think they're defined in Events.h.

I believe that catching the modifiers changed event is the only way.

IBethune
2002.10.13, 03:35 PM
Hmm, I thought that might be the solution. Oh well, guess I'll just have to go and implement it then :(

- Iain

kelvin
2002.10.22, 05:18 AM
but for Cocoa, I know that you can detach new thread to watch for events. Just make a while(1) loop that checks for shift/command/option/control down and posts a notification or event. I've done this with a network socket controller, so I know it works. My socket controller detaches a thread that watchs to see if a process is running. When the process ends (in you case when the mod-key is pressed) the loop sends a message to either the notification center or spawns the appropriate message. :D

Keeping the events synchronous may be troublesome, so my suggestion is to deal with the main runloop and try to intercept the key events there.

Hope that helps.

IBethune
2002.10.22, 05:30 AM
The solution I've ended up with is to have two different functions for dealing with key presses.

One is HandleKeyPress() which is called when a kEventRawKeyDown occurs, and gets the Char Code associated with that key press.

The other is HandleSpecialKey() which is called when a kEventRawKeyModifiersChanged. I have a byte stored in memory which holds the current state of the modifier keys, and this is then compared with the up-to-date modifier keys. If any have changed from off to on, I return a char value (which I have defined with values >128).

I can then call the function DoAction(char theKey) with either a real char code, or with the char codes I have defined to represent modifier key presses.

The only problem I have with this is that if the user hits Shift-A, say, then there will be two codes returned, 'shift', then 'A' - and if the user was actually wanting to use the command 'a' it would not be recognised. What I may do about that is either put all key presses to upper case by default, or deal in terms of key codes rather than char codes.

- Iain

OneSadCookie
2002.10.22, 05:52 AM
uppercasing doesn't work, since if they press shift-4, you'll get a '$', or something different on a German keyboard...

Also, if they type option-a or worse, control-a you're completely screwed :)

Use key codes...

IBethune
2002.10.22, 08:58 AM
Yeah, hadn't really considered that one. It's shouldn't be to hard to change anyway, as I just need to use the kEventParamKeyMacKeyCodes instead, and replace all my chars with shorts.

Do you have any idea what values the key codes can take up, as again I'll need to define some custom codes to represent modifier key presses (e.g. at the moment I use codes >128 as they are not ASCII values)

Unfortunately, I'll need to convert all the key codes back to Chars in order to display them in the preference page - I'm guessing the iGetKeys is an easy bit of code to use for this? Is there a quicker way to convert key codes to the equivalent ASCII char value?

Major refactoring of code tonight I think...

- Iain