글로벌 수정 자 키 상태를 모니터링하는 방법 (응용 프로그램에서)?
-
05-07-2019 - |
문제
Cocoa 프로젝트에서 다른 응용 프로그램에서 글로벌 키 이벤트 (바로 가기)를 처리하기 위해 Cocoa 프로젝트에서 카본 코드를 사용하고 있습니다. 현재 나는 a를 설정했다 kEventHotKeyReleased
이벤트 핸들러와 응용 프로그램이 활성화되지 않은 경우 핫 키를 성공적으로 얻을 수 있습니다. 내 응용 프로그램에서 약간의 작업이 발생합니다.
내가 행동하는 문제 kEventHotKeyReleased
이다:
예를 들어 CMD-Shift-P 키 조합을 누릅니다. "P"키를 해제하자마자 핫 키 이벤트가 트리거됩니다. 이벤트를 트리거 할 수 있어야합니다 (또는 수동으로 트리거). 모두 열쇠의 압박감이 없습니다 (예 : CMD 및 Shift 키도 해제됩니다).
핫 키를 모니터링하기는 쉽지만 개별 키 스트로크를 모니터링하는 데 아무것도 보지 못했습니다. 수정 자 키 상태를 모니터링 할 수 있다면 사업을 할 것입니다.
이 작업을 수행하는 방법에 대한 힌트가 있습니까?
미리 감사드립니다!
업데이트:
사용해 보았습니다 kEventRawKeyUp
그리고 kEventRawKeyModifiersChanged
그러나 kEventHotKeyReleased
내가 그 두 사람은 내가와 똑같은 방식으로 설정했지만 작동하지 않습니다. kEventHotKeyReleased
.
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
그만큼 globalHotKeyHandler
방법이 요구됩니다 kEventHotKeyReleased
, 그러나 그렇지 않습니다 kEventRawKeyUp
어떤 이유로 나는 이해할 수없는 것 같습니다. 여기 내 것입니다 globalHotKeyHandler
메소드는 다음과 같습니다.
OSStatus globalHotkeyHandler(EventHandlerCallRef nextHandler, EventRef anEvent, void *userData) {
NSLog(@"Something happened!");
}
추가 전화가 필요하거나 잊어 버린 다른 전화가 있습니까?
NB : 언뜻보기에는 보조 장치에 대한 액세스가 비활성화되었지만 그렇지 않습니다. 그래서 나는 꽤 단서가 없다.
UPDATE 2:
나는 조금 조사했다 CGEventTap
Leibowitzn은 제안했고 나는이 설정을 생각해 냈습니다.
CFMachPortRef keyUpEventTap = CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,kCGEventKeyUp,&keyUpCallback,NULL);
CFRunLoopSourceRef keyUpRunLoopSourceRef = CFMachPortCreateRunLoopSource(NULL, keyUpEventTap, 0);
CFRelease(keyUpEventTap);
CFRunLoopAddSource(CFRunLoopGetCurrent(), keyUpRunLoopSourceRef, kCFRunLoopDefaultMode);
CFRelease(keyUpRunLoopSourceRef);
... 그리고 콜백 :
CGEventRef keyUpCallback (CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
NSLog(@"KeyUp event tapped!");
return event;
}
보시다시피 내가 사용하고 있습니다 kCGEventKeyUp
이벤트 탭의 마스크로서 어떻게 든 받고 있습니다. 마우스 다운 이벤트 ??!??
3 : 업데이트 3.
좋아, 나는이 매개 변수에 cgeventmaskbit (kcgeventkeyup)을 사용한다고 말한 DOC의 줄을 간과 했으므로 올바른 호출은 다음과 같습니다.
CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventKeyUp),&keyUpCallback,NULL);
그래도 여전히 문제가 있습니다 : 수정 자 키는 kcgeventkeyup을 트리거하지 않습니다 ...
UPDATE 4:
좋아, 다시 잊어 버려 ... 오늘 그들에게 물었다.
수정 자 키를 가로 채려면 사용하십시오 kCGEventFlagsChanged
:
CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventFlagsChanged),&callbackFunction,NULL);
본질적으로 나는 키와 수정 자 키 상태 감지가 작동했지만 나는 여전히 알고 싶어합니다 왜 kEventRawKeyUp
작동하지 않습니다...
NB : 또한 새로운 버전의 OS를 최대한 지원한다는 목표로 Tiger를 개발하고 있습니다. CgeventTap은 10.4+ 만 있으므로 지금은 이것을 사용하지만 뒤로 호환되는 솔루션을 환영합니다.
해결책
한 가지 옵션은 EventTaps를 사용하는 것입니다. 이를 통해 모든 키보드 이벤트를 모니터링 할 수 있습니다. 보다:http://developer.apple.com/mac/library/documentation/carbon/reference/quartzeventservicesref/reference/reference.html#//apple_ref/c/func/cgeventtapcreate
불행히도 응용 프로그램이 보안 입력을 요청하는 경우 이벤트 탭이 작동을 중단합니다. 예를 들어 Quicken.
다른 팁
OSStatus err = InstallApplicationEventHandler(&globalHotkeyHandler, GetEventTypeCount(eventTypes), eventTypes, NULL, NULL);
이것은 글로벌이 아닙니다. 이것은 자신의 응용 프로그램이 활성화 된 경우에만 처리기를 설치하고 Carbon Event Manager의 이벤트 필터 후에 (나는 믿습니다).
사용해야합니다 InstallEventHandler
, 이벤트 대상을 첫 번째 매개 변수로 취합니다 (InstallApplicationEventHandler
응용 프로그램 이벤트 대상을 통과하는 매크로입니다).
응용 프로그램이 활성화되지 않은 상태에서 발생하는 이벤트의 경우 원하는 대상은 GetEventMonitorTarget()
. 응용 프로그램 중에 발생하는 이벤트 ~이다 활성, 원하는 대상입니다 GetEventDispatcherTarget()
. 어떤 응용 프로그램이 활성화되어 있든 이벤트를 잡으려면 두 대상에 핸들러를 설치하십시오.
그러나 요즘에는 Leibowitzn이 제안한 것처럼 CgeventTaps를 사용합니다.