Język

Jak obsługiwać komunikaty wejściowe klawiatury w formularzu

Formularze systemu Windows umożliwiają obsługę komunikatów klawiaturowych na poziomie formularza, zanim komunikaty dotrą do kontrolki. W tym artykule pokazano, jak wykonać to zadanie.

Obsługa komunikatu klawiaturowego

Obsłuż zdarzenie KeyPress lub KeyDown aktywnego formularza i ustaw właściwość KeyPreview formularza na true. Ta właściwość powoduje, że dane wejściowe klawiatury docierają do formularza, zanim dotrą do wszystkich kontrolek w formularzu. Poniższy przykład kodu obsługuje zdarzenie typu KeyPress, wykrywając wszystkie klawisze numeryczne i konsumując 1, 4oraz 7.

// Detect all numeric characters at the form level and consume 1, 4, and 7.
// Form.KeyPreview must be set to true for this event handler to be called.
void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (char.IsDigit(e.KeyChar))
    {
        MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.");

        switch (e.KeyChar)
        {
            case '1':
            case '4':
            case '7':
                MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.");
                e.Handled = true;
                break;
        }
    }
}
' Detect all numeric characters at the form level and consume 1, 4, and 7.
' Form.KeyPreview must be set to true for this event handler to be called.
Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs)
    If Char.IsDigit(e.KeyChar) Then
        MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.")

        Select Case e.KeyChar
            Case "1"c, "4"c, "7"c
                MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.")
                e.Handled = True
        End Select
    End If

End Sub

Kiedy KeyPreview jest za mało

Ustawienie Form.KeyPreview = true nie gwarantuje, że każde naciśnięcie klawisza trafi do procedur obsługi zdarzeń na poziomie formularza. Niektóre klawisze są wstępnie przetwarzane, zanim zostaną uruchomione standardowe zdarzenia formularza. Zrozumienie tych wyjątków jest ważne w przypadku prawidłowego obsługi kluczy poleceń, kluczy dialogowych i danych wejściowych specyficznych dla sterowania.

Wstępne przetwarzanie klawiszy poleceń i okien dialogowych

Zanim zostaną wywołane zdarzenia klawiatury na poziomie formularza, system Windows wstępnie przetwarza niektóre klawisze przy użyciu następujących metod (w kolejności):

  1. ProcessCmdKey: przechwytuje klawisze poleceń sterujących, takie jak skróty menu i klawisze przyspieszające. Jeśli ta metoda zwróci true, klawisz zostanie przechwycony i nie zostanie wywołane żadne zdarzenie.
  2. IsInputKey: określa, czy klawisz powinien wywołać zdarzenie KeyDown, czy przejść do ProcessDialogKey.
  3. ProcessDialogKey: obsługuje klucze nawigacji (klawisz Escape, Tab, Return i arrow). W przypadku przetworzenia żadne zdarzenie nie zostanie wyzwolony.

Jeśli kontrolka, która ma fokus, przechwytuje klawisz na etapie przetwarzania wstępnego, formularz nigdy go nie otrzyma, niezależnie od KeyPreview.

Przypadki szczególne omijające procedury obsługi na poziomie formularza

  • Enter i Escape: te klawisze mogą być obsługiwane przez AcceptButton i CancelButton, zanim dotrą do zdarzeń formularza.
  • Tab: często jest przechwytywany przez mechanizmy zarządzania fokusem kontrolek i nie dociera do modułów obsługi formularzy.
  • Skróty menu: kombinacje klawiszy Alt są obsługiwane przez wstępne przetwarzanie poleceń menu.

Przechwytywać klawisze poleceń na poziomie formularza

Aby obsługiwać klawisze poleceń (w tym skróty menu i klawisze okien dialogowych) na poziomie formularza, przesłoń metodę ProcessCmdKey w formularzu. Jest to uruchamiane podczas przetwarzania wstępnego przed zdarzeniami formularza standardowego.

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    // Intercept Ctrl+A for custom handling
    if (keyData == (Keys.Control | Keys.A))
    {
        MessageBox.Show("Ctrl+A intercepted at form level");
        return true; // Mark as handled
    }

    // Pass other keys to the base handler
    return base.ProcessCmdKey(ref msg, keyData);
}
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
    ' Intercept Ctrl+A for custom handling
    If keyData = (Keys.Control Or Keys.A) Then
        MessageBox.Show("Ctrl+A intercepted at form level")
        Return True ' Mark as handled
    End If

    ' Pass other keys to the base handler
    Return MyBase.ProcessCmdKey(msg, keyData)
End Function

W przypadku klawiszy, które powinny wywoływać standardowe zdarzenia w określonym formancie, użyj elementu PreviewKeyDown, ustawiając w tym formancie wartość IsInputKey na true.

Zobacz także