visual teclado tecla presionada formulario eventos evento detectar c#

c# - teclado - ¿Se presiona la tecla Detectar Shift sin usar eventos en Windows Forms?



eventos del teclado java (4)

Necesito poder detectar que se está reteniendo la tecla shift, pero no quiero usar eventos o variables globales para determinar eso. ¿Hay una API en C # que le permite preguntar qué teclas están presionadas actualmente en lugar de usar el evento?


if ((Control.ModifierKeys & Keys.Shift) != 0)

Esto también será true si otra tecla modificadora también está abajo (por ejemplo, Ctrl + Shift). Si desea comprobar si Shift solo se presiona sin ningún otro modificador, utilice

if (Control.ModifierKeys == Keys.Shift)

Tenga en cuenta que incluso esto será true si otro no modificador está inactivo (por ejemplo, Shift + A). Si desea verificar si Shift y solo Shift están presionados, tendrá que usar una llamada API.

Si está en una clase que hereda Control (como un formulario), puede eliminar el calificador de Control . (las propiedades static no necesitan calificadores en las clases heredadas)


Form.ModifierKeys (propiedad estática)


Puede instalar un gancho de teclado de bajo nivel .

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); }


No estoy seguro si está disponible en C # pero puede llamar a GetAsyncKeyState . Este método devuelve el estado de una clave en el momento en que se llama al método.

Para llamarlo desde C # necesitarás usar la interoperabilidad como cualquier otra API de Win32.