2011-04-30 11 views
8

He instalado un gancho de teclado:¿Cómo diferenciar entre un evento de teclado tocado por el usuario y uno generado?

CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {

Básicamente quiero tomar grifos de teclado del usuario, coma la entrada, y después de mi propia entrada en lugar.

Así que si toca "g", me gustaría publicar "foo" en el campo de texto.

estoy escribiendo para el campo de texto con CGEventPost y CGEventSetUnicodeString como se encuentra aquí: http://www.mail-archive.com/[email protected]/msg23343.html

El problema es que cada uno de mis caracteres introducidos mediante programación está golpeando el gancho de teclado. Así que no puedo return NULL en el gancho del teclado para bloquear la entrada del usuario ... ¡que también bloquea toda la entrada del programa!

que las diferenciaban en el lado de Windows en C# con la bandera 'inyecta', ver mi pregunta hace un año aquí: How do I use low-level 8 bit flags as conditionals?

Buscando algo similar en Objective-C.

Respuesta

6

Eche un vistazo a los comentarios en CGEventSource.h. Es un poco más fácil juntar la información que usar el Event Services Reference. La larga, pero más correcta, revés parece creating an event source (que está sujeta a las normas de gestión de memoria, que hay que CFRelease si ya está usando antes de la terminación del programa):

myEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate); 

Esto creará su propio fuente de evento privado con una ID única; A continuación, indica que los eventos que cree llegaron desde allí:

CGEventRef myKeyboardEvent = CGEventCreateKeyboardEvent(myEventSource, 
                 keyCode, true); 

Cuando un evento llega, comprobar para ver si es de sí mismo:

if((CGEventGetType(newEvent) == kCGEventKeyDown) && 
    (CGEventGetIntegerValueField(newEvent, kCGEventSourceStateID) == CGEventSourceGetSourceStateID(myEventSource)) { 

También hay un user data field de la fuente que le permita pasarlos alrededor de 64 bits arbitrarios, si es necesario.

La forma más rápida y sucia sería intentar recoger un campo de evento que no es probable que sea un valor significativo para un evento de teclado, como kCGMouseEventPressure y convertirla en una firma:

CGEventSetIntegerValueField(myKeyboardEvent, 
          kCGMouseEventPressure, 
          0xFEEDFACE); 
// The field is an int_64 so you could make the sig longer 
+0

Hmm, la La edición 'rápida y sucia' de MouseEventPressure como se muestra me da el siguiente : kCGErrorIllegalArgument: CGEventSetIntegerValueField: evento no válido – cksubs

+0

@cksubs: ¿Intentó la forma real que mencioné, utilizando el campo de datos del usuario para el origen del evento? –

+0

Tendré otro vistazo a eso esta noche. Me quedé atrapado con eso cuando originalmente hice la pregunta, pero no puedo recordar por qué en este momento. ¿Tienes alguna idea sobre ese error? http://stackoverflow.com/questions/7102883/using-cgeventsetintegervaluefield-to-edit-a-keyboard-event-gives-error – cksubs

Cuestiones relacionadas