Mõelge hetkeks mõne kiire arkaadmängu loomisele. Ütleme, et kogu graafika kuvatakse TPainBoxis. TPaintBox ei saa sisendfookust vastu võtta - kasutaja klahvi vajutamisel sündmusi ei vallandata; meie lahingulaeva liigutamiseks ei saa kursoriklahve pealtkuulata. Delphi appi!
Klaviatuuri sisendi pealtkuulamine
Enamik Delphi rakendusi tegeleb kasutaja sisestusega tavaliselt konkreetsete sündmuste käitlejate kaudu - need võimaldavad meil kasutajaid hõivata klahvivajutused ja töödelda hiire liikumine.
Me teame, et tähelepanu keskmes on võime saada kasutaja sisestust hiire või klaviatuuri kaudu. Ainult objekt, millel on fookus, võib vastu võtta klaviatuurisündmuse. Mõned juhtelemendid, näiteks TImage, TPaintBox, TPanel ja TLabel, ei suuda fookust vastu võtta. Enamiku graafiliste juhtelementide peamine eesmärk on teksti või graafika kuvamine.
Kui tahame pealt kuulata klaviatuurisisestust juhtnuppude jaoks, mis ei saa sisendfookust vastu võtta, peame tegelema Windows API, konksude, tagasihelistamise ja sõnumid.
Windowsi konksud
Tehniliselt on "konks" funktsioon tagasihelistamise funktsioon, mille saab lisada Windowsi sõnumisse süsteem, nii et rakendus pääseb sõnumivoogu juurde enne sõnumi muu töötlemist koht. Mitme tüüpi aknakonksude korral kutsutakse klaviatuuri konksu alati, kui rakendus helistab Funktsioon GetMessage () või PeekMessage () ja seal on klaviatuuriteade WM_KEYUP või WM_KEYDOWN protsess.
Klaviatuurikonksu loomiseks, mis katkestab kogu antud niidile suunatud klaviatuuri sisendi, peame helistama SetWindowsHookEx API funktsioon. Klaviatuuri sündmusi vastuvõtvad rutiinid on rakenduse määratletud tagasihelistamise funktsioonid, mida nimetatakse konksufunktsioonideks (KeyboardHookProc). Enne kui sõnum paigutatakse rakenduse sõnumite järjekorda, kutsub Windows iga klahvivajutuse teate jaoks klahvi funktsiooni (klahv üles ja alla). Konksufunktsioon võib klahvivajutusi töödelda, muuta või neist loobuda. Konksud võivad olla kohalikud või globaalsed.
tagastatav väärtus SetWindowsHookEx on just paigaldatud konksu käepide. Enne lõpetamist tuleb rakendusel helistada UnhookWindowsHookEx funktsioon konksuga seotud süsteemiressursside vabastamiseks.
Klaviatuuri konksu näide
Klaviatuurikonksude näitena loome graafilise juhtimisega projekti, millega saab vastu võtta klahvivajutusi. TImage on saadud TGraphicControlist, seda saab kasutada meie hüpoteetilise lahingumängu joonistuspinnana. Kuna TImage ei saa klaviatuuri vajutusi tavaliste klaviatuurisündmuste kaudu vastu võtta, loome konksufunktsiooni, mis hoiab kinni kõik meie joonistuspinnale suunatud klaviatuuri sisendid.
TImage töötlemise klaviatuuri sündmused
Alusta uut Delphi projekt ja asetage vormile üks pildikomponent. Seadke Image1.Align atribuut alClient. See on visuaalse osa jaoks, nüüd peame natuke kodeerima. Esiteks vajame natuke globaalsed muutujad:
var
Vorm 1: TForm1;
KBHook: HHook; {see võtab klaviatuuri sisestuse kinni}
cx, cy: täisarv; {jälgi lahingulaeva asukohta}
{tagasihelistamise deklaratsioon}
funktsioon KeyboardHookProc (kood: täisarv; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
rakendamine
...
Konksu installimiseks kutsume vormi OnCreate'i sündmuses SetWindowsHookExit.
protseduur TForm1.FormCreate (saatja: TObject);
alustada
{Seadistage klaviatuuri konks, et saaksime klaviatuurisisestust pealt kuulata}
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
{tagasihelistamine>} @KeyboardHookProc,
HI-seisukoht,
GetCurrentThreadId ());
{asetage lahingulaev ekraani keskele}
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Pilt1.Canvas. PenPos: = punkt (cx, cy);
lõpp;
Konksuga seotud süsteemiressursside vabastamiseks peame kutsuma sündmuse OnDestroy funktsiooni UnhookWindowsHookEx:
protseduur TForm1.FormDestroy (saatja: TObject);
alustada
{avage klaviatuuri pealtkuulamine}
UnHookWindowsHookEx (KBHook);
lõpp;
Selle projekti kõige olulisem osa on KeyboardHookProc tagasihelistamisprotseduur kasutatakse klahvivajutuste töötlemiseks.
funktsioon KeyboardHookProc (kood: täisarv; WordParam: Word; LongParam: LongInt): LongInt;
alustada
juhul WordParam of
vk_Space: {kustuta lahingu laeva tee}
alustada
koos vormiga1.Image1.Canvas teevad
alustada
Pintsel. Värv: = clWhite;
Pintsel. Stiil: = bsSolid;
Täitke (vorm1.Image1.ClientRect);
lõpp;
lõpp;
vk_Right: cx: = cx + 1;
vk_Left: cx: = cx-1;
vk_Up: cy: = cy-1;
vk_Down: cy: = cy + 1;
lõpp; {juhtum}
Kui cx <2, siis cx: = vorm1.Image1.ClientWidth-2;
Kui cx> Vorm1.Kujundus1.Kliendilaius -2, siis cx: = 2;
Kui cy <2, siis cy: = vorm1.Image1.ClientHeight -2;
Kui cy> vorm1.Image1.ClientHeight-2, siis cy: = 2;
koos vormiga1.Image1.Canvas teevad
alustada
Pliiats. Värv: = CLRed;
Pintsel. Värv: = clYellow;
TextOut (0,0, vorming ('% d,% d', [cx, cy]));
Ristkülik (cx-2, cy-2, cx + 2, cy + 2);
lõpp;
Tulemus: = 0;
{Selleks, et Windows ei saaks klahvivajutusi sihtiaknasse suunata, ei tohi tulemuse väärtus olla nullväärtus.}
lõpp;
See selleks. Nüüd on meil ülim klaviatuuri töötlemise kood.
Pange tähele ainult ühte asja: selle koodi kasutamine pole piiratud ainult TImage'i kasutamisel.
Funktsioon KeyboardHookProc toimib üldise KeyPreview & KeyProcess mehhanismina.