Pozdrowienia. Próbuję zrobić aplikację do kontroli dzieci. Rejestrator klawiatury jest częścią tej aplikacji. Używam CGEventTapCreate do oglądania klawiatury. Działa to dobrze, ale czasami zdarza się, że zdarza się zdublowanie kluczowych zdarzeń. Nie mają zestawu [NSEvent isARepeat], tylko duplikaty. Na przykład mogę wpisać "qwerty", ale aplikacja pobiera kluczowe zdarzenia dla tych znaków: "qqwweerrttyy". Może ktoś doświadczył czegoś podobnego? Otrzymuję ten problem na 10.5 & 10.6 (oba są Intel).CGEventTapCreate obserwuje wejście klawiatury w kakao
zamieścić tutaj klawiatury rejestratora zainstalować & metod Handler:
- (BOOL)installKeyboardLogger
{
CGEventMask keyboardMask = CGEventMaskBit(kCGEventKeyDown);
CGEventMask mouseMask = CGEventMaskBit(kCGEventMouseMoved) | CGEventMaskBit(kCGEventLeftMouseDown) |
CGEventMaskBit(kCGEventRightMouseDown);
CGEventMask mask = keyboardMask + mouseMask;// + mouseMask;//CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventMouseMoved);
// Try to create keyboard-only hook. It will fail if Assistive Devices are not set.
mMachPortRef = CGEventTapCreate(
kCGAnnotatedSessionEventTap,
kCGTailAppendEventTap, // kCGHeadInsertEventTap
kCGEventTapOptionListenOnly,
keyboardMask,
(CGEventTapCallBack)eventTapFunction,
self);
if (!mMachPortRef)
[mLogFile logNeedAssistiveDevice: @"Can't install keyboard hook."];
else
CFRelease(mMachPortRef);
mMachPortRef = CGEventTapCreate(
kCGAnnotatedSessionEventTap,
kCGTailAppendEventTap, // kCGHeadInsertEventTap
kCGEventTapOptionListenOnly,
mask,
(CGEventTapCallBack)eventTapFunction,
self);
if (!mMachPortRef)
{
[mLogFile logNeedAssistiveDevice: @"Can't install keyboard&mouse hook."];
return NO;
}
mKeyboardEventSrc = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mMachPortRef, 0);
if (!mKeyboardEventSrc)
return NO;
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
if (!runLoop)
return NO;
CFRunLoopAddSource(runLoop, mKeyboardEventSrc, kCFRunLoopDefaultMode);
return YES;
}
CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
{
if (type != NX_KEYDOWN && type != NX_OMOUSEDOWN && type != NX_OMOUSEUP && type != NX_OMOUSEDRAGGED &&
type != NX_LMOUSEUP && type != NX_LMOUSEDOWN && type != NX_RMOUSEUP && type != NX_RMOUSEDOWN &&
type != NX_MOUSEMOVED && type != NX_LMOUSEDRAGGED && type != NX_RMOUSEDRAGGED)
return event;
NSEvent* sysEvent = [NSEvent eventWithCGEvent:event];
if (type == NX_KEYDOWN && [sysEvent type] == NSKeyDown)
{
if (![sysEvent isARepeat])
[(ControlPanelController*)refcon handleCapturedCharacters: [sysEvent characters]];
}
else
[(ControlPanelController*)refcon handleMouse];
return event;
}
Czy Twoja aplikacja ma interfejs graficzny, z którym korzystają użytkownicy? – Chuck
Tak, to kakao. Nie ma jednak własnej ikony w Docku (aplikacja agenta). – Dmytro
Teraz mam obejście - sprawdzam, czy zduplikowane zdarzenia przychodzą szybciej niż w 0,2 sekundy. – Dmytro