Sonntag, 5. Dezember 2010

Tastendruck von mehreren Tasten gleichzeitig prüfen

In den Methoden KeyDown() und KeyPress(), die nahezu jedes Steuerelement implementiert, können Tastaturereignisse untersucht werden.
Der Parameter e vom Typ KeyEventArgs stellt die hierfür benötigten Methoden und Eigenschaften bereit.
So kann z.B. über e.KeyCode geprüft werden, welche Taste gedrückt wurde.
Werden mehrere Tasten (gleichzeitig) gedrückt, wird für jede Taste ein Ereignis aufgerufen, was aber nicht hilft, wenn man den Druck von Tastenkombinationen abfragen möchte.
In diesem Post beschreibe ich, wie man diese Fälle mittels der Eigenschaft KeyData bzw. Flags abdeckt, wobei diese Methoden nur funktionieren, wenn die Kombinationen nur aus Alt und / oder Shift und / oder Strg und / oder maximal einer anderen Taste besteht.
Zuerst über KeyData:
Diese Eigenschaft wird in 4 Bytes gespeichert, die unteren beiden geben die gedrückte Taste wieder, die oberen beiden die gedrückten Funktionstasten (Alt, Shift, Strg (Control)).
Werden mehrere Tasten drückt, werden die Byte - Werte Oder verknüpft.
Drückt man nun nur die Zustandstasten und maximal eine andere Taste, erhält man in KeyData eine eindeutige Bitkombination. Es sollte allerdings klar sein, dass die Eindeutigkeit beim Drücken von mehreren "normalen" Taste nicht mehr gewährleistet ist, da die Bits sich dann überschneiden können.
Zum Prüfen der gedrückten Kombination wird der Wert aus e.KeyData mit einer bitweisen Oder - Verknüpfung des gewünschten Wertes verglichen.
Folgendes Beispiel beendet das Programm, wenn die Tastenkombination Strg + Shift + Alt + "E" gedrückt wurde.

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyData == (Keys.Shift | Keys.Alt | Keys.Control | Keys.E))
        this.Close();
}

Das gleiche Ergebnis lässt sich aber auch erreichen, wenn man über e.KeyCode die gedrückte Taste abfragt und zusätzlich noch die Eigenschaften e.Shift, e.Alt und e.Control überprüft (diese Eigenschaften sind sogenannte Flags), die angeben, ob die entsprechenden Funktionstasten gedrückt sind:

if (e.KeyCode == Keys.E && e.Shift && e.Alt && e.Control)
    this.Close();

Kommentare:

  1. funktioniert bei mir aber nur bei
    z.B. strg + taste
    nicht bei 2 tasten wie z.B. I und A
    woran liegt denn das?
    wie kann man das beheben?

    AntwortenLöschen
  2. Hi,
    wie im Post beschrieben sind obige Methoden nur für Steuertasten wie Ctrl etc. vorgesehen, eigentlich sind ja auch nur diese zur Kombination vorgesehen.
    Kombinationen mehrerer beliebiger Tasten können über folgendes "manuelles" Prinzip erkannt werden: Beim KeyDown Ereignis wird für jede gedrückte Taste eine Variable auf true gesetzt, beim KeyUp Ereignis die entsprechende Variable wieder auf false. Da für jede gedrückte Taste genau ein KeyDown und KeyUp Ereignis erzeugt wird, kann somit geprüft werden, welche Tasten gleichzeitig gedrückt sind.
    Folgender Code sollte für dich funktionieren:

    bool ADown = false;
    bool IDown = false;

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
    if (e.KeyValue == 65)
    ADown = true;
    if (e.KeyValue == 73)
    IDown = true;

    if (ADown && IDown)
    MessageBox.Show("IA");
    }

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
    ADown = false;
    IDown = false;
    }

    Viele Grüße
    Oliver

    AntwortenLöschen
    Antworten
    1. kann man bei der KeyUp auch nur die bestimmten Tasten wieder auf false setzen?

      ich versuch gerade eine art mario mit c# zu programmieren und möchte wärend ich renne also die d taste drücke auch springen können, ohne das er mit dem rennen aufhört

      Löschen
    2. Ja, du kannst wieder KeyEventArgs e benutzen:

      private void Form1_KeyUp(object sender, KeyEventArgs e)
      {
      if (e.KeyValue == 65)
      ADown = false;
      if (e.KeyValue == 73)
      IDown = false;
      }

      Löschen