Procedimiento para modificar eventos de tecla de teclado (Windows Forms para .NET)

Windows Forms permite consumir y modificar la entrada de teclado. Consumir una tecla es controlar una tecla dentro de un método o controlador de eventos para que otros métodos y eventos más abajo en la cola de mensajes no reciban el valor de la tecla. Modificar una tecla es modificar el valor de una tecla para que los métodos y controladores de eventos más abajo en la cola de mensajes reciban un valor de tecla diferente. En este artículo se muestra cómo realizar estas tareas.

Importante

La documentación de la guía de escritorio para .NET 7 y .NET 6 está en proceso de elaboración.

Consumo de una tecla

En un controlador de eventos KeyPress, establezca la propiedad Handled de la clase KeyPressEventArgs en true.

O bien

En un controlador de eventos KeyDown, establezca la propiedad Handled de la clase KeyEventArgs en true.

Nota:

Establecer la propiedad Handled en el controlador de eventos KeyDown no impide que los eventos KeyPress y KeyUp se generen para la pulsación de tecla actual. Use la propiedad SuppressKeyPress para este propósito.

En el ejemplo siguiente se controla el evento KeyPress para consumir las teclas de caracteres A y a. Esas teclas no se pueden escribir en el cuadro de texto:

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == 'a' || e.KeyChar == 'A')
        e.Handled = true;
}
Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs)
    If e.KeyChar = "a"c Or e.KeyChar = "A"c Then
        e.Handled = True
    End If
End Sub

Modificación de una tecla de carácter estándar

En un controlador de eventos KeyPress, establezca la propiedad KeyChar de la clase KeyPressEventArgs en el valor de la nueva tecla de carácter.

En el ejemplo siguiente se controla el evento KeyPress para cambiar las teclas de caracteres A y a a !:

private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyChar == 'a' || e.KeyChar == 'A')
    {
        e.KeyChar = '!';
        e.Handled = false;
    }
}
Private Sub TextBox2_KeyPress(sender As Object, e As KeyPressEventArgs)
    If e.KeyChar = "a"c Or e.KeyChar = "A"c Then
        e.KeyChar = "!"c
        e.Handled = False
    End If
End Sub

Modificación de una tecla que no sea de caracteres

Solo se pueden modificar las pulsaciones de teclas que no sean de caracteres por herencia del control y reemplazo del método PreProcessMessage. Como la entrada Message se envía al control, se procesa antes de que el control genere eventos. Puede interceptar estos mensajes para modificarlos o bloquearlos.

En el ejemplo de código siguiente se muestra cómo usar la propiedad WParam del parámetro Message para cambiar la tecla presionada. Este código detecta una tecla de F1 a F10 y la convierte en una tecla numérica comprendida entre 0 y 9 (donde F10 se asigna a 0).

public override bool PreProcessMessage(ref Message m)
{
    const int WM_KEYDOWN = 0x100;

    if (m.Msg == WM_KEYDOWN)
    {
        Keys keyCode = (Keys)m.WParam & Keys.KeyCode;

        // Detect F1 through F9.
        m.WParam = keyCode switch
        {
            Keys.F1 => (IntPtr)Keys.D1,
            Keys.F2 => (IntPtr)Keys.D2,
            Keys.F3 => (IntPtr)Keys.D3,
            Keys.F4 => (IntPtr)Keys.D4,
            Keys.F5 => (IntPtr)Keys.D5,
            Keys.F6 => (IntPtr)Keys.D6,
            Keys.F7 => (IntPtr)Keys.D7,
            Keys.F8 => (IntPtr)Keys.D8,
            Keys.F9 => (IntPtr)Keys.D9,
            Keys.F10 => (IntPtr)Keys.D0,
            _ => m.WParam
        };
    }

    // Send all other messages to the base method.
    return base.PreProcessMessage(ref m);
}
Public Overrides Function PreProcessMessage(ByRef m As Message) As Boolean

    Const WM_KEYDOWN = &H100

    If m.Msg = WM_KEYDOWN Then
        Dim keyCode As Keys = CType(m.WParam, Keys) And Keys.KeyCode

        Select Case keyCode
            Case Keys.F1 : m.WParam = CType(Keys.D1, IntPtr)
            Case Keys.F2 : m.WParam = CType(Keys.D2, IntPtr)
            Case Keys.F3 : m.WParam = CType(Keys.D3, IntPtr)
            Case Keys.F4 : m.WParam = CType(Keys.D4, IntPtr)
            Case Keys.F5 : m.WParam = CType(Keys.D5, IntPtr)
            Case Keys.F6 : m.WParam = CType(Keys.D6, IntPtr)
            Case Keys.F7 : m.WParam = CType(Keys.D7, IntPtr)
            Case Keys.F8 : m.WParam = CType(Keys.D8, IntPtr)
            Case Keys.F9 : m.WParam = CType(Keys.D9, IntPtr)
            Case Keys.F10 : m.WParam = CType(Keys.D0, IntPtr)
        End Select
    End If

    Return MyBase.PreProcessMessage(m)
End Function

Vea también