Как имитировать нажатие клавиши Caps Lock с помощью CGEventCreateKeyboardEvent в OS X

Кому-нибудь удалось имитировать нажатие клавиши Caps Lock с помощью CGEventCreateKeyboardEvent в OS X? В основном я пробовал алфавитный символ и буквенно-цифровой символ в порядке, но Caps Lock. Надеюсь, я хотел бы имитировать нажатие клавиши Caps Lock для включения / выключения светодиода. Я не знаю, в чем проблема для моего тестового кода. У кого-нибудь был опыт для этого?

#include <stdio.h>
#include <ApplicationServices/ApplicationServices.h>

main()
{
    bool wasCapsLockDown = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, 57);
    if (wasCapsLockDown)
        printf("On\n");
    else
        printf("Off\n");
    ProcessSerialNumber psn;
    GetFrontProcess(&psn);
    CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);//CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
    CGEventRef CapsLockDown = CGEventCreateKeyboardEvent(source, (CGKeyCode)57, true);
    //CGEventFlags modifiers = 0;
    //modifiers |= kCGEventFlagMaskAlphaShift;
    //CGEventSetFlags(CapsLockDown, modifiers);
    CGEventRef CapsLockUp = CGEventCreateKeyboardEvent(source, (CGKeyCode)57, false);

    // simulate capslock down
    CGEventPost(kCGHIDEventTap, CapsLockDown);
    // simulate capslock up
    CGEventPost(kCGHIDEventTap, CapsLockUp);

    //CGEventPost(kCGAnnotatedSessionEventTap, CapsLockDown); /* doesn't work */
    //CGEventPost(kCGAnnotatedSessionEventTap, CapsLockUp);

    //CGEventPost(kCGSessionEventTap, CapsLockDown); /* doesn't work */
    //CGEventPost(kCGSessionEventTap, CapsLockUp);

    //CGEventPostToPSN(&psn, CapsLockDown); /* doesn't work */
    //CGEventPostToPSN(&psn, CapsLockUp);

    CFRelease(CapsLockUp);
    CFRelease(CapsLockDown);
    CFRelease(source);
}

Скомпилируйте с помощью команды ниже

    gcc test.c -framework ApplicationServices

person Eric Chen    schedule 01.09.2011    source источник
comment
То же самое, stackoverflow.com/q/2334022/236738   -  person RLT    schedule 01.09.2011
comment
Не работает в MacOSX 10.11.6 El Capitan, компилируется с предупреждением: «GetFrontProcess» устарел и правильно сообщает о состоянии Caps Lock, но не переключается.   -  person devon    schedule 13.10.2019


Ответы (2)


Вам действительно нужно переключить состояние блокировки заглавных букв или достаточно просто включить / выключить светодиод? Если это просто светодиоды, есть пример кода по адресу:

https://github.com/mikeash/mikeash.com-svn/blob/master/CPUFlash/keyboard_leds.c

Обратите внимание, что он вообще не использует CGEvent — он использует магию IOKit, чтобы напрямую возиться со светодиодами клавиатуры.

person Community    schedule 01.09.2011
comment
По сути, я надеюсь, что смогу изменить состояние блокировки заглавных букв и включить / выключить светодиод вместе. Я попробовал ваш пример кода. Но я нашел одну проблему. Это допустимо только в приложении, которое вызывает этот образец кода. Когда я переключаюсь на другое приложение, индикатор Caps Lock становится асинхронным с вводом с клавиатуры. Надеюсь, я хотел бы знать, есть ли способ реализовать это в osx. В любом случае, спасибо за ваш ответ заранее. - person Eric Chen; 01.09.2011

Ха-ха! Это может быть просто классика. Ваш код завершает работу, потому что он действительно мог делать что угодно. Добавьте несколько sleep(seconds) здесь и там. Также попробуйте установить небольшую задержку (usleep(microseconds)) между событиями down и up.

person TimZaman    schedule 20.03.2016