2010-12-29 19 views
6

Saludos. Intento hacer una aplicación de control para niños. El registrador de teclado es una parte de esta aplicación. Uso CGEventTapCreate para mirar el teclado. Esto funciona bien, pero a veces obtengo la duplicación de eventos clave. No tienen [NSEvent isARepeat] establecido, solo duplicados. Por ejemplo, puedo escribir "qwerty" pero la aplicación obtiene eventos de tecla para estos caracteres: "qqwweerrttyy". Tal vez alguien experimentado algo así? Obtengo este problema en 10.5 & 10.6 (ambos son Intel).CGEventTapCreate está viendo la entrada del teclado en Cocoa

he puesto aquí registrador de teclado instalar & métodos de controlador:

- (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

¿Su aplicación tiene una interfaz gráfica con la que los usuarios interactúan? – Chuck

+0

Sí, es Cocoa. Sin embargo, no tiene un ícono propio en Dock (aplicación agente) – Dmytro

+0

Ahora tengo una solución alternativa: verifico si los eventos de duplicación son más rápidos que en 0.2 segundos. – Dmytro

Respuesta

0

Si su primer CGEventTapCreate tiene éxito, todavía se crea otra con las teclas + ratón. ¿Es por eso que obtienes eventos duplicados?

+0

ahh, acabo de ver la marca de tiempo ... bueno, supongo que lo arregló por ahora :) – tadelv

Cuestiones relacionadas