我正在发送键盘按键和按键释放事件,这些事件适用于所有键盘按键。
但是,仅当与修饰符键关联的键是从应用程序而非真实硬件发送时,修饰符键才起作用。那就是如果我从应用程序发送Shift和'a',它会打印'A'(大写字母A,这是预期的)。
但是,如果我从应用程序发送“ shift”键按下事件,然后从物理键盘输入“ a”,则会打印“ a”(Shift键似乎无法在不同设备上使用)。其他修改器键(例如cmd,alt和fn键!)也是如此。
有没有一种方法可以将修改键发送到系统,以便可以从应用程序中模拟修改键?具体来说,我想从应用程序激活修改键,然后从物理键盘输入组合键。
这是我用来发送按键和释放事件的代码。
- (void)setADBKey:(uint32)key value:(int)value
{
if (!eventSource)
{
eventSource = CGEventSourceCreate(kCGEventSourceStatePrivate);
}
CGEventRef event = CGEventCreateKeyboardEvent(eventSource, key, value!=0);
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);
}
我还尝试通过以下代码创建和发送系统事件
struct
{
CGKeyCode keyCode;
int flag;
int cgEventFlag;
} modifiers[] = {
{ 56, NX_DEVICELSHIFTKEYMASK, kCGEventFlagMaskShift },
{ 60, NX_DEVICERSHIFTKEYMASK, kCGEventFlagMaskShift },
{ 59, NX_DEVICELCTLKEYMASK, kCGEventFlagMaskControl },
{ 58, NX_DEVICELALTKEYMASK, kCGEventFlagMaskAlternate },
{ 61, NX_DEVICERALTKEYMASK, kCGEventFlagMaskAlternate },
{ 55, NX_DEVICELCMDKEYMASK, kCGEventFlagMaskCommand },
{ 54, NX_DEVICERCMDKEYMASK, kCGEventFlagMaskCommand }
};
- (void)setAdbKey:(uint32)adbkey value:(int)value repeat:(BOOL)repeat
{
//int adbkey = def_usb_2_adb_keymap[hidkey];
int modifier = 0;
for(int i=0; i< ARR_SIZE(modifiers); i++)
{
if (adbkey == modifiers[i].keyCode)
{
modifier = modifiers[i].cgEventFlag;
break;
}
}
if (value)
{
flags |= modifier;
}
else
{
flags &= ~modifier;
}
CGEventRef event = CGEventCreateKeyboardEvent(eventSource, adbkey, value!=0);
if (repeat)
{
CGEventSetIntegerValueField(event, kCGKeyboardEventAutorepeat, (int64_t)1);
}
// don't apply modifier flags to a modifier
if (!modifier)
{
CGEventSetFlags(event, flags);
}
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);
}
当从应用程序发送修饰键和组合键时,这两种方法都有效,但仅从应用程序设置修饰键时,这两种方法均无效。
您所要做的就是创建一个事件水龙头并设置遮罩。
样本:
@interface AppDelegate ()
@property (assign) CFMachPortRef myEventTap;
@property (assign) CFRunLoopSourceRef myRunLoopSource;
@end
@implementation AppDelegate
CGEventRef MyEventTapCallBack(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
CGEventSetFlags(event, kCGEventFlagMaskShift);
return event;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
self.myEventTap = CGEventTapCreate(kCGHIDEventTap,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventFlagsChanged),
MyEventTapCallBack,
(__bridge void *)self);
if (self.myEventTap) {
self.myRunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, self.myEventTap, 0);
if (self.myRunLoopSource)
CFRunLoopAddSource(CFRunLoopGetMain(), self.myRunLoopSource, kCFRunLoopCommonModes);
}
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
if (self.myRunLoopSource) {
CFRunLoopSourceInvalidate(self.myRunLoopSource);
CFRelease(self.myRunLoopSource);
}
if (self.myEventTap)
CFRelease(self.myEventTap);
}
@end
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句