2010-01-14 16 views
8

me encontré con este código de enlace de teclado, lo que estoy tratando de modificar ligeramente para mis propósitos: http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspx¿Puedo cambiar la entrada del teclado de un usuario?

Como una visión general, yo quiero tener el usuario pulse una tecla, por ejemplo 'E', y tienen el retorno del teclado un personaje diferente, 'Z', a cualquier aplicación que esté enfocada.

El método relevante he cambiado se ve ahora como:

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
    { 
     if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
     { 
      //The truely typed character: 
      int vkCode = Marshal.ReadInt32(lParam); 
      Console.WriteLine((Keys)vkCode); 

      KBDLLHOOKSTRUCT replacementKey = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); 
      replacementKey.vkCode = 90; // char 'Z' 
      Marshal.StructureToPtr(replacementKey, lParam, false); 

      //Now changed to my set character 
      vkCode = Marshal.ReadInt32(lParam); 
      Console.WriteLine((Keys)vkCode); 
     } 
     return CallNextHookEx(_hookID, nCode, wParam, lParam); 
    } 

La consola emite correctamente esto como:

E 
Z 
T 
Z 
G 
Z 
etc. 

Sin embargo, 'E' los de aplicación enfoque todavía tipos en lugar de 'Z' . ¿Por qué? Cambié la entrada del teclado enganchado para contener 'Z' en lugar de 'E', ¡y las líneas de la consola muestran que se cambió correctamente!

Según tengo entendido, llamar al return CallNextHookEx(_hookID, nCode, wParam, lParam); es lo que envía el comando "imprimir ahora" a la aplicación abierta. ¿No es así como funciona? ¿Hay algo que me impida escribir el personaje que quiero? Sé que aplicaciones como AutoHotkey toman una tecla de entrada, la comprueban y devuelven un personaje diferente. ¿Cómo hago lo mismo aquí?

Gracias!

+3

por curiosidad, ¿cuál es la aplicación de esto? –

+1

¡No es un keylogger! :) La aplicación es tecnología de asistencia.Piensa en el teclado del iPhone; detrás de escena, modifica el área clave, corrige los errores obvios y ejecuta otro código inteligente para ayudarlo a escribir más rápido y con mayor precisión. Esta es una aplicación similar, pero para teclados completos. – cksubs

Respuesta

5

He hecho esto antes, pero un poco diferente.
En lugar de intentar cambiar los parámetros enviados a CallNextHookEx, 'tragué' la tecla presionada (puede hacer esto devolviendo un valor distinto de cero del procedimiento de enlace para evitar que se llamen procedimientos posteriores).

Luego usé SendInput para enviar la nueva clave que quería 'inyectar'.

Así que básicamente funciona así:

  • procedimiento de enlace identifica una clave de destino se presiona
  • llamada a SendInput, con la nueva clave
  • Retorno 1 del procedimiento de enlace de ignorar la llave original

Tenga cuidado de redirecciones cíclicos, es decir, 'a' redirigido a 'b' redirigido a 'a', que puede soplar fácilmente hasta;)

+0

Genial, ignoré con éxito la clave original con return '(IntPtr) 1;' Ahora, ¿cómo hago 'SendInput'? ¿Es necesario incluir un 'using XXX' específico en el encabezado u otro código que necesite agregar para usar el comando? – cksubs

+0

pinvoke.net tiene todo el código necesario para llamar a 'SendInput' - http://www.pinvoke.net/default.aspx/user32/SendInput.html –

+0

Ok, lo obtuve usando' [DllImport ("coredll.dll", SetLastError = true)] static Extern uint SendInput (uint cInputs,/* [MarshalAs (UnmanagedType.LPArray)] */KEYBOARDINPUT [] entradas, int cbSize); 'y una estructura KEYBOARDINPUT. Ahora estoy trabajando en pasar SendInput() los parámetros correctos. – cksubs

0

Lo más probable es que haya instalado el gancho "de rosca" y no "todo el sistema", lo que significa que la traducción de la llave ocurrirá solo para la rosca que instala el gancho.

Para instalarlo "en todo el sistema" necesitará dos piezas: una dll con el "proveedor de anzuelo" y un administrador de la misma. Aquí es un buen tutorial http://www.codeproject.com/KB/system/hooksys.aspx y aquí un ejemplo: http://www.codeguru.com/cpp/com-tech/shell/article.php/c4509/

Pero: 1. Instalación del sistema de ancho ganchos pueden atornillar en serio hasta que el sistema (asegúrese de que reenvía las teclas que no se traduce) . 2. Por favor ... no cree otro keylogger

+2

Utiliza el gancho del teclado de bajo nivel, no el gancho ordinario del teclado. El gancho de bajo nivel no necesita un dll separado que se carga en cada proceso. Desde http://msdn.microsoft.com/en-us/library/ms644985.aspx - Sin embargo, el enlace WH_KEYBOARD_LL no se inyecta en otro proceso. En cambio, el contexto vuelve al proceso que instaló el enlace y se llama en su contexto original. Luego, el contexto vuelve a la aplicación que generó el evento. –

+0

Entonces ... ¿eso significa que estoy usando esto correctamente? :) – cksubs

+0

Mucha información sobre la implementación/uso de WH_KEYBOARD_LL (y mucha discusión sobre problemas para detectar modificadores de control, pasar información clave a la siguiente aplicación o bloqueo, etc. en los comentarios) CodeProject: http: // www. codeproject.com/KB/system/CSLLKeyboard.aspx "Ganchos de Windows API de bajo nivel de C# para detener las pulsaciones de teclas no deseadas" Por Emma Burrows. Artículo de 2007 – BillW

Cuestiones relacionadas