teclas - keypress c# textbox
C#- Verifica si se presiona una tecla especĂfica (3)
Soy nuevo en la programación con C #. Estoy tratando de verificar si se presiona una tecla, pero obtengo estos mensajes de error: "Error 1 El nombre ''Teclado'' no existe en el contexto actual" "Error 2 El nombre ''Clave'' no existe en el contexto actual "¿Puedes decirme cómo solucionarlo?
//...
using System.Windows.Input;
class Main {
public void Main() {
while(true) {
if(Keyboard.IsKeyPressed(Key.A)) {
//...
}
return;
}
}
}
¡El tipo de aplicación no es clara para mí! Si tiene una aplicación de consola, no una de Windows, puede intentar esto:
while (true) {
if (Console.KeyAvailable)
if (Console.ReadKey(true).Key == ConsoleKey.A)
{
// Do something
}
}
y lea esto si quiere tener una tecla de acceso directo global en una aplicación de formularios de Windows: http://www.liensberger.it/web/blog/?p=207
Parece que está intentando crear una tecla de acceso directo global en el sistema y su aplicación debe responder cuando se pulsa.
Necesitará dos funciones API de Win32 RegisterHotKey y UnregisterHotKey .
Si observa el using System.Windows.Input
, parece que está intentando hacer esto con WPF, lo cual es posible.
Comencemos con sus P / Invocaciones bastante básicas:
using System.Runtime.InteropServices;
internal static class NativeMethods
{
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr windowHandle, int hotkeyId, uint modifierKeys, uint virtualKey);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr windowHandle, int hotkeyId);
}
Ahora, cuando registra su Window
, lo que ocurre es que se envía un mensaje WM_HOTKEY a la bomba de mensajes de su aplicación. Sin embargo, WPF abstrae esta bomba de mensajes de usted, por lo que deberá agregar un HwndSourceHook
para aprovecharla.
¿Cómo hacemos todo esto? Comencemos inicializando nuestro delegado HwndSourceHook
. Agregue este fragmento a su MainWindow
:
using System.Windows.Interop;
static readonly int MyHotKeyId = 0x3000;
static readonly int WM_HOTKEY = 0x312;
void InitializeHook()
{
var windowHelper = new WindowInteropHelper(this);
var windowSource = HwndSource.FromHwnd(windowHelper.Handle);
windowSource.AddHook(MessagePumpHook);
}
IntPtr MessagePumpHook(IntPtr handle, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_HOTKEY)
{
if ((int)wParam == MyHotKeyId)
{
// The hotkey has been pressed, do something!
handled = true;
}
}
return IntPtr.Zero;
}
Bien, ahora tenemos todo WM_HOTKEY
para responder al mensaje WM_HOTKEY
. Sin embargo, ¡necesitamos registrar nuestra tecla de acceso directo todavía! Agreguemos otro par de métodos de inicialización:
void InitializeHotKey()
{
var windowHelper = new WindowInteropHelper(this);
// You can specify modifiers such as SHIFT, ALT, CONTROL, and WIN.
// Remember to use the bit-wise OR operator (|) to join multiple modifiers together.
uint modifiers = (uint)ModifierKeys.None;
// We need to convert the WPF Key enumeration into a virtual key for the Win32 API!
uint virtualKey = (uint)KeyInterop.VirtualKeyFromKey(Key.A);
NativeMethods.RegisterHotKey(windowHelper.Handle, MyHotKeyId, modifiers, virtualKey);
}
void UninitializeHotKey()
{
var windowHelper = new WindowInteropHelper(this);
NativeMethods.UnregisterHotKey(windowHelper.Handle, MyHotKeyId);
}
¡Bien! ¿Dónde ponemos esto? ¡No los pongas en el constructor! ¿Por qué? ¡Porque el Handle
será 0
y no válido! Ponlos aquí (en MainWindow
):
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
InitializeHook();
InitializeHotKey();
}
Puede registrar varias teclas rápidas, anular el registro y volver a registrar otras nuevas. Depende de usted. Recuerde que cada tecla de acceso rápido debe tener una ID única registrada. ¡Solo tiene sentido, ya que su gancho de bomba de mensajes debe saber qué tecla de WM_HOTKEY
provocó el mensaje WM_HOTKEY
!
También es una buena práctica anular el registro de todas las teclas rápidas cuando se cierra la aplicación.
Puede usar un gancho de teclado. Mira esto , desde esta respuesta a una pregunta similar :
Los ganchos de teclado globales no son la solución correcta si solo quieres algunas teclas rápidas globales. Un gancho de teclado de alto nivel significa que su dll se inyectará en otras aplicaciones, y no se debe hacer en absoluto en el código administrado. Un gancho de teclado de bajo nivel es un poco mejor, ya que procesa los eventos del teclado en su propia aplicación. Aún así, requiere que cada evento de teclado sea manejado por su hilo.
La función API de Windows RegisterHotKey es mucho más adecuada para eso.
Pero usar un F-Key de smple como hotkey global es problemático ya que podría colisionar con una tecla de acceso rápido local de la aplicación que tiene foco. Por lo tanto, debe configurar las teclas rápidas globales para que el usuario pueda evitar colisiones con sus aplicaciones de uso común.