2010-12-29 15 views
6

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; 
} 
+0

Czy Twoja aplikacja ma interfejs graficzny, z którym korzystają użytkownicy? – Chuck

+0

Tak, to kakao. Nie ma jednak własnej ikony w Docku (aplikacja agenta). – Dmytro

+0

Teraz mam obejście - sprawdzam, czy zduplikowane zdarzenia przychodzą szybciej niż w 0,2 sekundy. – Dmytro

Odpowiedz

0

Jeśli Twoja pierwsza CGEventTapCreate powiedzie, trzeba jeszcze stworzyć jeszcze jeden z klawiszy + mysza. Czy dlatego otrzymujesz zduplikowane zdarzenie typu key-key?

+0

ahh, właśnie zobaczyłem sygnaturę czasową ... cóż, domyślam się, że naprawiłeś to już teraz :) – tadelv

Powiązane problemy