Windows Message Manager menyediakan kemampuan bagi aplikasi untuk mengakses aliran pesan yang dikontrol.
'c4 disebut mekanisme kait (HOOK). Ada banyak jenis hook, masing-masing digunakan untuk menangkap jenis atau rentang pesan tertentu. Seperti: pesan keyboard, pesan mouse, dll. Kami hanya mengambil penggunaan kait keyboard sebagai contoh di sini untuk membahas cara menulis program DLL di bawah DELPHI dan cara menginstal dan menggunakan fungsi kait keyboard di program Anda sendiri. Kami juga membahas cara berbagi data ketika program berbeda menggunakan file DLL yang sama .
1. Petunjuk untuk menulis fungsi filter kait
Karena fungsi filter kait harus berada dalam modul independen, artinya kita harus membuat kerangka DLL terlebih dahulu, lalu menambahkan kode fungsi kait dan kode fungsi terkait lainnya ke dalamnya. Di sini kita mengambil penulisan fungsi filter kait keyboard sebagai contoh untuk mengilustrasikannya. Langkah-langkah spesifiknya adalah sebagai berikut:
1. Pertama buat keranjang DLL 2
2. Tulis fungsi filter kait keyboard Anda sendiri
Fungsi filter kait harus berupa fungsi panggilan balik, dan fungsinya memiliki bentuk berikut:
fungsiKeyHookPROc(
kode:Bilangan Bulat;
wParam:WPARAM;
lParam:LPARAM ): HASIL; stdcall ;ekspor;
Tambahkan fungsi pemrosesan kait keyboard Anda sendiri ke kerangka DLL yang dihasilkan untuk menangani pesan keyboard.
Kodenya adalah sebagai berikut:…
if(iCode>=0) lalu mulai
Hasil:=0; //Inisialisasi nilai kembalian
//Tambahkan kode Anda sendiri di sini
akhiri yang lain
mulai
Hasil:=CallNextHook(hOldKeyHook,iCode,wParam,lParam);
//hOldKeyHook adalah fungsi filter keyboard asli yang disimpan?
akhir;
3. Pasang fungsi filter pengait keyboard
Untuk memasang hook, fungsi filter _fd harus memanggil fungsi SetWindowsHookEx (fungsi instalasi hook SetWindowsHook untuk Windows 3.0 sekarang sudah usang). Prototipe fungsi ini adalah sebagai berikut:
HHOOK SetWindowsHookEx(
int idHook, // Terpasang?_b3 subtipe
HOOKPROC lpfn, //Hook filter??f alamat nomor
PETUNJUK hMod, //Pegangan tugas
DWord dwThreadId // Tujuan dari pengait
);
Perlu dicatat bahwa: ?_a8 sering kali harus memanggil fungsi MakeProcInstance untuk mendapatkan alamat entri pembukaan fungsi keluaran, dan kemudian menggunakan alamat ini sebagai parameter kedua lpfn dari SetWindowsHookEx. Namun, karena Delphi menyediakan "smart callback", MakeProcInstance dapat dihilangkan dan nama fungsi hook filter dapat langsung digunakan sebagai alamat entri.
Dengan cara ini, ketika fungsi _c3GetMessage atau PeekMessage aplikasi membaca pesan dari antrian pesan atau memiliki pesan kunci (WM_KEYDOWN atau WM_KEYUP) untuk diproses, sistem akan memanggil fungsi filter kait KeyHookProc untuk memproses pesan keyboard.
4. Copot pemasangan fungsi filter pengait.
Ketika fungsi hook tidak lagi diperlukan, UnHookWindowsHookProc harus dipanggil untuk menghapus instalasi hook yang diinstal untuk melepaskan sumber daya sistem.
Daftar program selengkapnya adalah sebagai berikut?_ba
KAIT KUNCI Perpustakaan;
menggunakan Windows;
konstan BUFFER_SIZE=16*1024;
const HOOK_MEM_FILENAME='CONTOH KUNCI_HOOK_MEM_FILE';
const HOOK_MUTEX_NAME ='SAMPEL KEY_HOOK_MUTEX_NAME';
jenis
TShared=catatan
Kunci: array[0..BUFFER_SIZE] dari Char;
Jumlah Kunci : Integer;
akhir;
PDibagikan=^TDibagikan;
var
MemFile,HookMutex: Pegangan;
hOldKeyHook: HHook;
ProcSaveExit: Penunjuk;
Dibagikan: PSDibagikan;
//Fungsi filter kait keyboard
fungsi KeyHookProc(iCode: Integer; wParam: WPARAM ; lParam: LPARAM):LRESULT
;
const KeyPressMask = $80000000;
mulai
jika iCode < 0 maka
Hasil := CallNextHookEx(hOldKeyHook, iCode, wParam, lParam)
yang lain dimulai
if ((lParam dan KeyPressMask)= 0) lalu // tombol ditekan
mulai
Dibagi^.Keys[Dibagi^.KeyCount]:=Char(wParam dan $00ff);
Inc(Dibagi^.KeyCount);
jika Dibagi^.KeyCount>=BUFFER_SIZE-1 maka Dibagi^.KeyCount:=0;
akhir;
kode:=-1;
Hasil := CallNextHookEx(hOldKeyHook, iCode, wParam, lParam);
akhir;
akhir;
//Atur fungsi filter kait
fungsi EnableKeyHook: BOOL;
mulai
Bersama^.KeyCount:=0; //Inisialisasi penunjuk keyboard
jika hOldKeyHook=0 maka mulailah
hOldKeyHook := SetWindowsHookEx(WH_KEYBOARD,
Proc Kait Kunci,
Misalnya,
0);
akhir;
Hasil := (hOldKeyHook <> 0);
akhir;
//Membatalkan fungsi filter kait
fungsi DisableKeyHook: BOOL;
mulai
jika hOldKeyHook<> 0 lalu
mulai
Lepas KaitWindowsHookEx(hOldKeyHook); // Lepas Kait Keyboard
hOldKeyHook:= 0;
Dibagikan^.KeyCount:=0;
akhir;
Hasil := (hOldKeyHook = 0);
akhir;
//Dapatkan jumlah penekanan tombol di buffer keyboard
fungsi GetKeyCount :Ekspor bilangan bulat;
mulai
Hasil:=Dibagikan^.KeyCount;
akhir;
//Dapatkan kunci buffer keyboard
fungsi GetKey(indeks:Integer): Char ;
mulai
Hasil:=Dibagi^.Kunci[indeks];
akhir;
//Hapus buffer keyboard
prosedur ClearKeyString;
mulai
Dibagikan^.KeyCount:=0;
akhir;
//Proses pemrosesan keluar DLL
prosedur KeyHookExit;
mulai
jika hOldKeyHook <> 0 maka DisableKeyHook;
UnMapViewOfFile(Shared); // Lepaskan file gambar memori
CloseHandle(MemFile); // Tutup file gambar
KeluarProc := ProcSaveKeluar;
akhir;
ekspor // tentukan fungsi keluaran
AktifkanKeyHook,
NonaktifkanKeyHook,
DapatkanKeyCount,
HapusKeyString,
Dapatkan Kunci;
mulai
//bagian inisialisasi DLL
HookMutex:=CreateMutex(nihil,Benar,HOOK_MUTEX_NAME);
// Bagikan memori dengan membuat file gambar memori
MemFile:=OpenFileMapping(FILE_MAP_WRITE,Salah,
HOOK_MEM_FILENAME);
jika MemFile=0 maka
MemFile:=BuatPemetaanFile($FFFFFFFF,nihil,PAGE_READWRITE,0,
SizeOf(TDibagikan) ,HOOK_MEM_FILENAME);
Dibagikan:=MapViewOfFile(MemFile,File_MAP_WRITE,0,0,0);
RilisMutex(HookMutex);
CloseHandle(HookMutex);
ProcSaveExit := ExitProc; // Simpan ExitProc dari DLL
ExitProc := @KeyHookExit; // Atur ExitProc baru dari DLL
akhir.
//Akhir dari kode sumber
2. Gunakan fungsi filter pengait keyboard yang telah disiapkan di program Anda sendiri.
Setelah fungsi hook dikompilasi, sebenarnya sangat mudah digunakan: pertama-tama panggil SetWindowsHookEx untuk menginstal fungsi filter hook Anda sendiri, dan pada saat yang sama simpan alamat fungsi filter hook asli. Saat ini, fungsi pengait mulai berfungsi, dan akan menangani pesan keyboard sesuai dengan kebutuhan Anda. Ketika program selesai berjalan atau tidak perlu lagi memantau pesan keyboard, panggil fungsi UnHookWindowsHookProc untuk menghapus instalasi fungsi hook yang diinstal dan mengembalikan alamat fungsi filter hook asli.
Berikut ini adalah contoh penggunaan fungsi hook yang dikompilasi di atas:
satuan Unit1;
antarmuka
kegunaan
Windows, Pesan, SysUtils, Kelas, Grafik, Kontrol, Formulir, Dialog,
StdCtrls, ExtCtrls;
jenis
TForm1 = kelas(TForm)
Memo1: TMemo;
Panel1: TPanel;
bSetHook: Tombol T;
bCancelHook: TButton;
bReadKeys: Tombol T;
bClearKeys: Tombol T;
Panel2: TPanel;
prosedur bSetHookClick(Pengirim: TObject);
prosedur bCancelHookClick(Pengirim: TObject);
prosedur bReadKeysClick(Pengirim: TObject);
prosedur bClearKeysClick(Pengirim: TObject);
akhir;
var Formulir1: TForm1;
pelaksanaan
{$R *.DFM}
fungsi EnableKeyHook : BOOL ; eksternal 'KEYHOOK.DLL';
fungsi DisableKeyHook : BOOL ; eksternal 'KEYHOOK.DLL';
fungsi GetKeyCount : Integer ; eksternal 'KEYHOOK.DLL';
fungsi GetKey(idx:Integer): Char ; eksternal 'KEYHOOK.DLL';
prosedur ClearKeyString; eksternal 'KEYHOOK.DLL';
procedure TForm1.bSetHookClick(Pengirim: TObject); // Menyetel kait keyboard 7ó
mulai
AktifkanKeyHook;
bSetHook.Enabled :=Salah;
bCancelHook.Enabled:=Benar;
bReadKeys.Enabled :=Benar;
bClearKeys.Enabled :=Benar;
Panel2.Caption:='Pengait keyboard telah disetel';
akhir;
procedure TForm1.bCancelHookClick(Pengirim: TObject); // Copot pemasangan pengait keyboard
mulai
NonaktifkanKeyHook;
bSetHook.Enabled :=Benar;
bCancelHook.Enabled:=Salah;
bReadKeys.Enabled :=Salah;
bClearKeys.Enabled :=Salah;
Panel2.Caption:='Pengait keyboard tidak disetel';
akhir;
procedure TForm1.bReadKeysClick(Pengirim: TObject); // Dapatkan riwayat penekanan tombol
var i:Bilangan Bulat;
mulai
Memo1.Lines.Clear; // Menampilkan riwayat penekanan tombol di Memo1
untuk i:=0 hingga GetKeyCount-1 lakukan
Memo1.Teks:=Memo1.Teks+GetKey(i);
akhir;
prosedur TForm1.bClearKeysClick(Pengirim: TObject); // Hapus riwayat penekanan tombol
mulai
Memo1.Hapus;
HapusKeyString;
akhir;
akhir.
//Akhir dari kode sumber
3. Menerapkan memori bersama di DLL pada Windows95
Dalam file DLL tempat fungsi kait di atas berada, memori bersama perlu digunakan, yaitu semua catatan penekanan tombol disimpan dalam segmen data yang sama. Mengapa kita melakukan ini? Ini karena metode pemanggilan DLL pada Windows95 berbeda dengan Windows3.X. Saat setiap thread masuk ke pustaka tautan dinamis, ia akan meneruskan pegangan instans baru (yaitu, pegangan segmen data DLL) ke pustaka tautan dinamis. Hal ini memungkinkan berbagai contoh DLL untuk tidak saling mengganggu, namun menimbulkan beberapa kesulitan ketika semua contoh DLL berbagi satu set variabel. Untuk mengatasi masalah ini, kami menyelesaikannya di sini dengan membuat file yang dipetakan memori. Yaitu, menggunakan OpenFileMapping Windows, CreateFileMapping dan
MapViewOfFile tiga fungsi yang ingin dicapai. Cara menggunakannya:
…
MemFile adalah tipe THandle, Shared adalah tipe pointer, dan HOOK_MEM_FILENAME adalah string konstan.
…
MemFile:=OpenFileMapping(FILE_MAP_WRITE,Salah,
HOOK_MEM_FILENAME); //Buka file yang dipetakan memori
if MemFile=0 lalu //Jika pembukaan gagal?_c2 Buat file yang dipetakan memori
MemFile:=BuatPemetaanFile($FFFFFFFF,nihil,PAGE_READWRITE,0,
SizeOf(TDibagikan) ,HOOK_MEM_FILENAME);
//Petakan file ke variabel
Dibagikan:=MapViewOfFile(MemFile,File_MAP_WRITE,0,0,0);
Sejauh ini Anda sudah mengetahui betapa mudahnya mengkompilasi fungsi hook di Delphi. Terakhir, saya harus mengingatkan semua orang: Meskipun fungsi pengait relatif kuat, jika digunakan secara tidak tepat, hal ini akan berdampak serius pada efisiensi sistem, jadi cobalah untuk menghindari penggunaan pengait sistem. Kehati-hatian ekstra harus diberikan saat harus digunakan, sehingga sesedikit mungkin mempengaruhi pengoperasian sistem.
[Akhir teks lengkap]