2010-04-21 17 views
7

He leído aproximadamente NSPasteBoard en la documentación de Apple, y cómo permite que las aplicaciones escriban en el PasteBoard y permitan que otras aplicaciones lean ese texto y lo usen.¿Cómo pegar texto de una aplicación a otra usando Cocoa?

Podría alguien decirme cómo pegar texto de una aplicación (que se encuentra en la barra de estado) en un NSTextField que está dentro de una aplicación diferente.

Lo que estoy tratando de hacer es algo similar que Snippet y SnippetsApp do.

Si soy completamente estúpido y se perdió la obvia en Docs de Apple, podría por favor que me señale el camino correcto :)

Gracias!

Respuesta

8

Podría alguien decirme cómo pegar texto desde una aplicación (que se encuentra en la barra de estado) en un NSTextField que está dentro de una aplicación diferente.

Pegar es lo que sucede en la aplicación receptora. Escribir en una mesa de trabajo es copiar.

Además, no puede suponer que el usuario querrá pegar en un NSTextField. Puede ser un NSTextView, o un área de texto en un WebView, o un texto Carbon EditText o MLTE, o algún otro editor de texto como un editor de texto Qt o wxWidgets. Incluso pueden estar usando una aplicación con una vista de lista que les permite pegar texto directamente en ella.

Por lo tanto, no hay una forma programática de decirle directamente a una aplicación "aquí hay algo de texto, pégalo, por favor". Tienes que copiarlo en la mesa de trabajo general y luego forjar un evento que generalmente debería causar que la aplicación de más arriba pegue. La sugerencia de Charlie de ⌘V es una forma, aunque engañosa; el diseño de Dvorak coloca a V en otra tecla, mientras que el diseño "Dvorak QWERTY puts" coloca V-with-⌘ (en oposición a V-sin-⌘) en la misma tecla que QWERTY V.

Para forjar ese ⌘V evento, mira en CGEventTap. Tendrá que usar the CGEventCreateKeyboardEvent function para crear el evento en sí mismo, y dado que esa función toma un código de tecla, necesitará buscar el código de clave adecuado para la parte V de la combinación ⌘V, que requerirá pasar por Text Input Source Services o Keyboard Layout Services, según el diseño.

En este momento puede pensar en usar Accesibilidad para encontrar el elemento del menú Pegar en el menú Editar y enviar un mensaje de AXPress, pero "Pegar" y "Editar" son solo palabras en inglés para esos conceptos; si hicieras esto, tu aplicación no funcionaría en ningún otro idioma. Podría ir por orden (tercer menú, sexto elemento del menú), pero luego su aplicación no funcionaría en aplicaciones sin un menú Archivo, o sin un elemento de menú Rehacer, o con dos elementos del menú Deshacer (Photoshop). Forjar un evento ⌘V realmente es el camino a seguir.

+0

CGEventSourceRef no está funcionando mientras que yo he sandboxed mi solicitud. ¿Hay alguna forma de resolver el problema? – iPhoneDv

+0

@iPhoneDv: debe hacer una pregunta por separado con más información sobre lo que está haciendo y qué problema encontró. –

+0

Aquí hay un enlace no roto a la documentación de KeyboardLayoutServices: https://developer.apple.com/legacy/library/documentation/Carbon/Reference/KeyboardLayoutServices/ (Por supuesto, esto aún no fallará si el usuario se ha deshabilitado o cambiado el atajo de teclado para pegar?) – jtbandes

0

En general, la única manera es escribir a la NSPasteboard y luego cambiar a otra aplicación y utilizar algunas funciones de carbono que pulsar "Comando-V" ...

6

Aquí hay un código de trabajo para publicar el ⌘ + evento clave (suponiendo un código clave se conoce):

// some common keycodes 
#define KEY_CODE_x ((CGKeyCode)7) 
#define KEY_CODE_c ((CGKeyCode)8) 
#define KEY_CODE_v ((CGKeyCode)9) 

void DCPostCommandAndKey(CGKeyCode key) 
{ 
    CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); 

    CGEventRef keyDown = CGEventCreateKeyboardEvent(source, key, TRUE); 
    CGEventSetFlags(keyDown, kCGEventFlagMaskCommand); 
    CGEventRef keyUp = CGEventCreateKeyboardEvent(source, key, FALSE); 

    CGEventPost(kCGAnnotatedSessionEventTap, keyDown); 
    CGEventPost(kCGAnnotatedSessionEventTap, keyUp); 

    CFRelease(keyUp); 
    CFRelease(keyDown); 
    CFRelease(source); 
} 
+0

¿Alguna manera de hacer que esto funcione en el modo de espacio aislado? –

+1

@cocoa coder: estoy bastante seguro de que no. –

+0

Hay aplicaciones en la tienda de aplicaciones que pueden pegar datos en otra aplicación haciendo clic en los elementos de una tabla. Preguntándose cómo lo hacen ... –

Cuestiones relacionadas