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. Es werden keine Ereignisse ausgelöst, wenn der Benutzer eine Taste drückt. Wir können keine Cursortasten abfangen, um unser Schlachtschiff zu bewegen. Delphi-Hilfe!
Die meisten Delphi-Anwendungen verarbeiten Benutzereingaben in der Regel über bestimmte Ereignishandler, die es uns ermöglichen, Benutzertastenanschläge zu erfassen und Mausbewegungen zu verarbeiten.
Wir wissen, dass Fokus die Fähigkeit ist, Benutzereingaben über die Maus oder die Tastatur zu empfangen. Nur der Objekt, das den Fokus hat, kann ein Tastaturereignis empfangen. Einige Steuerelemente wie TImage, TPaintBox, TPanel und TLabel können den Fokus nicht 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 erhalten, müssen wir uns mit Windows-API, Hooks, Rückrufen und Nachrichten befassen.
Technisch gesehen ist eine "Hook" -Funktion eine Rückruffunktion, die in das Windows-Nachrichtensystem eingefügt werden kann, damit eine Anwendung auf den Nachrichtenstrom zugreifen kann, bevor eine andere Verarbeitung der Nachricht stattfindet. Unter vielen Arten von Windows-Hooks wird ein Tastatur-Hook aufgerufen, wenn die Anwendung die Funktion GetMessage () oder PeekMessage () aufruft und eine WM_KEYUP- oder WM_KEYDOWN-Tastaturnachricht zu verarbeiten ist.
Um einen Tastatur-Hook zu erstellen, der alle Tastatureingaben abfängt, die an einen bestimmten Thread gerichtet sind, müssen wir callen 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 Tastenanschlagsnachricht (Taste hoch und Taste runter) auf, bevor die Nachricht in die Nachrichtenwarteschlange der Anwendung gestellt wird. Die Hook-Funktion kann Tastatureingaben verarbeiten, ändern oder verwerfen. Hooks können lokal oder global sein.
Der Rückgabewert von SetWindowsHookEx ist ein Handle für den gerade installierten Hook. Vor dem Beenden muss eine Anwendung die aufrufen UnhookWindowsHookEx Funktion zum Freigeben von Systemressourcen, die dem Hook zugeordnet sind.
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 Tastatureingaben über Standardtastaturereignisse empfangen kann, erstellen wir eine Hook-Funktion, die alle Tastatureingaben abfängt, die an unsere Zeichenoberfläche gerichtet sind.
Starten Sie ein neues Delphi-Projekt und platzieren Sie eine Image-Komponente in einem Formular. Setzen Sie die Image1.Align-Eigenschaft auf alClient. Das ist es für den visuellen Teil, jetzt müssen wir etwas programmieren. Zunächst benötigen wir einige globale Variablen:
var
Form1: TForm1;
KBHook: HHook; dies fängt die Tastatureingabe ab
cx, cy: ganze Zahl; Position des Schlachtschiffes 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,
HInstanz,
GetCurrentThreadId ());
Platziere das Schlachtschiff in der Mitte des Bildschirms
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas.PenPos: = Point (cx, cy);
Ende;
Um dem Hook zugeordnete Systemressourcen freizugeben, müssen wir die UnhookWindowsHookEx-Funktion im OnDestroy-Ereignis aufrufen:
procedure TForm1.FormDestroy (Sender: TObject);
Start
Tastatur abfangen
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: Kampfschiffspfad löschen
Start
mit Form1.Image1.Canvas tun
Start
Brush.Color: = clWhite;
Brush.Style: = 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 then cx := Form1.Image1.ClientWidth-2;
Wenn cx> Form1.Image1.ClientWidth -2, dann ist cx: = 2;
Wenn cy < 2 then cy := Form1.Image1.ClientHeight -2 ;
Wenn cy> Form1.Image1.ClientHeight-2, dann cy: = 2;
mit Form1.Image1.Canvas tun
Start
Pen.Color: = clRed;
Brush.Color: = clYellow;
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 weiterleitet, 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.