Cómo llamar a .NET Framework desde una aplicación MFC¿Cómo enviar pulsaciones de teclas a otras aplicaciones? Comentarios desactivados en ¿Cómo enviar pulsaciones de teclas Ctrl Alt Del mediante programación? ¿Cómo enviar pulsaciones de teclas Ctrl Alt Del desde una aplicación MFC a otras aplicaciones? Quiero escribir una aplicación que escriba información en otro formulario de aplicación mediante pulsaciones de teclas. ¿Debo enviar mensajes WM_KEYDOWN y WM_KEYUP? ¿Existe una mejor manera? El envío de mensajes WM_KEYDOWN y WM_KEYUP puede funcionar, pero SendInput es una función API diseñada específicamente para este propósito. Sintetiza la entrada, incluidas las pulsaciones de teclas y los eventos del mouse, a través de una matriz de parámetros de la estructura INPUT, donde cada elemento de la matriz de la estructura INPUT corresponde a un evento de entrada, es decir, una pulsación de tecla o una operación del mouse. La estructura INPUT contiene un tipo de unión cuyos miembros son MOUSEINPUT, KEYBDINPUT (o HARDWAREINPUT, para simular un horno de pan). La estructura KEYBDINPUT para la entrada del teclado es la siguiente: struct KEYBDINPUT {WORD wVk; // virt key codeWORD wScan; // hw scan codeDWORD dwFlags // flags-see docDWORD time // marca de tiempo, 0 = dfltULONG_PTR dwExtraInfo; - definido}; Por lo tanto, enviar pulsaciones de teclas a otra aplicación es en realidad sólo una cuestión de crear una matriz INPUT, con cada elemento de la matriz correspondiente a una pulsación de tecla (emergente y presión), y luego llamar a la función SendInput. Para demostrar cómo funciona esto en acción, escribí un pequeño programa llamado Typematic que le permite escribir rápidamente nombres, direcciones, números de teléfono u otra información en un formulario simplemente presionando una tecla de acceso rápido. Esto es perfecto para compradores en línea. Cuando ejecuta Typematic por primera vez, aparecerá un cuadro de diálogo, como se muestra en la Figura 1: Figura 1 Después de presionar el botón "Aceptar", el cuadro de diálogo inicial de Typematic estará oculto. Luego presione T para reactivar Typematic, que muestra el cuadro de diálogo que se muestra en la Figura 2: Figura 2 Typematic reactivado Puede ver que el cuadro de diálogo muestra una lista de abreviaturas. Ingrese "n" para el nombre y "a" para la dirección, y Typematic enviará las cadenas correspondientes al formulario o aplicación actual. Estas abreviaturas se definen en una tabla estática y puede cambiarlas por sus propias abreviaturas: struct ABBREV {TCHAR key; LPCTSTR text;} MYABBREVS[] = {{ _T(''n''), _T("Elmer Fudd" ) }, { _T(''a''), _T("1 Bunny Way ") }, { 0, NULL}} Por supuesto, en el proceso de desarrollo real, no es necesario codificar esta información; proporcione una interfaz de usuario para personalizar esta información y guardarla en un perfil de usuario para que cada usuario de esta máquina pueda tener diferentes configuraciones. Typematic también demuestra algunos otros trucos: cómo registrar teclas de acceso rápido para activar aplicaciones (consulte la columna en el número 12, 2000) y cómo hacer que un control de texto estático acepte entradas de teclado (debe manejar WM_GETDLGCODE y devolver DLGC_WANTCHARS). Typematic define un control de texto estático especializado CStaticAbbrev, que puede mostrar información de abreviaturas y leer teclas de aceleración. El código se muestra en la Figura 3. Cuando el usuario presiona la tecla de acceso rápido.
Typematic se activará y colocará el foco en el control CStaticAbbrev, esperando que se ingresen caracteres. Cuando CStaticAbbrev::OnChar obtiene una clave que coincide con la abreviatura en la tabla, oculta el cuadro de diálogo y llama a la función auxiliar SendString para enviar el texto: // En CStaticAbbrev::OnCharif (/* Encuentra el carácter en la tabla ABBREV * /) { GetParent( )-gt; ShowWindow(SW_HIDE); // Ocultar el cuadro de diálogo SendString(abbrev.text); Cuando Typematic se oculta, Windows restaura automáticamente el foco en la ventana que anteriormente tenía el foco para que la entrada se dirija a las teclas de acceso rápido del usuario. Muy inteligente, ¿no? Si necesita dirigir la entrada a una aplicación o ventana específica, asegúrese de que esté activa antes de llamar a SendInput y llame a la función SetForegroundWindow para lograrlo. Todo el trabajo de enviar pulsaciones de teclas se realiza en SendString, que crea la matriz INPUT y llama a SendInput (consulte la Figura 3). SendString enviará una serie de estructuras KEYDOWN/KEYUP INPUT emparejadas, donde cada carácter de la cadena corresponde a un par de dichas estructuras, que representan una pulsación/pop. Utiliza el indicador KEYEVENTF_UNICODE para enviar la cadena como caracteres Unicode. Es más fácil trabajar con Unicode porque no es necesario usar la tecla Shift para formar caracteres en mayúsculas. Sin KEYEVENTF_UNICODE, debes enviar una E mayúscula, seguida de una e. Cada personaje tiene un evento arriba/abajo, *** y cuatro pulsaciones de teclas. Enviar pulsaciones de teclas es más fácil si programa en Managed C u otro lenguaje en Microsoft .NET Framework. Existe una clase de marco llamada SendKeys cuya función estática Enviar hace que enviar pulsaciones de teclas sea muy sencillo. Incluso puedes enviar pulsaciones de teclas especializadas utilizando una sintaxis sofisticada. Por ejemplo, utilice "{F1}{BACKSPACE}A " para enviar F1, Retroceso y A. Por lo tanto, también escribí una versión .NET de Typematic llamada Typematic.NET que usa SendKeys. Se ve así: #pragma administradovoid SendString(LPCTSTR str) {SendKeys::SendWait(str);} ¿Hay algo más simple que esto? Cuando comencé a hacer esto, naturalmente intenté usar SendKeys::Send en lugar de SendWait, ¿por qué debería esperar a que la aplicación termine de consumir las claves? Lamentablemente, Typematic falló cuando lo probé, con una excepción System.InvalidOperationException en algún lugar de Windows.Forms.dll. Cuando inicié el depurador de Common Language Runtime (CLR) para ver por qué, la ventana de salida mostró lo siguiente: "Información adicional: SendKeys no se puede ejecutar en esta aplicación porque no puede manejar mensajes de Windows. Deje que la aplicación Para manejar el mensaje, use el método SendKeys.SendWait." ¡Eso es lo que yo llamo un mensaje de error amigable! Tomemos esto como ejemplo. Sin embargo, antes de utilizar SendKeys, tenga en cuenta: no es tan estable como SendInput.