Aflytning af tastaturinput med Delphi

Overvej et øjeblik oprettelse af et hurtigt arkadespil. Al grafikken vises, lad os sige, i en TPainBox. TPaintBox kan ikke modtage inputfokus - ingen hændelser affyres, når brugeren trykker på en tast; vi kan ikke opfange cursortasterne for at flytte vores slagskib. Delphi Hjælp!

Aflytning af tastaturinput

De fleste Delphi-applikationer håndterer typisk brugerinput gennem specifikke hændelsesbehandlere, dem, der gør det muligt for os at fange bruger tastetryk og proces mus bevægelse.

Vi ved, at fokus er muligheden for at modtage brugerinput via musen eller tastaturet. Kun objekt, der har fokus, kan modtage en tastaturhændelse. Nogle kontroller, såsom TImage, TPaintBox, TPanel og TLabel, kan ikke modtage fokus. Det primære formål med de fleste grafiske kontroller er at vise tekst eller grafik.

Hvis vi ønsker at aflytte tastaturindgang for kontroller, der ikke kan modtage inputfokus, bliver vi nødt til at håndtere Windows API, hooks, callbacks og Beskeder.

Windows Hooks

Teknisk set er en "hook" -funktion en callback-funktion, der kan indsættes i Windows-meddelelsen system, så en applikation kan få adgang til meddelelsesstrømmen, før anden behandling af meddelelsen tager placere. Blandt mange typer vindueskrog kaldes en tastaturkrog, når applikationen kalder GetMessage () eller PeekMessage () -funktionen, og der er en WM_KEYUP- eller WM_KEYDOWN-tastaturmeddelelse til behandle.

instagram viewer

For at oprette en tastaturkrog, der opfanger al tastaturindgang, der er rettet til en given tråd, er vi nødt til at ringe til SetWindowsHookEx API-funktion. De rutiner, der modtager tastaturbegivenhederne, er applikationsdefinerede tilbagekaldsfunktioner kaldet hook-funktioner (KeyboardHookProc). Windows kalder din hook-funktion til hver tastetrykmeddelelse (tast op og tast ned), før beskeden placeres i programmets meddelelseskø. Krogfunktionen kan behandle, ændre eller kassere tastetryk. Kroge kan være lokale eller globale.

Det returværdi af SetWindowsHookEx er et håndtag til krogen, der netop er installeret. Inden en ansøgning afsluttes, skal en ansøgning ringe til UnhookWindowsHookEx funktion til at frigøre systemressourcer tilknyttet krogen.

Eksempel på tastaturkrog

Som en demonstration af tastaturkroge opretter vi et projekt med grafisk kontrol, der kan modtage tastetryk. TImage er afledt af TGraphicControl, det kan bruges som tegneoverflade til vores hypotetiske kampspil. Da TImage ikke er i stand til at modtage tastaturpresser gennem standard tastaturbegivenheder, opretter vi en krogfunktion, der opfanger al tastaturindgang, der er rettet mod vores tegningsflade.

TImage-behandling af tastaturbegivenheder

Start nyt Delphi-projekt og placer en billedkomponent på en formular. Indstil Image1.Align egenskab til alClient. Det er det for den visuelle del, nu er vi nødt til at lave noget kodning. Først har vi brug for nogle globale variabler:

 Var
Form1: TForm1;
KBHook: HHook; {dette opfanger tastaturindgang}
cx, cy: heltal; {spore kampskibets position}
{tilbagekaldserklæring}
funktion KeyboardHookProc (kode: heltal; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
implementering
...

For at installere en krog, kalder vi SetWindowsHookEx i OnCreate-hændelsen af ​​en formular.

 procedure TForm1.FormCreate (Afsender: TObject);
begynde
{Indstil tastaturkrog, så vi kan aflytte tastaturindgang}
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
{callback>} @KeyboardHookProc,
hInstance,
GetCurrentThreadId ());
{placere slagskibet midt på skærmen}
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas. PenPos: = Punkt (cx, cy);
ende;

For at frigøre systemressourcer, der er tilknyttet krogen, skal vi kalde funktionen UnhookWindowsHookEx i OnDestroy-begivenheden:

 procedure TForm1.FormDestroy (Afsender: TObject);
begynde
{fjern hak på tastaturets aflytning}
UnHookWindowsHookEx (KBHook);
ende;

Den vigtigste del af dette projekt er TastaturHookProc tilbagekaldsprocedure bruges til at behandle tastetryk.

 funktion KeyboardHookProc (kode: heltal; WordParam: Word; LongParam: LongInt): LongInt;
begynde
sag WordParam af
vk_Space: {slet slagskibets sti}
begynde
med Form1.Image1.Canvas do
begynde
Børste. Farve: = clWhite;
Børste. 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; {sag}
Hvis cx <2, så er cx: = Form1.Image1.ClientWidth-2;
Hvis cx> Form1.Image1.ClientWidth -2, så er cx: = 2;
Hvis cy <2, vil cy: = Form1.Image1.ClientHeight -2;
Hvis cy> Form1.Image1.ClientHeight-2, er cy: = 2;
med Form1.Image1.Canvas do
begynde
Pen. Farve: = clRed;
Børste. Farve: = clYellow;
TextOut (0,0, Format ('% d,% d', [cx, cy]));
Rektangel (cx-2, cy-2, cx + 2, cy + 2);
ende;
Resultat: = 0;
{For at forhindre Windows i at videresende tastetryk til målvinduet, skal resultatsværdien være en ikke-nul-værdi.}
ende;

Det er det. Vi har nu den ultimative tastaturbehandlingskode.

Bemærk kun en ting: denne kode er på ingen måde begrænset til kun at blive brugt med TImage.

KeyboardHookProc-funktionen fungerer som en generel KeyPreview & KeyProcess-mekanisme.