I have been successful sending keystrokes in order to automate a particular software package for drawing that I use. This software relies a lot of keyboard shortcuts so I wrote something that could call some of these keyboard shortcuts in order to streamline my workflow. As I said, this has worked out good.
My library is a Cocoa library that is loaded as a plugin to the software package. Here is a snippet of code that I have been using for sending my keystrokes.
CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef eventDown = CGEventCreateKeyboardEvent(eventSource, (CGKeyCode)1, true);
CGEventRef eventUp = CGEventCreateKeyboardEvent(eventSource, (CGKeyCode)1, false);
//setting the process number somewhere else
CGEventPostToPSN(&number, eventDown);
CGEventPostToPSN(&number, eventUp);
For some procedures in the drawing package if you continue to hold the Shift key then you activate a special tool. I have been unable to simulate this. I thought I could send the Shift key and say that I wanted it to auto-repeat but that doesn't seem to work. I have been using the following code to set the auto-repeat:
//This is done before sending the key
CGEventSetIntegerValueField(eventDown, kCGKeyboardEventAutorepeat, 1);
In my testing I have been unable to make any key auto-repeat. It just send the key once and that is it.
Is there anyone that have been successful autorepeating a key using the above method? I have searched the Internet for answers but all I have found are some unanswered questions from 2008... Any help is greatly appreciated.
Thanks,
mobbe
UPDATE: the Shift key's code isn't 56
, according to Events.h:
...
kVK_Shift = 0x38,
...
(EDIT: of course those of you who are paying attention (I wasn't) realize that HEX 38 == DEC 56.)
I also realized how to get modifier key presses: flagsChanged:
. So using this keycode, I can catch Shift key presses in flagsChanged:
, and the repeat works fine; I also get repeated key events for "normal" keys in keyDown:
and keyUp:
without difficulty.
It sounds like you may not have access to/want to change the event-handling code (to add flagsChanged:
) though, so if that keycode doesn't work for you, I'm stumped and can only say "Good luck!"
I believe that the field you're setting is used to indicate not that the event should be repeated by the system, but that an event is an auto-repeat of a previous event. You still have to generate each event yourself. Something like (EDITED to use a timer instead of a loop):
CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef eventDown = CGEventCreateKeyboardEvent(eventSource, (CGKeyCode)1, true);
// Post the initial keydown
CGEventPostToPSN(&pidNumber, eventDown);
// Keep track of how many Shift keydown events have been sent
shiftKeyRepeatCount = 1;
[NSTimer scheduledTimerWithTimeInterval:0.3 // I don't know exactly what the interval should be, of course
target:self
selector:@selector(repeatShiftKeyDown:)
userInfo:nil
repeats:YES];
CFRelease(eventDown);
- (void)repeatShiftKeyDown:(NSTimer *)tim {
if( shiftKeyRepeatCount >= kRepeatCountForSpecialTool ){
[tim invalidate];
[self sendShiftKeyUp];
return;
}
shiftKeyRepeatCount++;
GEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef eventDown = CGEventCreateKeyboardEvent(eventSource, (CGKeyCode)1, true);
// Set the auto-repeat field
CGEventSetIntegerValueField(eventDown, kCGKeyboardEventAutorepeat, 1);
CGEventPostToPSN(&pidNumber, eventDown);
CFRelease(eventDown);
}
I'm not certain whether you can reuse the first event with a changed field or you'll need to generate a new event to use when repeating.
The code that OP finally came up with to solve the problem (transferred here from a comment under other answer):
CGEventRef flagsChanged = CGEventCreate(eventSource);
CGEventSetType(flagsChanged, kCGEventFlagsChanged);
CGEventSetIntegerValueField(flagsChanged, kCGKeyboardEventKeycode, 56);
CGEventSetFlags(flagsChanged, 131330);
CGEventPostToPSN(&number, flagsChanged);
CFRelease(flagsChanged); CFRelease(eventSource);
131330
is a constant indicating the Shift key; it is related to NSShiftKeyMask
and kCGEventFlagMaskShift
, which are 131072
( 0x00020000
). 131330 - 256 - 2 == 131072
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.