evento - detectar tecla presionada c#
¿Cómo interceptar todos los eventos del teclado y evitar perder el foco en una aplicación WinForms? (2)
Puede usar la implementación de gancho de teclado de bajo nivel publicada aquí . No debe robar el foco de ningún programa, pero su programa puede ser notificado cuando se presionan las teclas. Este es el código de la publicación en caso de que el enlace deje de funcionar.
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class InterceptKeys
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void Main()
{
_hookID = SetHook(_proc);
Application.Run();
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelKeyboardProc(
int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
Puede manejar las pulsaciones de teclas en el evento HookCallback
(o HookCallback
las partes principales en una clase separada y generar un evento).
Un amigo mío es ciego y tengo la idea de desarrollar un programa que le permita usar una PC con la ayuda de un método de tipeo ciego y comentarios auditivos. La experiencia sería mucho más rica (haciendo uso de más teclas para funciones particulares) e impecable (como evitar pérdidas ocasionales de foco) si mi aplicación pudiera tomar el control total de la entrada del teclado tan pronto como se inicie (lo pondría por la fuerza) en la puesta en marcha para él). Soy un desarrollador de WinForms C # .Net, por lo que me gustaría implementar esto en una aplicación que utiliza este marco de trabajo y lenguaje en particular (sin embargo, no me importan las llamadas envueltas en WinAPI).
PD: No me importa que el sistema tenga control sobre la combinación Ctrl + Ald + Supr, pero me gustaría tomar el control de todas las demás teclas y combinaciones, incluido el logotipo de Windows y los botones de iniciador de aplicaciones estándar.
Sé que este tema es antiguo, pero encontré una posible solución. Puedes usar la última respuesta y editarla un poco:
en lugar de llamar al siguiente enganche
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
simplemente devuelve -1 para detener el procesamiento de cualquier manejador a otros controles
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return -1;
}
Esto no es bueno, pero está funcionando. ¡Ten cuidado con esto!