글로벌 수정 자 키 상태를 모니터링하는 방법 (응용 프로그램에서)?

StackOverflow https://stackoverflow.com/questions/1603030

  •  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를 사용합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top