Tenk et øyeblikk på å lage et raskt arkadespill. La oss si all grafikken i en TPainBox. TPaintBox kan ikke motta inngangsfokus - ingen hendelser blir avfyrt når brukeren trykker på en tast; vi kan ikke avskjøre markørtastene for å flytte slagskipet vårt. Delphi hjelp!
Avskjære tastaturinngang
De fleste Delphi-applikasjoner håndterer vanligvis brukerinndata gjennom spesifikke hendelsesbehandlere, de som lar oss fange bruker tastetrykk og prosess musebevegelse.
Vi vet at fokus er muligheten til å motta brukerinput via mus eller tastatur. Bare den objekt som har fokus, kan motta en tastaturhendelse. Noen kontroller, for eksempel TImage, TPaintBox, TPanel og TLabel, kan ikke få fokus. Hovedformålet med de fleste grafiske kontroller er å vise tekst eller grafikk.
Hvis vi vil avskjære tastaturinngang for kontroller som ikke kan motta inngangsfokus, må vi forholde oss til Windows API, kroker, tilbakeringinger og meldinger.
Windows kroker
Teknisk er en "hook" -funksjon en tilbakeringingsfunksjon som kan settes inn i Windows-meldingen system slik at en applikasjon kan få tilgang til meldingsstrømmen før annen behandling av meldingen tar plass. Blant mange typer vinduer kroker, kalles en tastatur krok når applikasjonen kaller GetMessage () eller PeekMessage () -funksjonen, og det er en WM_KEYUP- eller WM_KEYDOWN-tastaturmelding til prosess.
For å lage en tastaturkrok som avskjærer all tastaturinngang rettet til en gitt tråd, må vi ringe SetWindowsHookEx API-funksjon. Rutinene som mottar tastaturhendelsene er applikasjonsdefinerte tilbakeringingsfunksjoner kalt hook-funksjoner (KeyboardHookProc). Windows kaller krokfunksjonen din for hver tastetrykkmelding (tast opp og tast ned) før meldingen plasseres i programmets meldingskø. Krokfunksjonen kan behandle, endre eller forkaste tastetrykk. Kroker kan være lokale eller globale.
De returverdi av SetWindowsHookEx er et håndtak til kroken som nettopp er installert. Før søknad avsluttes, må en søknad ringe til UnhookWindowsHookEx funksjon for å frigjøre systemressurser tilknyttet kroken.
Eksempel på tastaturkrok
Som en demonstrasjon av tastaturkroker, lager vi et prosjekt med grafisk kontroll som kan motta tastetrykk. TImage er avledet fra TGraphicControl, det kan brukes som tegneoverflate for vårt hypotetiske kampspill. Siden TImage ikke kan motta tastaturpresser gjennom standard tastaturhendelser, oppretter vi en krokfunksjon som avskjærer all tastaturinngang rettet mot tegneoverflaten vår.
TImage Behandler tastaturhendelser
Start nytt Delphi-prosjektet og plasser en bildekomponent på et skjema. Sett Image1.Align egenskap til alClient. Det er det for den visuelle delen, nå må vi gjøre litt koding. Først trenger vi noen globale variabler:
Var
Form1: TForm1;
KBHook: HHook; {dette avskjærer tastaturinndata}
cx, cy: heltall; {spore kampskipets posisjon}
{tilbakeringingserklæring}
funksjon KeyboardHookProc (kode: heltall; WordParam: Word; LongParam: LongInt): LongInt; STDCALL;
gjennomføring
...
For å installere en krok, kaller vi SetWindowsHookEx i OnCreate-hendelsen til et skjema.
prosedyre TForm1.FormCreate (avsender: TObject);
begynne
{Still tastaturhaken slik at vi kan avskjære tastaturinndata}
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
{tilbakeringing>} @KeyboardHookProc,
hInstance,
GetCurrentThreadId ());
{plasser kampskipet midt på skjermen}
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas. PenPos: = Punkt (cx, cy);
slutt;
For å frigjøre systemressurser tilknyttet kroken, må vi kalle funksjonen UnhookWindowsHookEx i OnDestroy-hendelsen:
prosedyre TForm1.FormDestroy (avsender: TObject);
begynne
{hake opp tastaturets avskjæring}
UnHookWindowsHookEx (KBHook);
slutt;
Den viktigste delen av dette prosjektet er TastaturHookProc tilbakeringingsprosedyre brukes til å behandle tastetrykk.
funksjon KeyboardHookProc (kode: heltall; WordParam: Word; LongParam: LongInt): LongInt;
begynne
sak WordParam av
vk_Space: {slett kampskipets vei}
begynne
med Form1.Image1.Canvas do
begynne
Børste. Farge: = clWhite;
Børste. Stil: = bsSolid;
Fillrect (Form1.Image1.ClientRect);
slutt;
slutt;
vk_Right: cx: = cx + 1;
vk_Left: cx: = cx-1;
vk_Up: cy: = cy-1;
vk_Down: cy: = cy + 1;
slutt; {sak}
Hvis cx <2, så cx: = Form1.Image1.ClientWidth-2;
Hvis cx> Form1.Image1.ClientWidth -2, så er cx: = 2;
Hvis cy <2 så cy: = Form1.Image1.ClientHeight -2;
Hvis cy> Form1.Image1.ClientHeight-2, så cy: = 2;
med Form1.Image1.Canvas do
begynne
Penn. Farge: = clRed;
Børste. Farge: = gult;
TextOut (0,0, Format ('% d,% d', [cx, cy]));
Rektangel (cx-2, cy-2, cx + 2, cy + 2);
slutt;
Resultat: = 0;
{For å forhindre Windows i å sende tastetrykkene til målvinduet, må resultatverdien være en verdi som ikke er null.}
slutt;
Det er det. Vi har nå den ultimate tastaturbehandlingskoden.
Merk bare en ting: denne koden er på ingen måte begrenset til å brukes bare med TImage.
KeyboardHookProc-funksjonen fungerer som en generell KeyPreview & KeyProcess-mekanisme.