Abfangen der Tastatureingabe mit Delphi

Betrachten Sie für einen Moment die Erstellung eines schnellen Arcade-Spiels. Alle Grafiken werden beispielsweise in einer TPainBox angezeigt. TPaintBox kann den Eingabefokus nicht empfangen. Wenn der Benutzer eine Taste drückt, werden keine Ereignisse ausgelöst. Wir können keine Cursortasten abfangen, um unser Schlachtschiff zu bewegen. Delphi Hilfe!

Tastatureingabe abfangen

Die meisten Delphi-Anwendungen verarbeiten Benutzereingaben normalerweise über bestimmte Ereignishandler, mit denen wir Benutzer erfassen können Tastenanschläge und verarbeiten Mausbewegung.

Wir wissen, dass der Fokus auf der Fähigkeit liegt, Benutzereingaben über die Maus oder die Tastatur zu empfangen. Nur der Objekt mit Fokus kann ein Tastaturereignis empfangen. Einige Steuerelemente wie TImage, TPaintBox, TPanel und TLabel können keinen Fokus erhalten. Der Hauptzweck der meisten Grafiksteuerelemente ist die Anzeige von Text oder Grafiken.

Wenn wir Tastatureingaben für Steuerelemente abfangen möchten, die den Eingabefokus nicht empfangen können, müssen wir uns mit Windows-API, Hooks, Rückrufen und befassen

instagram viewer
Mitteilungen.

Windows Hooks

Technisch gesehen ist eine "Hook" -Funktion eine Rückruffunktion, die in die Windows-Nachricht eingefügt werden kann System, damit eine Anwendung auf den Nachrichtenstrom zugreifen kann, bevor eine andere Verarbeitung der Nachricht erfolgt Platz. Unter vielen Arten von Windows-Hooks wird ein Tastatur-Hook aufgerufen, wenn die Anwendung das aufruft GetMessage () oder PeekMessage () Funktion und es gibt eine WM_KEYUP oder WM_KEYDOWN Tastaturmeldung an Prozess.

Um einen Tastatur-Hook zu erstellen, der alle Tastatureingaben abfängt, die an einen bestimmten Thread gerichtet sind, müssen wir aufrufen SetWindowsHookEx API-Funktion. Die Routinen, die die Tastaturereignisse empfangen, sind anwendungsdefinierte Rückruffunktionen, die als Hook-Funktionen (KeyboardHookProc) bezeichnet werden. Windows ruft Ihre Hook-Funktion für jede Tastendrucknachricht (Taste hoch und Taste runter) auf, bevor die Nachricht in die Nachrichtenwarteschlange der Anwendung gestellt wird. Die Hook-Funktion kann Tastenanschläge verarbeiten, ändern oder verwerfen. Hooks können lokal oder global sein.

Das Rückgabewert von SetWindowsHookEx ist ein Handle für den gerade installierten Hook. Vor dem Beenden muss eine Anwendung die UnhookWindowsHookEx Funktion zum Freigeben von Systemressourcen, die dem Hook zugeordnet sind.

Beispiel für einen Tastaturhaken

Als Demonstration von Tastatur-Hooks erstellen wir ein Projekt mit grafischer Steuerung, das Tastendrücke empfangen kann. TImage ist von TGraphicControl abgeleitet und kann als Zeichenfläche für unser hypothetisches Kampfspiel verwendet werden. Da TImage keine Tastendrücke über Standardtastaturereignisse empfangen kann, erstellen wir eine Hook-Funktion, die alle Tastatureingaben abfängt, die auf unsere Zeichenfläche gerichtet sind.

TImage Processing-Tastaturereignisse

Neu anfangen Delphi-Projekt und platzieren Sie eine Bildkomponente in einem Formular. Setzen Sie die Image1.Align-Eigenschaft auf alClient. Das war's für den visuellen Teil, jetzt müssen wir etwas codieren. Zuerst brauchen wir welche globale Variablen:

 var
Form1: TForm1;
KBHook: HHook; {dies fängt Tastatureingaben ab}
cx, cy: ganze Zahl; {Position des Schlachtschiffs verfolgen}
{Rückruferklärung}
Funktion KeyboardHookProc (Code: Integer; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
Implementierung
...

Um einen Hook zu installieren, rufen wir SetWindowsHookEx im OnCreate-Ereignis eines Formulars auf.

 procedure TForm1.FormCreate (Sender: TObject);
Start
{Stellen Sie den Tastaturhaken so ein, dass wir Tastatureingaben abfangen können}
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
{Rückruf>} @KeyboardHookProc,
Instanz,
GetCurrentThreadId ());
{Platziere das Schlachtschiff in der Mitte des Bildschirms}
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas. PenPos: = Punkt (cx, cy);
Ende;

Um die mit dem Hook verbundenen Systemressourcen freizugeben, müssen wir die Funktion UnhookWindowsHookEx im OnDestroy-Ereignis aufrufen:

 Prozedur TForm1.FormDestroy (Absender: TObject);
Start
{Tastaturabfangen aushaken}
UnHookWindowsHookEx (KBHook);
Ende;

Der wichtigste Teil dieses Projekts ist der KeyboardHookProc-Rückrufprozedur wird zum Verarbeiten von Tastenanschlägen verwendet.

 Funktion KeyboardHookProc (Code: Integer; WordParam: Word; LongParam: LongInt): LongInt;
Start
Fall WordParam von
vk_Space: {Pfad des Schlachtschiffs löschen}
Start
mit Form1.Image1.Canvas tun
Start
Bürste. Farbe: = weiß;
Bürste. Stil: = bsSolid;
Fillrect (Form1.Image1.ClientRect);
Ende;
Ende;
vk_Right: cx: = cx + 1;
vk_Left: cx: = cx-1;
vk_Up: cy: = cy-1;
vk_Down: cy: = cy + 1;
Ende; {Fall}
Wenn cx <2, dann cx: = Form1.Image1.ClientWidth-2;
Wenn cx> Form1.Image1.ClientWidth -2, dann ist cx: = 2;
Wenn cy <2, dann cy: = Form1.Image1.ClientHeight -2;
Wenn cy> Form1.Image1.ClientHeight-2 ist, dann ist cy: = 2;
mit Form1.Image1.Canvas tun
Start
Stift. Farbe: = clRed;
Bürste. Farbe: = gelb;
TextOut (0,0, Format ('% d,% d', [cx, cy]));
Rechteck (cx-2, cy-2, cx + 2, cy + 2);
Ende;
Ergebnis: = 0;
{Um zu verhindern, dass Windows die Tastenanschläge an das Zielfenster übergibt, muss der Ergebniswert ein Wert ungleich Null sein.}
Ende;

Das ist es. Wir haben jetzt den ultimativen Tastaturverarbeitungscode.

Beachten Sie nur eines: Dieser Code darf in keiner Weise nur mit TImage verwendet werden.

Die KeyboardHookProc-Funktion dient als allgemeiner KeyPreview- und KeyProcess-Mechanismus.