2

キーボードのキーを押すイベントとキーを離すイベントを送信しています。これは、すべてのキーボード キーで機能します。

ただし、修飾キーは、修飾キーに関連付けられたキーがアプリケーションから送信された場合にのみ機能し、実際のハードウェアからは送信されません。つまり、アプリケーションから Shift と 'a' を送信すると、'A' (大文字の A、これが期待されます) が出力されます。

しかし、アプリケーションから「シフト」キーダウンイベントを送信し、物理キーボードから「a」を入力すると、「a」が出力されます (シフトキーは異なるデバイス間で機能していないようです)。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);
}

どちらの方法も、アプリケーションから修飾キーと組み合わせキーが送信された場合は機能しますが、アプリケーションから修飾キーのみが設定された場合は機能しません。

4

2 に答える 2

2

イベントタップを作成し、マスクを設定するだけです。

サンプル:

@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
于 2016-02-17T22:29:31.377 に答える