2010-03-04 7 views
13

Estoy escribiendo una aplicación donde necesito simular eventos de pulsación de tecla en una Mac, dado un código que representa cada tecla. Parece que necesito usar la función CGEventCreateKeyboardEvent para crear el evento. El problema es que esta función necesita un código clave Mac, y lo que tengo es un código que representa la clave específica. Entonces, por ejemplo, recibo:Simulación de eventos de pulsación de tecla en Mac OS X

KEY_CODE_SHIFT o KEY_CODE_A - estas son ambas constantes numéricas definidas en alguna parte.

Necesito tomar estas constantes y convertirlas en valores CGKeyCode.

Mi intento actual utiliza un código similar al this SO question. El problema es que solo funciona para caracteres imprimibles. Si todo lo demás falla, no estoy por encima de la codificación difícil de la conversión, pero eso significaría que necesitaría una tabla de posibles valores CGKeyCode, que aún no he podido encontrar.

¿Alguna idea?

Respuesta

24

Aquí está el código para simular una Cmd - S acción:

CGKeyCode inputKeyCode = kVK_ANSI_S; 
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); 
CGEventRef saveCommandDown = CGEventCreateKeyboardEvent(source, inputKeyCode, YES); 
CGEventSetFlags(saveCommandDown, kCGEventFlagMaskCommand); 
CGEventRef saveCommandUp = CGEventCreateKeyboardEvent(source, inputKeyCode, NO); 

CGEventPost(kCGAnnotatedSessionEventTap, saveCommandDown); 
CGEventPost(kCGAnnotatedSessionEventTap, saveCommandUp); 

CFRelease(saveCommandUp); 
CFRelease(saveCommandDown); 
CFRelease(source); 

Un CGKeyCode es nada más que un entero sin signo:

typedef uint16_t CGKeyCode; //From CGRemoteOperation.h 

Su verdadero problema será girar un carácter (probablemente un NSString) en un código clave. Afortunadamente, el proyecto Shortcut Recorder tiene un código que hará exactamente eso en el archivo SRKeyCodeTransformer.m. Es genial para transformar una cadena en un código clave y viceversa.

+0

Entonces, en este ejemplo, ¿el 'CGKeyCode' de' 1' es el código para S? Además, ¿funcionaría esto solo para una aplicación de primer plano, o si se ejecutara en segundo plano, funcionaría en toda la sesión? Gracias – joec

+0

@joec sí a todos esos. –

+0

Entonces, por ejemplo, si mi aplicación se ejecutaba en segundo plano (solo como un servicio) y tenía Photoshop al frente, podía simular una pulsación de tecla, y ¿se vería en Photoshop? Gracias – joec

2

Sólo en caso de que alguien necesita una versión Swift:

XCode 7.3 y Swift 2.2:

let event1 = CGEventCreateKeyboardEvent(nil, 0x09, true); // cmd-v down 
CGEventSetFlags(event1, CGEventFlags.MaskCommand); 
CGEventPost(CGEventTapLocation.CGHIDEventTap, event1); 

let event2 = CGEventCreateKeyboardEvent(nil, 0x09, false); // cmd-v up 
CGEventSetFlags(event2, CGEventFlags.MaskCommand); 
CGEventPost(CGEventTapLocation.CGHIDEventTap, event2); 

Código encima simula CMD-V prensa entonces liberado (También conocido como: pasta).