Tastatureingabe (Erste Schritte win32 und C++)

Die Tastatur wird für verschiedene Eingabetypen verwendet, darunter:

  • Zeicheneingabe. Text, den der Benutzer in ein Dokument oder Bearbeitungsfeld ein gibt.
  • Tastenkombinationen. Tastenanschläge, die Anwendungsfunktionen aufrufen; Drücken Sie z. B. STRG+O, um eine Datei zu öffnen.
  • Systembefehle. Tastenanschläge, die Systemfunktionen aufrufen; Beispiel: ALT+TAB zum Wechseln von Fenstern.

Beachten Sie bei der Tastatureingabe, dass ein Tastenstrich nicht mit einem Zeichen identisch ist. Wenn Sie z. B. die A-Taste drücken, kann dies zu einem der folgenden Zeichen führen.

  • a
  • Ein
  • lva (wenn die Tastatur das Kombinieren von diakritischen Zeichen unterstützt)

Wenn die ALT-TASTE gedrückt gehalten wird, erzeugt das Drücken der A-Taste ALT+A, was vom System überhaupt nicht als Zeichen, sondern als Systembefehl behandelt wird.

Schlüsselcodes

Wenn Sie eine Taste drücken, generiert die Hardware einen Scancode. Scancodes variieren von Tastatur zu Tastatur, und es gibt separate Überprüfungscodes für Key-Up- und Key-Down-Ereignisse. Scancodes sind ihnen fast nie egal. Der Tastaturtreiber übersetzt Scancodes in virtuelle Tastencodes. Codes für virtuelle Schlüssel sind geräteunabhängig. Wenn Sie die A-Taste auf einer beliebigen Tastatur drücken, wird der gleiche Code für die virtuelle Taste generiert.

Im Allgemeinen entsprechen Codes für virtuelle Schlüssel weder ASCII-Codes noch einem anderen Zeichencodierungsstandard. Dies ist offensichtlich, wenn Sie darüber nachdenken, da derselbe Schlüssel unterschiedliche Zeichen generieren kann (a, A, ): ) und einige Schlüssel, z. B. Funktionsschlüssel, keinem Zeichen entsprechen.

Die folgenden Codes für virtuelle Schlüssel werden jedoch ASCII-Entsprechungen zugerechnet:

  • 0 bis 9 Schlüssel = ASCII '0' – '9' (0x30 – 0x39)
  • A bis Z-Schlüssel = ASCII 'A' – 'Z' (0x41 – 0x5A)

In gewissem Sinne ist diese Zuordnung ungnend, da Sie sich aus den hier genannten Gründen niemals Codes für virtuelle Schlüssel als Zeichen ein denken sollten.

Die Headerdatei WinUser.h definiert Konstanten für die meisten Codes virtueller Schlüssel. Der Virtuelle Schlüsselcode für die NACH-LINKS-TASTE ist beispielsweise VK _ LEFT (0x25). Die vollständige Liste der Codes für virtuelle Schlüssel finden Sie unter Codes für virtuelle Schlüssel. Für die Codes virtueller Schlüssel, die ASCII-Werten übereinstimmen, werden keine Konstanten definiert. Beispielsweise ist der Virtuelle Schlüsselcode für den A-Schlüssel 0x41, aber es gibt keine Konstante mit dem Namen VK _ A. Verwenden Sie stattdessen einfach den numerischen Wert.

Key-Down und Key-Up Nachrichten

Wenn Sie eine Taste drücken, empfängt das Fenster mit dem Tastaturfokus eine der folgenden Meldungen.

Die WM _ SYSKEYDOWN-Meldung gibt einen Systemschlüssel an, bei dem es sich um einen Schlüsselstrich handelt, der einen Systembefehl aufruft. Es gibt zwei Arten von Systemschlüsseln:

  • ALT + beliebige Taste
  • F10

Die Taste F10 aktiviert die Menüleiste eines Fensters. Verschiedene ALT-Tastenkombinationen rufen Systembefehle auf. Alt und TAB wechseln z. B. zu einem neuen Fenster. Wenn ein Fenster über ein Menü verfügt, kann außerdem die ALT-TASTE verwendet werden, um Menüelemente zu aktivieren. Einige ALT-Tastenkombinationen machen nichts.

Alle anderen Tastenstriche werden als Nichtsystemschlüssel betrachtet und erzeugen die WM _ KEYDOWN-Meldung. Dies schließt die anderen Funktionsschlüssel als F10 ein.

Wenn Sie einen Schlüssel frei geben, sendet das System eine entsprechende Key-Up-Meldung:

Wenn Sie eine Taste lange genug halten, um das Wiederholungsfeature der Tastatur zu starten, sendet das System mehrere Tastenkombinationsmeldungen, gefolgt von einer einzelnen Key-Up-Nachricht.

In allen vier bisher erläuterten Tastaturmeldungen enthält der wParam-Parameter den Virtuellen Tastencode der Taste. Der lParam-Parameter enthält verschiedene Informationen, die in 32 Bits gepackt sind. In der Regel benötigen Sie die Informationen in lParam nicht. Ein Flag, das nützlich sein kann, ist bit 30, das Flag "previous key state", das für wiederholte Key-Down-Meldungen auf 1 festgelegt ist.

Wie der Name schon sagt, sind Systemschlüsselstriche in erster Linie für die Verwendung durch das Betriebssystem vorgesehen. Wenn Sie die WM _ SYSKEYDOWN-Nachricht abfangen, rufen Sie anschließend DefWindowProc auf. Andernfalls blockieren Sie die Verarbeitung des Befehls durch das Betriebssystem.

Zeichenmeldungen

Schlüsselstriche werden von der TranslateMessage-Funktion, die wir zum ersten Mal in Modul 1 gesehen haben, in Zeichen konvertiert. Diese Funktion untersucht Key-Down-Nachrichten und übersetzt sie in Zeichen. Für jedes erzeugte Zeichen legt die TranslateMessage-Funktion eine WM _ CHAR- oder WM _ SYSCHAR-Nachricht in die Nachrichtenwarteschlange des Fensters. Der wParam-Parameter der Nachricht enthält das UTF-16-Zeichen.

Wie Sie vielleicht erraten, werden WM _ CHAR-Nachrichten aus WM _ KEYDOWN-Nachrichten generiert, während WM _ SYSCHAR-Nachrichten aus WM _ SYSKEYDOWN-Nachrichten generiert werden. Angenommen, der Benutzer drückt die UMSCHALTTASTE, gefolgt von der A-Taste. Bei einem Standardtastaturlayout erhalten Sie die folgende Nachrichtensequenz:

WM _ KEYDOWN: UMSCHALT
WM _ KEYDOWN: A
WM _ CHAR:'A'

Auf der anderen Seite würde die Kombination ALT + P generieren:

WM _ SYSKEYDOWN: _ VK-MENÜ
WM _ SYSKEYDOWN: 0x50
WM _ SYSCHAR:'p'
WM _ SYSKEYUP: 0x50
WM _ KEYUP: _ VK-MENÜ

(Der Virtuelle Schlüsselcode für die ALT-Taste heißt VK. _ MENU aus historischen Gründen.)

Die WM _ SYSCHAR-Meldung gibt ein Systemzeichen an. Wie bei WM _ SYSKEYDOWNsollten Sie diese Meldung im Allgemeinen direkt an DefWindowProc übergeben. Andernfalls können Sie die Standardsystembefehle beeinträchtigen. Insbesondere sollten Sie WM _ SYSCHAR nicht als Text behandeln, den der Benutzer typiert hat.

Die WM _ CHAR-Nachricht wird normalerweise als Zeicheneingabe bezeichnet. Der Datentyp für das Zeichen ist wchar _ t, der ein UTF-16-Unicode-Zeichen darstellt. Zeicheneingaben können Zeichen außerhalb des ASCII-Bereichs enthalten, insbesondere bei Tastaturlayouts, die häufig außerhalb der USA. Sie können verschiedene Tastaturlayouts ausprobieren, indem Sie eine regionale Tastatur installieren und dann das Feature Bildschirmtastatur verwenden.

Benutzer können auch einen Eingabemethode-Editor (Input Method Editor, IME) installieren, um komplexe Skripts, z. B. japanische Zeichen, mit einer Standardtastatur eineingaben zu können. Wenn Sie z. B. einen japanischen IME verwenden, um das Katakana-Zeichen (ka) ein eingaben, erhalten Sie möglicherweise die folgenden Meldungen:

WM _ KEYDOWN: VK _ PROCESSKEY (DER IME PROCESS-Schlüssel)
WM _ KEYUP: 0x4B
WM _ KEYDOWN: VK _ PROCESSKEY
WM _ KEYUP: 0x41
WM _ KEYDOWN: VK _ PROCESSKEY
WM _ CHAR:
WM _ KEYUP: VK _ RETURN

Einige TASTENKOMBINATIONEN WERDEN in ASCII-Steuerzeichen übersetzt. Beispielsweise wird STRG+A in das ASCII-Zeichen STRG+A (SOH) (ASCII-Wert 0x01) übersetzt. Für die Texteingabe sollten Sie die Steuerzeichen in der Regel herausfiltern. Vermeiden Sie außerdem die Verwendung von WM _ CHAR zum Implementieren von Tastenkombinationen. Verwenden Sie stattdessen WM _ KEYDOWN-Nachrichten oder sogar eine Zugriffstastentabelle. Zugriffstastentabellen werden im nächsten Thema, Zugriffstastentabellen,beschrieben.

Der folgende Code zeigt die Haupttastaturmeldungen im Debugger an. Versuchen Sie, mit verschiedenen Tastenkombinationen zu spielen und zu sehen, welche Nachrichten generiert werden.

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    wchar_t msg[32];
    switch (uMsg)
    {
    case WM_SYSKEYDOWN:
        swprintf_s(msg, L"WM_SYSKEYDOWN: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_SYSCHAR:
        swprintf_s(msg, L"WM_SYSCHAR: %c\n", (wchar_t)wParam);
        OutputDebugString(msg);
        break;

    case WM_SYSKEYUP:
        swprintf_s(msg, L"WM_SYSKEYUP: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_KEYDOWN:
        swprintf_s(msg, L"WM_KEYDOWN: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_KEYUP:
        swprintf_s(msg, L"WM_KEYUP: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_CHAR:
        swprintf_s(msg, L"WM_CHAR: %c\n", (wchar_t)wParam);
        OutputDebugString(msg);
        break;

    /* Handle other messages (not shown) */

    }
    return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}

Verschiedene Tastaturmeldungen

Einige andere Tastaturmeldungen können von den meisten Anwendungen problemlos ignoriert werden.

  • Die WM _ DEADCHAR-Nachricht wird für einen kombinierenden Schlüssel gesendet, z. B. ein diakritischer Schlüssel. Wenn Sie z. B. auf einer Tastatur in spanischer Sprache Akzent (') gefolgt von E eingeben, wird das Zeichen "1" erzeugt. WM _ DEADCHAR wird für das Akzentzeichen gesendet.
  • Die WM _ UNICHAR-Nachricht ist veraltet. Damit können ANSI-Programme Unicode-Zeicheneingaben empfangen.
  • Das WM _ IME _ CHAR-Zeichen wird gesendet, wenn eine IME eine Tastatureingabesequenz in Zeichen übersetzt. Sie wird zusätzlich zur üblichen WM _ CHAR-Nachricht gesendet.

Tastaturstatus

Die Tastaturmeldungen sind ereignisgesteuert. Das heißt, Sie erhalten eine Nachricht, wenn etwas Interessantes passiert, z. B. ein Tastendruck, und die Nachricht informiert Sie darüber, was gerade passiert ist. Sie können den Status eines Schlüssels aber auch jederzeit testen, indem Sie die GetKeyState-Funktion aufrufen.

Überlegen Sie sich beispielsweise, wie Sie die Kombination aus linker Maustaste und ALT-TASTE erkennen würden. Sie können den Zustand des ALT-Schlüssels nachverfolgen, indem Sie auf Schlüsselstrichnachrichten lauschen und ein Flag speichern, aber GetKeyState spart Ihnen das Problem. Wenn Sie die _ WM-LBUTTONDOWN-Nachricht erhalten, rufen Sie GetKeyState einfach wie folgt auf:

if (GetKeyState(VK_MENU) & 0x8000))
{
    // ALT key is down.
}

Die GetKeyState-Nachricht nimmt einen Code mit virtuellem Schlüssel als Eingabe und gibt einen Satz von Bitflags (eigentlich nur zwei Flags) zurück. Der Wert 0x8000 enthält das Bitflag, das testet, ob die Taste gerade gedrückt wird.

Die meisten Tastaturen verfügen über zwei ALT-Tasten, links und rechts. Im vorherigen Beispiel wird getestet, ob einer von gedrückt ist. Sie können getKeyState auch verwenden, um zwischen der linken und rechten Instanz der ALT-, UMSCHALT- oder STRG-Taste zu unterscheiden. Der folgende Code testet beispielsweise, ob die rechte ALT-TASTE gedrückt wird.

if (GetKeyState(VK_RMENU) & 0x8000))
{
    // Right ALT key is down.
}

Die GetKeyState-Funktion ist interessant, da sie einen virtuellen Tastaturzustand meldet. Dieser virtuelle Zustand basiert auf dem Inhalt Ihrer Nachrichtenwarteschlange und wird aktualisiert, wenn Sie Nachrichten aus der Warteschlange entfernen. Während Das Programm Fenstermeldungen verarbeitet, stellt GetKeyState Ihnen eine Momentaufnahme der Tastatur zum Zeitpunkt der Warteschlange der einzelnen Nachrichten zur Seite. Wenn beispielsweise die letzte Nachricht in der Warteschlange WM _ LBUTTONDOWNlautet, meldet GetKeyState den Tastaturzustand zu dem Zeitpunkt, zu dem der Benutzer auf die Maustaste geklickt hat.

Da GetKeyState auf Ihrer Nachrichtenwarteschlange basiert, ignoriert es auch Tastatureingaben, die an ein anderes Programm gesendet wurden. Wenn der Benutzer zu einem anderen Programm wechselt, werden alle Tastendrucke, die an dieses Programm gesendet werden, von GetKeyState ignoriert. Wenn Sie wirklich den unmittelbaren physischen Zustand der Tastatur kennen möchten, gibt es dafür eine Funktion: GetAsyncKeyState. Für den großteil des Benutzeroberflächencodes ist getKeyState jedoch die richtige Funktion.

Nächste

Zugriffstastentabellen