¿Cómo detectar la tecla presionada actualmente?

En Windows Forms , puede conocer, en cualquier momento, la posición actual del cursor gracias a la clase Cursores .

Lo mismo no parece estar disponible para el teclado. ¿Es posible saber si, por ejemplo, se presiona la tecla Shift ?

¿Es absolutamente necesario rastrear cada notificación de teclado (eventos KeyDown y KeyUp)?

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

    Esto también será cierto si Ctrl + Shift está abajo. Si desea verificar si Shift solo está presionado,

     if (Control.ModifierKeys == Keys.Shift) 

    Si estás en una clase que hereda Control (como un formulario), puedes eliminar el Control.

    El siguiente código es cómo detectar casi todas las teclas presionadas actualmente, no solo la tecla Shift .

     private KeyMessageFilter m_filter = new KeyMessageFilter(); private void Form1_Load(object sender, EventArgs e) { Application.AddMessageFilter(m_filter); } public class KeyMessageFilter : IMessageFilter { private const int WM_KEYDOWN = 0x0100; private const int WM_KEYUP = 0x0101; private bool m_keyPressed = false; private Dictionary m_keyTable = new Dictionary(); public Dictionary KeyTable { get { return m_keyTable; } private set { m_keyTable = value; } } public bool IsKeyPressed() { return m_keyPressed; } public bool IsKeyPressed(Keys k) { bool pressed = false; if (KeyTable.TryGetValue(k, out pressed)) { return pressed; } return false; } public bool PreFilterMessage(ref Message m) { if (m.Msg == WM_KEYDOWN) { KeyTable[(Keys)m.WParam] = true; m_keyPressed = true; } if (m.Msg == WM_KEYUP) { KeyTable[(Keys)m.WParam] = false; m_keyPressed = false; } return false; } } 

    También puede ver lo siguiente si hace referencia a System.Windows.Input

     if (Keyboard.Modifiers == ModifierKeys.Shift) 

    El espacio de nombres del teclado también se puede usar para verificar el estado presionado de otras teclas con Keyboard.IsKeyDown (Key), o si se está suscribiendo a un evento KeyDownEvent o similar, los argumentos del evento llevan una lista de las teclas presionadas actualmente.

    La mayoría de estas respuestas son demasiado complicadas o no parecen funcionar para mí (por ejemplo, System.Windows.Input no parece existir). Luego encontré un código de muestra que funciona bien: http://www.switchonthecode.com/tutorials/winforms-accessing-mouse-and-keyboard-state

    En caso de que la página desaparezca en el futuro, estoy publicando el código fuente relevante a continuación:

     using System; using System.Windows.Forms; using System.Runtime.InteropServices; namespace MouseKeyboardStateTest { public abstract class Keyboard { [Flags] private enum KeyStates { None = 0, Down = 1, Toggled = 2 } [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] private static extern short GetKeyState(int keyCode); private static KeyStates GetKeyState(Keys key) { KeyStates state = KeyStates.None; short retVal = GetKeyState((int)key); //If the high-order bit is 1, the key is down //otherwise, it is up. if ((retVal & 0x8000) == 0x8000) state |= KeyStates.Down; //If the low-order bit is 1, the key is toggled. if ((retVal & 1) == 1) state |= KeyStates.Toggled; return state; } public static bool IsKeyDown(Keys key) { return KeyStates.Down == (GetKeyState(key) & KeyStates.Down); } public static bool IsKeyToggled(Keys key) { return KeyStates.Toggled == (GetKeyState(key) & KeyStates.Toggled); } } } 

    Desde .NET Framework versión 3.0, es posible utilizar el método Keyboard.IsKeyDown desde el nuevo espacio de nombres System.Windows.Input . Por ejemplo:

     if (((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) && Keyboard.IsKeyDown(Key.F)) { // CTRL + F is currently pressed } 

    Aunque es parte de WPF, ese método funciona bien para las aplicaciones WinForm (siempre que agregue referencias a PresentationCore.dll y WindowsBase.dll ). Desafortunadamente, sin embargo, las versiones 3.0 y 3.5 del método Keyboard.IsKeyDown no funcionaron para las aplicaciones WinForm. Por lo tanto, si desea utilizarlo en una aplicación WinForm, deberá estar orientando .NET Framework 4.0 o posterior para que funcione.

    Puede P / Invocar en el Win32 GetAsyncKeyState para probar cualquier tecla en el teclado.

    Puede pasar valores desde la clave Enum (por ejemplo, Keys.Shift) a esta función, por lo que solo se necesitan un par de líneas de código para agregarla.

     if ((ModifierKeys == Keys.Control) && ((e.KeyChar & (char)Keys.F) != 0)) { // CTRL+F pressed ! } 
     if (Form.ModifierKeys == Keys.Shift) 

    funciona para un cuadro de texto si el código anterior está en el evento de selección del formulario y ningún otro control captura el evento de selección para la tecla hacia abajo.

    También es posible que desee detener el procesamiento de claves adicionales con:

     e.Handled = true; 
     if (Control.ModifierKeys == Keys.Shift) //Shift is pressed 

    La posición del cursor x / y es una propiedad y una pulsación de tecla (como un clic / mousemove del mouse) es un evento. La mejor práctica es generalmente permitir que la interfaz sea impulsada por eventos. La única vez que necesitaría lo anterior es si está tratando de hacer un cambio + clic con el mouse.

    La mejor manera que he encontrado para administrar la entrada de teclado en un formulario de Windows Forms es procesarlo después de la pulsación de tecla y antes de que el control enfocado reciba el evento. Microsoft mantiene una propiedad Formlevel incorporada llamada .KeyPreview para facilitar esta cosa precisa:

     public frmForm() { // ... frmForm.KeyPreview = true; // ... } 

    Luego, los eventos _KeyDown, _KeyPress y / o _KeyUp del formulario se pueden calcular para acceder a los eventos de entrada antes de que el control de formulario enfocado los vea, y puede aplicar la lógica del controlador para capturar el evento allí o permitir que pase al control de formulario enfocado .

    Aunque no es tan elegante desde el punto de vista estructural como la architecture de enrutamiento de eventos de XAML , hace que la administración de las funciones a nivel de formulario en Winforms sea mucho más simple. Consulte las notas de MSDN en KeyPreview para advertencias.

    En WinForms:

     if( Form.ModifierKeys == Keys.Shift ) 

    Parece que se ha presionado un duplicado de la pregunta de desbordamiento de stack. La tecla Detectar cambio sin usar eventos en Windows Forms? .