c# - teclas - ¿Cómo detectar la tecla presionada actualmente?
evento keydown c# (11)
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.
En Windows Forms , puede conocer, en cualquier momento, la posición actual del cursor gracias a la clase Cursors .
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)?
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<Keys, bool> m_keyTable = new Dictionary<Keys, bool>();
public Dictionary<Keys, bool> 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;
}
}
En WinForms:
if( Form.ModifierKeys == Keys.Shift )
Parece que se ha presionado un duplicado de la pregunta de desbordamiento de pila. La tecla Detectar cambio sin usar eventos en Windows Forms? .
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);
}
}
}
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 Form
- level 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 XAML''s arquitectura de enrutamiento XAML''s eventos XAML''s , 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.
Puede P/Invoke 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.
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.
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.
if ((ModifierKeys == Keys.Control) && ((e.KeyChar & (char)Keys.F) != 0))
{
// CTRL+F pressed !
}
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.
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;