Pertimbangkan sejenak pembuatan beberapa game arcade cepat. Semua gambar ditampilkan, katakanlah, dalam TPainBox. TPaintBox tidak dapat menerima fokus input - tidak ada peristiwa yang dipicu ketika pengguna menekan tombol; kita tidak bisa mencegat kunci kursor untuk memindahkan kapal perang kita. Delphi Tolong!
Mencegah Input Keyboard
Sebagian besar aplikasi Delphi biasanya menangani input pengguna melalui event handler tertentu, yang memungkinkan kami untuk menangkap pengguna penekanan tombol dan proses gerakan mouse.
Kita tahu bahwa fokus adalah kemampuan untuk menerima input pengguna melalui mouse atau keyboard. Hanya yang objek yang memiliki fokus dapat menerima acara keyboard. Beberapa kontrol, seperti TImage, TPaintBox, TPanel, dan TLabel tidak dapat menerima fokus. Tujuan utama dari sebagian besar kontrol grafis adalah untuk menampilkan teks atau gambar.
Jika kami ingin memotong input keyboard untuk kontrol yang tidak dapat menerima fokus input, kami harus berurusan dengan Windows API, hooks, callback, dan pesan.
Windows Hooks
Secara teknis, fungsi "hook" adalah fungsi callback yang dapat dimasukkan dalam pesan Windows sistem sehingga aplikasi dapat mengakses aliran pesan sebelum pemrosesan pesan lainnya dilakukan tempat. Di antara banyak jenis kait windows, kait keyboard dipanggil setiap kali aplikasi memanggil Fungsi GetMessage () atau PeekMessage () dan ada pesan keyboard WM_KEYUP atau WM_KEYDOWN untuk proses.
Untuk membuat kait keyboard yang memotong semua input keyboard yang diarahkan ke utas tertentu, kita perlu menelepon SetWindowsHookEx Fungsi API. Rutinitas yang menerima acara keyboard adalah fungsi panggilan balik yang ditentukan aplikasi yang disebut fungsi kait (KeyboardHookProc). Windows memanggil fungsi kait Anda untuk setiap pesan penekanan tombol (tombol atas dan tombol bawah) sebelum pesan ditempatkan dalam antrian pesan aplikasi. Fungsi kait dapat memproses, mengubah, atau membuang penekanan tombol. Kait bisa lokal atau global.
Itu nilai pengembalian SetWindowsHookEx adalah pegangan untuk pengait yang baru saja diinstal. Sebelum mengakhiri, aplikasi harus memanggil UnhookWindowsHookEx berfungsi untuk membebaskan sumber daya sistem yang terkait dengan hook.
Contoh Kait Keyboard
Sebagai peragaan kait keyboard, kami akan membuat proyek dengan kontrol grafis yang dapat menerima penekanan tombol. TImage berasal dari TGraphicControl, dapat digunakan sebagai permukaan gambar untuk game pertempuran hipotetis kami. Karena TImage tidak dapat menerima penekanan keyboard melalui acara keyboard standar, kami akan membuat fungsi kait yang memotong semua input keyboard yang diarahkan ke permukaan gambar kami.
TImage Memproses Acara Keyboard
Mulai baru Proyek Delphi dan letakkan satu komponen Gambar pada formulir. Setel properti Image1.Align ke alClient. Itu saja untuk bagian visual, sekarang kita harus melakukan beberapa pengkodean. Pertama, kita perlu beberapa variabel global:
var
Form1: TForm1;
KBHook: HHook; {ini memotong input keyboard}
cx, cy: integer; {lacak posisi kapal perang}
{pernyataan panggilan balik}
fungsi KeyboardHookProc (Kode: Integer; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
penerapan
...
Untuk memasang kait, kami memanggil SetWindowsHookEx dalam acara OnCreate dari formulir.
procedure TForm1.FormCreate (Pengirim: TObject);
mulai
{Setel pengait keyboard agar kami dapat mencegat input keyboard}
KBHook: = SetWindowsHookEx (WH_KEYBOARD,
{callback>} @KeyboardHookProc,
Keadaan,
GetCurrentThreadId ());
{letakkan kapal perang di tengah layar}
cx: = Image1.ClientWidth div 2;
cy: = Image1.ClientHeight div 2;
Image1.Canvas. PenPos: = Titik (cx, cy);
akhir;
Untuk membebaskan sumber daya sistem yang terkait dengan hook, kita harus memanggil fungsi UnhookWindowsHookEx dalam acara OnDestroy:
procedure TForm1.FormDestroy (Pengirim: TObject);
mulai
{lepaskan intersepsi keyboard}
UnHookWindowsHookEx (KBHook);
akhir;
Bagian terpenting dari proyek ini adalah Prosedur panggilan balik KeyboardHookProc digunakan untuk memproses penekanan tombol.
fungsi KeyboardHookProc (Kode: Integer; WordParam: Word; LongParam: LongInt): LongInt;
mulai
kasus WordParam dari
vk_Space: {erase path kapal perang}
mulai
dengan Form1.Image1.Canvas lakukan
mulai
Sikat. Warna: = clWhite;
Sikat. Gaya: = bsSolid;
Fillrect (Form1.Image1.ClientRect);
akhir;
akhir;
vk_Right: cx: = cx + 1;
vk_Left: cx: = cx-1;
vk_Up: cy: = cy-1;
vk_Down: cy: = cy + 1;
akhir; {kasus}
Jika cx <2 maka cx: = Form1.Image1.ClientWidth-2;
Jika cx> Form1.Image1.ClientWidth -2 maka cx: = 2;
Jika cy <2 maka cy: = Form1.Image1.ClientHeight -2;
Jika cy> Form1.Image1.ClientHeight-2 maka cy: = 2;
dengan Form1.Image1.Canvas lakukan
mulai
Pena. Warna: = clRed;
Sikat. Warna: = clYellow;
TextOut (0,0, Format ('% d,% d', [cx, cy]));
Persegi panjang (cx-2, cy-2, cx + 2, cy + 2);
akhir;
Hasil: = 0;
{Untuk mencegah Windows meneruskan penekanan tombol ke jendela target, nilai Hasil harus bukan nilai nol.}
akhir;
Itu dia. Kami sekarang memiliki kode pemrosesan keyboard terbaik.
Catat hanya satu hal: kode ini sama sekali tidak dibatasi untuk digunakan hanya dengan TImage.
Fungsi KeyboardHookProc berfungsi sebagai mekanisme KeyPreview & KeyProcess umum.