Przechwytywanie danych z klawiatury za pomocą Delphi

Zastanów się przez chwilę nad stworzeniem szybkiej gry zręcznościowej. Wszystkie grafiki są wyświetlane, powiedzmy, w TPainBox. TPaintBox nie może otrzymać fokusu wejściowego - żadne zdarzenia nie są wywoływane, gdy użytkownik naciśnie klawisz; nie możemy przechwytywać klawiszy kursora, aby przenieść nasz pancernik. Delfy Wsparcie!

Przechwyć dane z klawiatury

Większość aplikacji Delphi zazwyczaj obsługuje dane wejściowe użytkownika za pośrednictwem określonych procedur obsługi zdarzeń, które umożliwiają nam przechwycenie użytkownika naciśnięcia klawiszy i proces ruch myszy.

Wiemy, że nacisk kładziony jest na możliwość uzyskiwania informacji od użytkownika za pomocą myszy lub klawiatury. Tylko obiekt, na którym jest ustawiony fokus, może otrzymać zdarzenie klawiatury. Niektóre elementy sterujące, takie jak TImage, TPaintBox, TPanel i TLabel, nie mogą być aktywne. Podstawowym celem większości kontrolek graficznych jest wyświetlanie tekstu lub grafiki.

Jeśli chcemy przechwycić dane wejściowe z klawiatury dla elementów sterujących, które nie mogą uzyskać fokusu wejściowego, będziemy musieli poradzić sobie z interfejsem API systemu Windows, hakami, wywołaniami zwrotnymi i

instagram viewer
wiadomości.

Haki do systemu Windows

Technicznie funkcja „przechwytująca” jest funkcją zwrotną, którą można wstawić do komunikatu Windows system, aby aplikacja mogła uzyskać dostęp do strumienia wiadomości, zanim zajmie to inne przetwarzanie wiadomości miejsce. Spośród wielu typów zaczepów systemu Windows, wywoływany jest zaczep klawiatury, za każdym razem, gdy aplikacja wywołuje funkcję Funkcja GetMessage () lub PeekMessage () i pojawia się komunikat klawiatury WM_KEYUP lub WM_KEYDOWN proces.

Aby utworzyć zaczep klawiatury, który przechwytuje wszystkie dane wejściowe klawiatury skierowane do danego wątku, musimy zadzwonić SetWindowsHookEx Funkcja API. Procedury odbierające zdarzenia klawiatury to zdefiniowane przez aplikację funkcje zwrotne zwane funkcjami przechwytującymi (KeyboardHookProc). System Windows wywołuje funkcję przechwytującą dla każdej wiadomości naciśnięcia klawisza (klawisz w górę i klawisz w dół), zanim wiadomość zostanie umieszczona w kolejce komunikatów aplikacji. Funkcja przechwytująca może przetwarzać, zmieniać lub odrzucać naciśnięcia klawiszy. Haki mogą być lokalne lub globalne.

The zwracana wartość SetWindowsHookEx to właśnie zainstalowany uchwyt do haka. Przed zakończeniem aplikacja musi wywołać funkcję UnhookWindowsHookEx funkcja zwalniająca zasoby systemowe związane z zaczepem.

Przykład zaczepu klawiatury

Jako demonstrację zaczepów klawiatury stworzymy projekt z graficznym sterowaniem, który może odbierać naciśnięcia klawiszy. TImage pochodzi z TGraphicControl, można go wykorzystać jako powierzchnię do rysowania w naszej hipotetycznej grze bitewnej. Ponieważ TImage nie jest w stanie odbierać naciśnięć klawiatury przez standardowe zdarzenia klawiatury, stworzymy funkcję przechwytującą, która przechwytuje wszystkie dane wejściowe klawiatury skierowane na naszą powierzchnię rysowania.

TIMage Przetwarzanie zdarzeń klawiatury

Zacząć nowy Projekt Delphi i umieść jeden składnik obrazu w formularzu. Ustaw właściwość Image1.Align na alClient. To tyle w części wizualnej, teraz musimy trochę kodować. Najpierw będziemy potrzebować zmienne globalne:

 var
Form1: TForm1;
KBHook: HHook; {to przechwytuje dane z klawiatury}
cx, cy: liczba całkowita; {śledź pozycję statku bojowego}
{deklaracja oddzwonienia}
funkcja KeyboardHookProc (Kod: Liczba całkowita; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
realizacja
...

Aby zainstalować hook, wywołujemy SetWindowsHookEx w zdarzeniu OnCreate formularza.

 Procedura TForm1.FormCreate (Sender: TObject);
zaczynać
{Ustaw zaczep klawiatury, abyśmy mogli przechwytywać dane z klawiatury}
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
{callback>} @KeyboardHookProc,
HInstance,
GetCurrentThreadId ());
{umieść okręt bojowy na środku ekranu}
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas. PenPos: = Point (cx, cy);
koniec;

Aby zwolnić zasoby systemowe związane z przechwyceniem, musimy wywołać funkcję UnhookWindowsHookEx w zdarzeniu OnDestroy:

 procedura TForm1.FormDestroy (Sender: TObject);
zaczynać
{odczep klawiaturę}
UnHookWindowsHookEx (KBHook);
koniec;

Najważniejszą częścią tego projektu jest Procedura wywołania zwrotnego KeyboardHookProc używane do przetwarzania naciśnięć klawiszy.

 funkcja KeyboardHookProc (Kod: Liczba całkowita; WordParam: Word; LongParam: LongInt): LongInt;
zaczynać
sprawa WordParam z
vk_Space: {wymaż ścieżkę statku bojowego}
zaczynać
z Form1.Image1.Canvas zrobić
zaczynać
Szczotka. Kolor: = clWhite;
Szczotka. Styl: = bsSolid;
Fillrect (Form1.Image1.ClientRect);
koniec;
koniec;
vk_Right: cx: = cx + 1;
vk_Left: cx: = cx-1;
vk_Up: cy: = cy-1;
vk_Down: cy: = cy + 1;
koniec; {walizka}
Jeśli cx <2, to cx: = Form1.Image1.ClientWidth-2;
Jeśli cx> Form1.Image1.ClientWidth -2, to cx: = 2;
Jeśli cy <2, to cy: = Form1.Image1.ClientHeight -2;
Jeśli cy> Form1.Image1.ClientHeight-2, to cy: = 2;
z Form1.Image1.Canvas zrobić
zaczynać
Długopis. Kolor: = clRed;
Szczotka. Kolor: = kolor żółty;
TextOut (0,0, Format („% d,% d”, [cx, cy]));
Prostokąt (cx-2, cy-2, cx + 2, cy + 2);
koniec;
Wynik: = 0;
{Aby uniemożliwić systemowi Windows przekazywanie naciśnięć klawiszy do okna docelowego, wartość Wynik musi być wartością niezerową.}
koniec;

Otóż ​​to. Mamy teraz najlepszy kod przetwarzania klawiatury.

Pamiętaj tylko o jednej rzeczy: ten kod nie jest w żaden sposób ograniczony do używania tylko z TImage.

Funkcja KeyboardHookProc służy jako ogólny mechanizm KeyPreview i KeyProcess.