在OS X中以编程方式模拟/切换CAPS LOCK

时间:2015-05-04 16:31:50

标签: objective-c c xcode macos cgeventtap

我在这个主题上看过很多帖子。但是避难所在任何地方都没有找到明确的答案。

有没有办法在Objective-C或C代码中切换CAPS LOCK?我不是在寻找使用X11库的解决方案。我对LED的开/关状态并不感到困扰。但只是CAPS LOCK的功能(更改字母大小写并在数字键上打印特殊字符)。

为什么CGEvent不像其他键那样支持它?

3 个答案:

答案 0 :(得分:1)

var ioConnect: io_connect_t = .init(0)
let ioService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass))
IOServiceOpen(ioService, mach_task_self_, UInt32(kIOHIDParamConnectType), &ioConnect)

var modifierLockState = false
IOHIDGetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), &modifierLockState) 

modifierLockState.toggle()
IOHIDSetModifierLockState(ioConnect, Int32(kIOHIDCapsLockState), modifierLockState)

IOServiceClose(ioConnect)

答案 1 :(得分:0)

当您希望 CapsLock 切换当前键盘语言时,以下方法也适用(如果您已将 CapsLock 键配置为这样做)。

CFMutableDictionaryRef mdict = IOServiceMatching(kIOHIDSystemClass);
io_service_t ios = IOServiceGetMatchingService(kIOMasterPortDefault, (CFDictionaryRef)mdict);
if (ios) {
    io_connect_t ioc = 0;
    IOServiceOpen(ios, mach_task_self(), kIOHIDParamConnectType, &ioc);
    if (ioc) {
        NXEventData event{};
        IOGPoint loc{};

        // press CapsLock key
        UInt32 evtInfo = NX_KEYTYPE_CAPS_LOCK << 16 | NX_KEYDOWN << 8;
        event.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS;
        event.compound.misc.L[0] = evtInfo;
        IOHIDPostEvent(ioc, NX_SYSDEFINED, loc, &event, kNXEventDataVersion, 0, FALSE);

        // release CapsLock key
        evtInfo = NX_KEYTYPE_CAPS_LOCK << 16 | NX_KEYUP << 8;
        event.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS;
        event.compound.misc.L[0] = evtInfo;
        IOHIDPostEvent(ioc, NX_SYSDEFINED, loc, &event, kNXEventDataVersion, 0, FALSE);

        IOServiceClose(ioc);
    }
}

答案 2 :(得分:-1)

经过长时间的斗争,我得到了这个工作。

两次调用下面给出的方法。一次为up事件,另一次为down事件。例如,为了模拟CAPS A,我们需要执行以下操作。

[self handleKeyEventWithCapsOn:0 andKeyDown:NO];
[self handleKeyEventWithCapsOn:0 andKeyDown:YES];

0是&#39; a&#39;的密码。

- (void) handleKeyEventWithCapsOn:(int) keyCode andKeyDown:(BOOL)keyDown
{
    if(keyDown)
    {
        CGEventRef eventDown;
        eventDown = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)keyCode, true);
        CGEventSetFlags(eventDown, kCGEventFlagMaskShift);
        CGEventPost(kCGSessionEventTap, eventDown);
        CFRelease(eventDown);
    }
    else
    {
        CGEventRef eventUp;
        eventUp = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)keyCode, false);
        CGEventSetFlags(eventUp, kCGEventFlagMaskShift);
        CGEventPost(kCGSessionEventTap, eventUp);

        // SHIFT Up Event
        CGEventRef eShiftUp = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)56, false);
        CGEventPost(kCGSessionEventTap, eShiftUp);
        CFRelease(eventUp);
        CFRelease(eShiftUp);
    }
}