2008-10-05 29 views
8

Estoy escribiendo un programa de C# que captura señales de un dispositivo externo y envía pulsaciones de teclas a otra aplicación. Estoy usando SendKeys y funciona bien.¿Cómo presionar una tecla y soltarla usando C#?

SendKeys "presiona" una tecla sosteniéndola y soltándola inmediatamente. Me gustaría hacer que presione la tecla y soltarlo a voluntad.

Mi pregunta es: "¿hay alguna manera de enviar una señal de" empuje "a una tecla, luego una señal de" liberación "después de un cierto período de tiempo?"

No estoy seguro de que SendKeys pueda hacer esto. Cualquier pista ?

Respuesta

3

Puede usar SendInput o keyb_event, ambas son funciones API nativas. SendInput tiene algunas ventajas sobre keybd_event, pero SendInput solo está disponible comenzando con XP.

Aquí está el enlace de MSDN http://msdn.microsoft.com/en-us/library/ms646310.aspx

Esperanza esto ayuda

1

Una vez estaba buscando hacer lo mismo en PowerPoint, para ocultar el cursor, y más tarde para detener la presentación. Pero es difícil y complicado ya que hay muchas ventanas de primer nivel en PowerPoint, y también es difícil determinar qué parte de la emulación falló si no funciona. Después de examinar la cola de mensajes usando Spy ++, noté que el comando del acelerador se envió después de la pulsación de tecla, así que en su lugar, emulé el comando del acelerador, y funciona como el amuleto. Así que es posible que desee buscar alternativas como esta.

4

La respuesta aceptada usa keybd_event que está en desuso. La API oficial ahora es SendInput. También hay una buena envoltura para él en http://inputsimulator.codeplex.com.

Ninguno de los anteriores, sin embargo, satisface completamente el escenario de "retención de tecla". Esto se debe al hecho de que mantener presionada una tecla generará múltiples mensajes WM_KEYDOWN, seguidos de un mensaje único WM_KEYUP al momento de la publicación (puede verificar esto con Spy ++).

La frecuencia de los mensajes WM_KEYDOWN depende del hardware, la configuración del BIOS y un par de configuraciones de Windows: KeyboardDelay y KeyboardSpeed. Los últimos son accesibles desde Windows Forms (SystemInformation.KeyboardDelay, SystemInformation.KeyboardSpeed).

Utilizando la biblioteca de Input Simulator mencionada, he implementado un método de retención de teclas que imita el comportamiento real. Está await/async listo, y admite la cancelación.

static Task SimulateKeyHold(VirtualKeyCode key, int holdDurationMs, 
          int repeatDelayMs, int repeatRateMs, CancellationToken token) 
{ 
    var tcs = new TaskCompletionSource<object>(); 
    var ctr = new CancellationTokenRegistration(); 
    var startCount = Environment.TickCount; 
    Timer timer = null; 
    timer = new Timer(s =>   
    { 
     lock (timer) 
     { 
      if (Environment.TickCount - startCount <= holdDurationMs) 
       InputSimulator.SimulateKeyDown(key); 
      else if (startCount != -1) 
      { 
       startCount = -1; 
       timer.Dispose(); 
       ctr.Dispose();      
       InputSimulator.SimulateKeyUp(key); 
       tcs.TrySetResult(null); 
      } 
     } 
    }); 
    timer.Change(repeatDelayMs, repeatRateMs); 

    if (token.CanBeCanceled) 
     ctr = token.Register(() => 
         { 
          timer.Dispose(); 
          tcs.TrySetCanceled(); 
         }); 
    return tcs.Task; 
} 
+0

Muchas gracias por esta valiosa información. – Larry

+0

De nada, valiosa información es de lo que estoy hablando;) –

Cuestiones relacionadas