Trumpam apsvarstykite galimybę sukurti greitą arkadinį žaidimą. Tarkime, visa grafika rodoma „TPainBox“. „TPaintBox“ negali priimti įvesties fokusavimo - vartotojui paspaudus klavišą, įvykiai neiššaukiami; mes negalime perimti žymeklio klavišų, kad judėtume mūšio laivu. Delfi padėti!
Klaviatūros įvestis
Daugelis „Delphi“ programų paprastai tvarko vartotojo įvestį per tam tikrus įvykių tvarkytuvus - tuos, kurie įgalina mus sugauti vartotoją klavišų paspaudimai ir procesas pelės judėjimas.
Mes žinome, kad dėmesys yra galimybė priimti vartotojo duomenis per pelę ar klaviatūrą. Tik fokusuotas objektas gali priimti klaviatūros įvykį. Kai kurie valdikliai, tokie kaip TImage, TPaintBox, TPanel ir TLabel, negali sufokusuoti. Pagrindinis daugelio grafinių valdiklių tikslas yra parodyti tekstą arba grafiką.
Jei norime perimti klaviatūros įvestį valdikliams, kurie negali priimti įvesties fokusavimo, turėsime susidurti su „Windows API“, kabliais, atšaukimais ir žinutes.
„Windows“ kabliukai
Techniškai „kabliuko“ funkcija yra atgalinio ryšio funkcija, kurią galima įterpti į „Windows“ pranešimą sistema, kad programa galėtų pasiekti pranešimų srautą prieš imdamasi kito pranešimo apdorojimo vieta. Tarp daugelio langų kabliukų tipų klaviatūros kabliukas yra skambinamas kaskart, kai programa skambina „GetMessage“ () arba „PeekMessage ()“ funkcija ir yra WM_KEYUP arba WM_KEYDOWN klaviatūros pranešimas, skirtas procesas.
Norėdami sukurti klaviatūros kablį, kuris sulaiko visą klaviatūros įvestį, nukreiptą į nurodytą giją, turime paskambinti „SetWindowsHookEx“ API funkcija. Įprasta klaviatūros įvykių priėmimo tvarka yra programos apibrėžtos atgalinio ryšio funkcijos, vadinamos „kabliuko funkcijomis“ („KeyboardHookProc“). Prieš įdėdami pranešimą į programos pranešimų eilę, „Windows“ iškviečia jūsų kabliuko funkciją kiekvienam klavišo paspaudimui (klavišu aukštyn ir žemyn). Kabliuko funkcija gali apdoroti, pakeisti ar atšaukti klavišų paspaudimus. Kabliukai gali būti vietiniai arba globalūs.
grąžos vertė „SetWindowsHookEx“ yra ką tik įdiegto kablio rankena. Prieš nutraukdama programą, ji turi paskambinti „UnhookWindowsHookEx“ funkcija išlaisvinti sistemos resursus, susijusius su kabliu.
Klaviatūros kablio pavyzdys
Kaip klaviatūros kabliukų demonstraciją sukursime projektą su grafiniu valdymu, kuriuo bus galima priimti klavišų paspaudimus. „TImage“ yra gautas iš „TGraphicControl“, jis gali būti naudojamas kaip piešimo paviršius mūsų hipotetiniam mūšio žaidimui. Kadangi „TImage“ negali priimti klaviatūros paspaudimų per įprastus klaviatūros įvykius, mes sukursime kablio funkciją, kuri sulauks visos klaviatūros įvesties, nukreiptos į mūsų piešimo paviršių.
„TImage“ apdorojimo klaviatūros įvykiai
Pradėkite naują „Delphi“ projektas ir įdėkite vieną paveikslėlio komponentą į formą. Nustatykite „Image1.Align“ nuosavybę į „alClient“. Tai vizualinei daliai, dabar turime šiek tiek užkoduoti. Pirmiausia, mums to reikės globalieji kintamieji:
var
1 forma: TForm1;
KBHook: HHook; {tai perima klaviatūros įvestį}
cx, cy: sveikasis skaičius; {sekti mūšio laivo padėtį}
{atgalinio ryšio deklaracija}
funkcija „KeyboardHookProc“ (kodas: sveikasis skaičius; „WordParam“: „Word“; „LongParam“: „LongInt“): „LongInt“; stdcall;
įgyvendinimas
...
Norėdami įdiegti kabliuką, formos „OnCreate“ įvykyje mes vadiname „SetWindowsHookEx“.
procedūra TForm1.FormCreate (Siuntėjas: TObject);
prasideda
{Nustatykite klaviatūros kabliuką, kad galėtume perimti klaviatūros įvestį}
„KBHook“: = „SetWindowsHookEx“ (WH_KEYBOARD,
{callback>} @KeyboardHookProc,
Sveiki,
„GetCurrentThreadId“);
{statykite mūšio laivą ekrano viduryje}
cx: = Image1.ClientWidth 2 div;
cy: = Image1.ClientHeight 2 div .;
Image1.Canvas. PenPos: = Taškas (cx, cy);
galas;
Norėdami atlaisvinti su šaldytuvu susijusius sistemos išteklius, turime pakviesti „UnhookWindowsHookEx“ funkciją „OnDestroy“ įvykyje:
procedūra TForm1.FormDestroy (Siuntėjas: TObject);
prasideda
{atkabinkite klaviatūros perėmimą}
„UnHookWindowsHookEx“ („KBHook“);
galas;
Svarbiausia šio projekto dalis yra „KeyboardHookProc“ atgalinio ryšio procedūra naudojamas apdoroti klavišų paspaudimus.
funkcija „KeyboardHookProc“ (kodas: sveikasis skaičius; „WordParam“: „Word“; „LongParam“: „LongInt“): „LongInt“;
prasideda
atvejis
vk_Space: {trinti mūšio laivo kelią}
prasideda
su forma1.Image1.Canvas padaryti
prasideda
Šepetys. Spalva: = clWhite;
Šepetys. Stilius: = bsSolid;
Užpildykite teisingai (forma1.Image1.ClientRect);
galas;
galas;
vk_Right: cx: = cx + 1;
vk_Left: cx: = cx-1;
vk_Up: cy: = cy-1;
vk_Down: cy: = cy + 1;
galas; {atvejis}
Jei cx <2, tada cx: = Forma1.Image1.ClientWidth-2;
Jei cx> Forma1.Paveikslas1.Kliento plotis -2, tada cx: = 2;
Jei cy <2, tada cy: = Forma1.Image1.ClientHeight -2;
Jei cy> Forma1.Image1.ClientHeight-2, tada cy: = 2;
su forma1.Image1.Canvas padaryti
prasideda
Rašiklis. Spalva: = CLRED;
Šepetys. Spalva: = clYellow;
„TextOut“ (0,0, formatas ('% d,% d', [cx, cy]));
Stačiakampis (cx-2, cy-2, cx + 2, cy + 2);
galas;
Rezultatas: = 0;
{Norėdami neleisti „Windows“ perduoti klavišų paspaudimų į tikslinį langą, Rezultato reikšmė turi būti lygi nuliui.}
galas;
Viskas. Dabar turime aukščiausią klaviatūros apdorojimo kodą.
Atkreipkite dėmesį tik į vieną dalyką: šis kodas jokiu būdu nėra ribojamas, kad jį būtų galima naudoti tik su „TImage“.
„KeyboardHookProc“ funkcija tarnauja kaip bendras „KeyPreview“ ir „KeyProcess“ mechanizmas.