tecla presionada detectar winapi keyboard low-level

winapi - detectar tecla presionada c#



Entrada de teclado de bajo nivel en Windows (5)

Simplemente use la función nativa GetKeyState, GetAsyncKeyState o GetKeyboardState de la DLL de usuario32.

Puede leer sobre cada función que mencioné anteriormente en el sitio msdn:

h ttp: //msdn.microsoft.com/en-us/library/windows/desktop/ms646301 (v = vs.85) .aspx

para GetKeyState , y

h ttp: //msdn.microsoft.com/en-us/library/windows/desktop/ms646293 (v = vs.85) .aspx

para GetAsyncKeyState , y

h ttp: //msdn.microsoft.com/en-us/library/windows/desktop/ms646299 (v = vs.85) .aspx

para el GetKeyboardState .

Si programa en C #, entonces:

Su código debe incluir la siguiente línea de cualquier declaración de clase, estructura o enum:

using System.Runtime.InteropServices;

Luego, en la clase que tiene el método en el que desea detectar las claves, defina una de las tres funciones anteriores para su elección, o qué funciona y qué no.

[DllImport("user32.dll")] static uint GetKeyState(byte virtualKeyCode); //or [DllImport("user32.dll")] static uint GetAsyncKeyState(byte virtualKeyCode); //or [DllImport("user32.dll")] static uint GetKeyboardState(byte[] virtualKeyCodes); //NOTE: The length of the byte array parameter must be always 256 bytes!

Si no le gusta uint como tipo de devolución, también puede cambiarlo a int .

Si las funciones nativas siempre devuelven 1 como verdadero o 0 como falso, entonces puede cambiar su tipo de devolución a bool , pero si lo hace, entonces creo que debería agregar otra línea de código por encima de la definición de función nativa, que es:

[MarshalAs(UnmanagedType.Bool)]

O puede agregar la siguiente línea en el medio de la definición de función nativa (debajo de la línea donde está la palabra DllImport, y encima de la línea, donde está la palabra ''extern''):

[return: MarshalAs(UnmanagedType.Bool)]

El sitio de Pinvoke ofrece una mejor definición para estas funciones, por lo que no tiene que usar números enteros para mencionar una tecla particular de su teclado, sino una enumeración más comprensible.

El siguiente enlace lleva a la definición de GetKeyState en C #:

h ttp: //www.pinvoke.net/default.aspx/user32.getkeystate

El siguiente enlace conduce a la definición de GetAsyncKeyState en C #

h ttp: //www.pinvoke.net/default.aspx/user32.getasynckeystate

El siguiente enlace conduce a la definición de GetKeyboardState en C #

h ttp: //www.pinvoke.net/default.aspx/user32.getkeyboardstate

Para detectar qué tecla se mantiene presionada (en cualquier momento, en cualquier lugar) y luego llamar a la función GetKeyState o GetAsyncKeyState, en el parámetro único, mencione la clave que desea detectar y luego agregue: & 0x8000 , o & 0x80 después de la llamada. Si la tecla mencionada se mantiene presionada, el valor de retorno de la expresión no es cero, pero de lo contrario es cero. De acuerdo con el número entero devuelto de la expresión, puede determinar qué tecla se mantuvo presionada o no. Tenga en cuenta que si coloca el código dentro de la instrucción if con esa expresión! = 0 como condición de entrada, que está dentro de un bucle, el código en esa instrucción if se ejecutará más de una vez, en realidad muchas veces , cuando mantenga presionada esa tecla. Si desea que se ejecute algún código una vez Cuando presiona una tecla y luego la suelta, el siguiente código es un truco que logra este objetivo:

while (boolean exression that will return false when you want to quit this loop) { if (boolean expression that will return true when particular key is **held down**) //This boolean expression calls either GetKeyState or GetAsyncKeyState with the & 0x8000 or & 0x80 after the call, and then != 0 to check for **held down** key while (true) //It''s purpose is to wait for the same key that was held down to be released. After code execution, it will encounter the break keyword that will finish him, even though that his enter condition is true. if (boolean expression that will return true when the **same** particular key is **NOT** held down! (NOT held down, means that at that time, that key was released). You can copy the same condition from the first if statement, and just change **!=**, which is next to 0, to **==**, or instead add brackets to the condition ''('' and '')'', and in left of ''('' add ''!''). { //Put here the code that you want to execute once, when paticular key was pressed and then released. break; //the while (true), which is the only way to get out of it } }

¿Qué llamadas de win32 se pueden usar para detectar eventos de pulsación de teclas globalmente (no solo para 1 ventana, me gustaría recibir un mensaje CADA vez que se presiona una tecla) desde un servicio de Windows?


Consulte la API de entrada sin procesar en MSDN:

http://msdn.microsoft.com/en-us/library/ms645536(VS.85).aspx

Le permite obtener información de los teclados (entre otras cosas) sin jugar con los ganchos globales. Los ganchos globales solo deben usarse como último recurso, ya que pueden generar consecuencias imprevistas.

El único inconveniente de usar Raw Input es que puede no recibir correctamente las pulsaciones de teclas que genera el software.


Eche un vistazo a los ganchos que puede establecer con SetWindowHookEx:

http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx

Sin embargo, a menos que esté ejecutando un servicio "interactivo", no tendrá acceso al escritorio (y no debería ejecutar un servicio interactivo porque no funcionará correctamente en las versiones más nuevas de Windows). Deberá examinar las API de administración de sesión y escritorio para acceder al escritorio / consola.


Si está implementando esto en una aplicación .NET , le recomendaría GlobalKeyboardHook . De lo contrario, vería su fuente y tomaría lo que necesita, ya que está implementando las funciones de DLLImport mencionadas anteriormente.


Desea utilizar Win32 Hooks. En particular, un gancho de teclado.

Puedes leer más sobre esto aquí

El tipo de enlace que desea es WH_KEYBOARD y puede establecerlo a través de la API de Win32 SetWindowsHookEx.

Básicamente Windows llamará a una función en un dll que usted crea cada vez que se presiona una tecla en cualquier sistema de aplicación.

El gancho llamará a su función que tendrá esta interfaz:

LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam );

Más información sobre esta devolución de llamada aquí .

Con los ganchos de Windows no solo puede rastrear eventos de todo el sistema en todos los procesos, sino que también puede filtrarlos y detenerlos por completo.