Jak monitorować stan klucza modyfikatora globalnego (w dowolnej aplikacji)?

Używam kodu węglowego w moim projekcie Cocoa do obsługi globalnych zdarzeń kluczowych (skrótów) z innych aplikacji. Obecnie mam konfigurację akEventHotKeyReleased obsługa zdarzeń i mogę z powodzeniem uzyskać skróty klawiszowe, gdy moja aplikacja nie jest aktywna. To powoduje pewne działanie w mojej aplikacji.

Mam problem z zachowaniemkEventHotKeyReleased jest:

Powiedz na przykład, że naciskam kombinację klawiszy Cmd-Shift-P. Jak tylko zwolnię klawisz „P”, wyzwalane jest zdarzenie „hot key”.Muszę być w stanie wyzwolić zdarzenie (lub uruchomić je ręcznie), gdywszystko klawiszy nie jest wciśnięty (tj. zwolnione są także klawisze Cmd i Shift).

Łatwo jest monitorować klawisze dostępu, ale nie widziałem nic do monitorowania poszczególnych naciśnięć klawiszy. Gdybym mógł monitorować stan klawiszy modyfikujących, byłbym w biznesie.

Jakieś wskazówki, jak to zrobić?

Z góry dziękuję!

AKTUALIZACJA:

Próbowałem użyćkEventRawKeyUp ikEventRawKeyModifiersChanged ale kiedykEventHotKeyReleased działa te dwa nie, chociaż ustawiam je dokładnie tak samo jakkEventHotKeyReleased.

EventTypeSpec eventTypes[] = {{kEventClassKeyboard, kEventHotKeyReleased}, {kEventClassKeyboard, kEventRawKeyUp}};
// Changing the order in the list does not help, nor does removing kEventHotKeyReleased
OSStatus err = InstallApplicationEventHandler(&globalHotkeyHandler, GetEventTypeCount(eventTypes), eventTypes, NULL, NULL);
// err == noErr after this line

TheglobalHotKeyHandler metoda jest wymaganakEventHotKeyReleased, ale nie dlakEventRawKeyUp z jakiegoś powodu nie mogę pojąć. Oto co mojeglobalHotKeyHandler metoda wygląda następująco:

OSStatus globalHotkeyHandler(EventHandlerCallRef nextHandler, EventRef anEvent, void *userData) {
    NSLog(@"Something happened!");
}

Czy istnieje dodatkowe połączenie, które trzeba wykonać lub coś, o czym zapomniałem?

N.B: Na pierwszy rzut oka wygląda na to, że dostęp do urządzeń wspomagających jest wyłączony, alenie jest. Więc jestem całkiem nieświadomy.

AKTUALIZACJA 2:

Zbadałem trochę na tematCGEventTap Leibowitzn zasugerował i wymyśliłem tę konfigurację:

CFMachPortRef keyUpEventTap = CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,kCGEventKeyUp,&keyUpCallback,NULL);
CFRunLoopSourceRef keyUpRunLoopSourceRef = CFMachPortCreateRunLoopSource(NULL, keyUpEventTap, 0);
CFRelease(keyUpEventTap);
CFRunLoopAddSource(CFRunLoopGetCurrent(), keyUpRunLoopSourceRef, kCFRunLoopDefaultMode);
CFRelease(keyUpRunLoopSourceRef);

... i wywołanie zwrotne:

CGEventRef keyUpCallback (CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
    NSLog(@"KeyUp event tapped!");
    return event;
}

Jak widać, używamkCGEventKeyUp jak maska ​​zdarzenia, ale jakoś to odbieramzdarzenia myszy w dół ??

AKTUALIZACJA 3:

Ok, zapomnij o tym, przeoczyłem wiersz w dokumencie, który powiedział, że używa tego CGEventMaskBit (kCGEventKeyUp), więc prawidłowe połączenie to:

CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventKeyUp),&keyUpCallback,NULL);

Nadal mam problem: klawisze modyfikujące nie wyzwalają kCGEventKeyUp ...

AKTUALIZACJA 4:

Ok, zapomnij o tym jeszcze raz ... Odpowiem na moje pytania będę musiał odpowiedzieć 5 minut po zapytaniu ich dzisiaj, huh!

Aby przechwytywać klawisze modyfikujące, użyjkCGEventFlagsChanged:

CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventFlagsChanged),&callbackFunction,NULL);

Tak więc w istocie udało mi się wykryć stan klucza klucza modyfikującego i modyfikatora, aleNadal jestem zainteresowany poznaniemczemu kEventRawKeyUp nie działa...

N.B: Zauważ również, że pracuję nad Tiger, aby w jak największym stopniu obsługiwać nowe i starsze wersje systemu operacyjnego. CGEventTap ma tylko 10.4+, więc na razie będę go używać, ale rozwiązanie kompatybilne wstecz będzie mile widziane.

questionAnswers(2)

yourAnswerToTheQuestion