Share via


Tastatureingabe (Erste Schritte mit Win32 und C++)

Die Tastatur wird für verschiedene Arten von Eingaben verwendet, einschließlich:

  • Zeicheneingabe. Text, den der Benutzer in ein Dokument oder ein Bearbeitungsfeld eingibt.
  • Tastenkombinationen. Tastenstriche, die Anwendungsfunktionen aufrufen; z. B. STRG+O, um eine Datei zu öffnen.
  • Systembefehle. Tastenstriche, die Systemfunktionen aufrufen; z. B. ALT +TAB zum Wechseln von Fenstern.

Wenn Sie über Tastatureingaben nachdenken, ist es wichtig zu beachten, dass ein Tastenstrich nicht mit einem Zeichen identisch ist. Das Drücken der A-Taste kann beispielsweise zu einem der folgenden Zeichen führen.

  • a
  • Ein
  • á (wenn die Tastatur die Kombination diakritischer Zeichen unterstützt)

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

Schlüsselcodes

Wenn Sie eine Taste drücken, generiert die Hardware einen Scancode. Scancodes variieren von Tastatur zu Tastatur, und es gibt separate Scancodes für Key-Up- und Key-Down-Ereignisse. Sie werden sich fast nie um Scancodes kümmern. Der Tastaturtreiber übersetzt Scancodes in Virtuelle Tastencodes. Virtuelle Schlüsselcodes sind geräteunabhängig. Durch Drücken der A-Taste auf einer beliebigen Tastatur wird der gleiche Virtuelle Schlüsselcode generiert.

Im Allgemeinen entsprechen Virtuelle Schlüsselcodes nicht ASCII-Codes oder einem anderen Zeichencodierungsstandard. Dies ist offensichtlich, wenn Sie darüber nachdenken, da derselbe Schlüssel verschiedene Zeichen (a, A, á) generieren kann und einige Schlüssel, z. B. Funktionstasten, keinem Zeichen entsprechen.

Das heißt, die folgenden Virtuellen Schlüsselcodes werden ASCII-Entsprechungen zugeordnet:

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

In mancher Hinsicht ist diese Zuordnung bedauerlich, da Sie sich virtuelle Schlüsselcodes aus den erläuterten Gründen niemals als Zeichen vorstellen sollten.

Die Headerdatei WinUser.h definiert Konstanten für die meisten Codes für virtuelle Schlüssel. Der Virtuelle Schlüsselcode für die NACH-LINKS-TASTE ist beispielsweise VK_LEFT (0x25). Eine vollständige Liste der Codes für virtuelle Schlüssel finden Sie unter Virtual-Key Codes. Für die Codes für virtuelle Schlüssel, die ASCII-Werten entsprechen, werden keine Konstanten definiert. Beispielsweise ist der Virtuelle Schlüsselcode für den A-Schlüssel 0x41, es gibt jedoch keine Konstante namens VK_A. Verwenden Sie stattdessen einfach den numerischen Wert.

Key-Down und Key-Up Nachrichten

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

Die WM_SYSKEYDOWN Meldung gibt einen Systemschlüssel an, bei dem es sich um einen Tastenstrich handelt, der einen Systembefehl aufruft. Es gibt zwei Arten von Systemschlüsseln:

  • ALT + beliebige Taste
  • F10

Die F10-Taste aktiviert die Menüleiste eines Fensters. Verschiedene ALT-Tastenkombinationen rufen Systembefehle auf. Beispielsweise wechselt ALT+TAB 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 tun nichts.

Alle anderen Tastenstriche werden als Nichtsystemschlüssel betrachtet und erzeugen die WM_KEYDOWN Meldung. Dies schließt die anderen Funktionstasten als F10 ein.

Wenn Sie einen Schlüssel freigeben, sendet das System eine entsprechende Key-Up-Nachricht:

Wenn Sie eine Taste lange genug gedrückt halten, um die Wiederholungsfunktion der Tastatur zu starten, sendet das System mehrere Tasten-nach-unten-Nachrichten, gefolgt von einer einzigen Meldung nach oben.

In allen vier bisher besprochenen Tastaturnachrichten enthält der wParam-Parameter den Virtuellen Schlüsselcode der Taste. Der Parameter lParam enthält einige 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 "vorheriger Schlüsselzustand", das für wiederholte Key-Down-Nachrichten 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 wird verhindert, dass das Betriebssystem den Befehl verarbeitet.

Zeichennachrichten

Tastenstriche werden von der TranslateMessage-Funktion in Zeichen konvertiert, die wir zuerst in Modul 1 gesehen haben. Diese Funktion untersucht key-down-Nachrichten und übersetzt sie in Zeichen. Für jedes erzeugte Zeichen fügt die TranslateMessage-Funktion eine WM_CHAR oder WM_SYSCHAR Nachricht in die Nachrichtenwarteschlange des Fensters ein. 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. Wenn Sie ein Standardtastaturlayout annehmen, erhalten Sie die folgende Nachrichtensequenz:

WM_KEYDOWN: UMSCHALT
WM_KEYDOWN: A
WM_CHAR: "A"

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

WM_SYSKEYDOWN: VK_MENU
WM_SYSKEYDOWN: 0x50
WM_SYSCHAR: "p"
WM_SYSKEYUP: 0x50
WM_KEYUP: VK_MENU

(Der virtuelle Schlüsselcode für den ALT-Schlüssel wird aus historischen Gründen VK_MENU benannt.)

Die WM_SYSCHAR Meldung gibt ein Systemzeichen an. Wie bei WM_SYSKEYDOWN sollten Sie diese Meldung im Allgemeinen direkt an DefWindowProc übergeben. Andernfalls können Sie standardsystembefehle beeinträchtigen. Behandeln Sie insbesondere WM_SYSCHAR nicht als Text, den der Benutzer eingegeben hat.

Die WM_CHAR Nachricht ist das, was Sie normalerweise als Zeicheneingabe betrachten. Der Datentyp für das Zeichen ist wchar_t und stellt ein UTF-16-Unicode-Zeichen dar. Die Zeicheneingabe kann Zeichen außerhalb des ASCII-Bereichs enthalten, insbesondere bei Tastaturlayouts, die häufig außerhalb der USA verwendet werden. Sie können verschiedene Tastaturlayouts ausprobieren, indem Sie eine regionale Tastatur installieren und dann die Funktion Bildschirmtastatur verwenden.

Benutzer können auch einen Eingabemethoden-Editor (IME) installieren, um komplexe Skripts, z. B. japanische Zeichen, mit einer Standardtastatatur einzugeben. Wenn Sie beispielsweise einen japanischen IME verwenden, um das Katakana-Zeichen カ (ka) einzugeben, 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 STRG-Tastenkombinationen werden in ASCII-Steuerzeichen übersetzt. Beispielsweise wird STRG+A in das ASCII-Zeichen STRG-A (SOH) übersetzt (ASCII-Wert 0x01). Bei der Texteingabe sollten Sie die Steuerzeichen im Allgemeinen herausfiltern. Vermeiden Sie außerdem die Verwendung von WM_CHAR , um Tastenkombinationen zu implementieren. Verwenden Sie stattdessen WM_KEYDOWN Nachrichten. oder noch besser: Verwenden Sie eine Acceleratortabelle. Acceleratortabellen werden im nächsten Thema Accelerator Tables (Accelerator Tables) beschrieben.

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

Hinweis

Stellen Sie sicher, dass Sie wchar.h einschließen, sonst ist swprintf_s undefiniert.

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 Tastaturnachrichten

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

  • Die WM_DEADCHAR Nachricht wird für einen kombinierten Schlüssel gesendet, z. B. ein diakritisches Schlüssel. Auf einer Tastatur in spanischer Sprache erzeugt beispielsweise die Eingabe des Akzents (') gefolgt von E das Zeichen é. Die WM_DEADCHAR wird für das Akzentzeichen gesendet.
  • Die WM_UNICHAR Nachricht ist veraltet. Es ermöglicht ANSI-Programmen, Unicode-Zeicheneingaben zu empfangen.
  • Das WM_IME_CHAR Zeichen wird gesendet, wenn eine IME eine Tastenanschlägesequenz in Zeichen übersetzt. Es wird zusätzlich zur üblichen WM_CHAR Nachricht gesendet.

Tastaturzustand

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

Überlegen Sie beispielsweise, wie Sie die Kombination von Linksklick + ALT-Taste erkennen würden. Sie könnten den Zustand der ALT-Taste nachverfolgen, indem Sie auf Nachrichten mit Tastenstrich lauschen und ein Flag speichern, aber GetKeyState erspart Ihnen die Probleme. Wenn Sie die WM_LBUTTONDOWN Nachricht erhalten, rufen Sie einfach GetKeyState wie folgt auf:

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

Die GetKeyState-Nachricht nimmt einen Code mit virtuellen Schlüsseln als Eingabe an und gibt eine Reihe von Bitflags zurück (eigentlich nur zwei Flags). 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 ihnen gedrückt ist. Sie können getKeyState auch verwenden, um zwischen den linken und rechten Instanzen 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 Ihr Programm Fensternachrichten verarbeitet, bietet Ihnen GetKeyState eine Momentaufnahme der Tastatur, wenn jede Nachricht in die Warteschlange gestellt wurde. Wenn beispielsweise die letzte Nachricht in der Warteschlange WM_LBUTTONDOWN war, meldet GetKeyState den Tastaturzustand zu dem Zeitpunkt, zu dem der Benutzer auf die Maustaste geklickt hat.

Da GetKeyState auf Ihrer Nachrichtenwarteschlange basiert, werden tastatureingaben ignoriert, die an ein anderes Programm gesendet wurden. Wenn der Benutzer zu einem anderen Programm wechselt, werden alle Tastendrücke, die an dieses Programm gesendet werden, von GetKeyState ignoriert. Wenn Sie den unmittelbaren physischen Zustand der Tastatur wirklich kennen möchten, gibt es dafür eine Funktion: GetAsyncKeyState. Für den meisten Ui-Code ist die richtige Funktion jedoch GetKeyState.

Nächste

Acceleratortabellen