Ich verwende etwas Carbon-Code in meinem Cocoa-Projekt, um globale Schlüsselereignisse (Shortcuts) von anderen Anwendungen zu verarbeiten. Derzeit habe ich einen kEventHotKeyReleased
Event-Handler eingerichtet und ich kann Hot Keys erfolgreich erhalten, wenn meine Anwendung nicht aktiv ist. Das löst einige Vorgänge in meiner Anwendung aus.Wie kann der globale Modifier-Key-Status (in einer beliebigen Anwendung) überwacht werden?
Das Problem, das ich mit dem Verhalten von kEventHotKeyReleased
haben ist:
Sagen Sie zum Beispiel drücke ich die Cmd-Shift-P-Tastenkombination. Sobald ich die Taste "P" loslasse, wird das Hotkey-Ereignis ausgelöst. Ich muss in der Lage sein, das Ereignis auszulösen (oder manuell auszulösen), wenn alle der Tasten (d. H .: die Cmd und Shift-Tasten sind ebenfalls freigegeben).
Es ist einfach, für Hotkeys zu überwachen, aber ich habe nichts für die Überwachung einzelner Tastenanschläge gesehen. Wenn ich die Modifier-Key-Zustände überwachen könnte, wäre ich im Geschäft.
Irgendwelche Hinweise, wie das geht?
Vielen Dank im Voraus!
UPDATE:
Ich habe versucht, mit kEventRawKeyUp
und kEventRawKeyModifiersChanged
aber während kEventHotKeyReleased
funktioniert diese beiden nicht, obwohl ich sie in genau der gleichen Art und Weise wie kEventHotKeyReleased
eingerichtet.
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
Die globalHotKeyHandler
Methode wird für kEventHotKeyReleased
genannt, aber nicht für kEventRawKeyUp
aus irgendeinem Grund kann ich nicht zu begreifen scheinen. Hier ist, was meine globalHotKeyHandler
Methode wie folgt aussieht:
OSStatus globalHotkeyHandler(EventHandlerCallRef nextHandler, EventRef anEvent, void *userData) {
NSLog(@"Something happened!");
}
Gibt es einen zusätzlichen Anruf, die gemacht werden muss oder etwas anderes habe ich vergessen?
N. B: Auf den ersten Blick scheint es, wie es, dass Zugriff für Hilfsgeräte deaktiviert ist aber es ist nicht sein könnte. Also bin ich ziemlich ahnungslos.
UPDATE 2:
suchte ich ein bisschen auf dem CGEventTap
Leibowitzn vorgeschlagen und ich kam mit dieser Einrichtung auf:
CFMachPortRef keyUpEventTap = CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,kCGEventKeyUp,&keyUpCallback,NULL);
CFRunLoopSourceRef keyUpRunLoopSourceRef = CFMachPortCreateRunLoopSource(NULL, keyUpEventTap, 0);
CFRelease(keyUpEventTap);
CFRunLoopAddSource(CFRunLoopGetCurrent(), keyUpRunLoopSourceRef, kCFRunLoopDefaultMode);
CFRelease(keyUpRunLoopSourceRef);
... und der Rückruf:
CGEventRef keyUpCallback (CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
NSLog(@"KeyUp event tapped!");
return event;
}
Wie Sie sehen können, verwende ich kCGEventKeyUp
als die Maske für den Event tippen, aber irgendwie bekomme ich mouse down Ereignisse ??! ??
UPDATE 3:
Ok vergessen, dass ich die Linie in dem doc übersehen, daß die CGEventMaskBit (kCGEventKeyUp) für diesen Parameter zu verwenden, so dass der korrekte Aufruf lautet:
CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventKeyUp),&keyUpCallback,NULL);
Ich habe immer noch ein Problem: Modifier-Tasten lösen nicht die kCGEventKeyUp ...
UPDATE 4:
Ok das wieder vergessen ... Ich bin verpflichtet, meine eigenen Fragen 5 Minuten zu beantworten, nachdem sie huh heute fragen!
Zusatztasten abzufangen, verwenden kCGEventFlagsChanged
:
CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventFlagsChanged),&callbackFunction,NULL);
Also im Grunde habe ich den Schlüssel und Zusatztaste Zustandserkennung arbeiten, aber ich weiß, noch interessiert bin, warumkEventRawKeyUp
nicht funktioniert ...
NB: beachten Sie auch, dass ich mit dem Ziel, die Unterstützung für neue und ältere Versionen des OS auf Tiger bin Entwicklung so viel wie möglich. CGEventTap ist nur 10.4+, also werde ich dies jetzt verwenden, aber eine rückwärtskompatible Lösung wäre willkommen.
Ich denke, es gibt eine Möglichkeit, nur Modifikatortasten zu überwachen. Sieh dir den Quellcode im Google Schnellsuchfeld an. Es enthält Code, der erkannt wird, wenn der Benutzer zweimal auf die Befehlsschaltfläche klickt. Siehe: http://www.google.com/codesearch/p?hl=en&sa=N&cd=2&ct=rc#qWBe9JkJhME/trunk/QuickSearchBox/QSB/QSBApplicationDelegate.m&q=modifiersChangedWhileInactive%20package:http://qsb-mac \ .googlecode \.com – Leibowitzn
Ahh, sie registrieren gerade für das folgende Kohlenstoffereignis: {kEventClassKeyboard, kEventRawKeyModifiersChanged} – Leibowitzn
Ich habe bemerkt, kEventRawKeyModifiersChanged und kEventRawKeyUp, aber ich kann nicht scheinen, dass sie arbeiten für das Leben von mir. Siehe das Update in meiner Frage. (Danke für deine Hilfe übrigens!) – Form