亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Delphi > 正文

用DELPHI編制Windows95下的鉤子函數

2019-11-18 18:52:44
字體:
來源:轉載
供稿:網友
Windows消息管理機構提供了能使應用程序訪問控制消息流μ
'c4所謂的鉤子(HOOK)機制。鉤子有多種,分別用于捕獲某一特定類型或某一范圍的消息。如:鍵盤消息,鼠標消息等。我們這里僅以鍵盤鉤子的使用為例,討論在DELPHI下怎樣編寫DLL程序和怎樣在自己的程序中安裝使用鍵盤鉤子函數,并討論了不同程序使用同一DLL文件時怎樣共享數據。
一、 鉤子過濾函數的編寫說明
由于鉤子過濾函數必須在獨立的模塊中,也就是說我們必須首先生成一個DLL框架,然后再在其中加入鉤子函數代碼以及其他相關函數代碼。我們這里以鍵盤鉤子過濾函數的編寫為例來說明。具體步驟如下:
1、先生成一個DLL筐2架
2、編寫自己的鍵盤鉤子過濾函數
鉤子過濾函數必須是回調函數,其函數的 4?形如下?o
function KeyHookPRoc(
iCode:Integer;
wParam:WPARAM;
lParam:LPARAM ) : LRESULT; stdcall ;export ;
在生成的DLL框架中加入自己的鍵盤鉤子處理函數處理鍵盤消息。
代碼如下:…
if(iCode>=0) then begin
Result:=0; //初始化返回值
// 在這里加入自己的代碼
end else
begin
Result:=CallNextHook(hOldKeyHook,iCode,wParam,lParam);
// hOldKeyHook是保存的原鍵盤過濾函數 5刂?
end;
3、 安裝鍵盤鉤子過濾函數
為安裝一個鉤子?_fd濾函數應調用SetWindowsHookEx函數(適用于Windows3.0的SetWindowsHook鉤子安裝函數現在已經廢棄不用)。該函數的原形如下:
HHOOK SetWindowsHookEx(
int idHook,  // 安裝的?_b3子類型
HOOKPROC lpfn,  // 鉤子過濾??f數地址
HINSTANCE hMod,   // 任務句柄
DWord dwThreadId   // 鉤子用于的目的
);
需要說明的是:?_a8常應該調用MakeProcInstance函數以獲取一個輸出函數的前導碼的入口地址,再將此地址作為SetWindowsHookEx的第二個參數lpfn。但由于Delphi提供了"靈巧調用(smart callback)",使得MakeProcInstance可以省去,而直接將鉤子過濾函數名用作入口地址。
這樣當應用程序?_c3GetMessage或PeekMessage函數從消息隊列中讀消息或有按鍵消息(WM_KEYDOWN或WM_KEYUP)要處理時,系統就要調用鉤子過濾函數KeyHookProc處理鍵盤消息。
4、 卸載鉤子過濾函數。
當鉤子函數不再需要時,應調用UnHookWindowsHookProc卸載安裝的鉤子以釋放系統資源。
完整的程序清單如下?_ba
Library KEYHOOK;
uses Windows;
const BUFFER_SIZE=16*1024;
const HOOK_MEM_FILENAME='SAMPLE KEY_HOOK_MEM_FILE';
const HOOK_MUTEX_NAME ='SAMPLE KEY_HOOK_MUTEX_NAME';
type
TShared=record
Keys : array[0..BUFFER_SIZE] of Char;
KeyCount : Integer;
end;
PShared=^TShared;
var
MemFile,HookMutex : THandle;
hOldKeyHook : HHook;
ProcSaveExit : Pointer;
Shared : PShared;

//鍵盤鉤子過濾函數
function KeyHookProc(iCode: Integer; wParam: WPARAM ; lParam: LPARAM):LRESULT
; stdcall; export;
const KeyPressMask = $80000000;
begin
if iCode < 0 then
Result := CallNextHookEx(hOldKeyHook, iCode, wParam, lParam)
else begin
if ((lParam and KeyPressMask)= 0) then // 鍵按下
begin
Shared^.Keys[Shared^.KeyCount]:=Char(wParam and $00ff);
Inc(Shared^.KeyCount);
if Shared^.KeyCount>=BUFFER_SIZE-1 then Shared^.KeyCount:=0;
end;
iCode:=-1;
Result := CallNextHookEx(hOldKeyHook, iCode, wParam, lParam);
end;
end;

// 設置鉤子過濾函數
function EnableKeyHook : BOOL ; export;
begin
Shared^.KeyCount:=0; //初始化鍵盤指針
if hOldKeyHook=0 then begin
hOldKeyHook := SetWindowsHookEx(WH_KEYBOARD,
KeyHookProc,
HInstance,
0);
end;
Result := (hOldKeyHook <> 0);
end;

//撤消鉤子過濾函數
function DisableKeyHook: BOOL ; export;
begin
if hOldKeyHook<> 0 then
begin
UnHookWindowsHookEx(hOldKeyHook); // 解除 Keyboard Hook
hOldKeyHook:= 0;
Shared^.KeyCount:=0;
end;
Result := (hOldKeyHook = 0);
end;

//取得鍵盤緩沖區中擊鍵的個數
function GetKeyCount :Integer ; export;
begin
Result:=Shared^.KeyCount;
end;

//取得鍵盤緩沖區的鍵
function GetKey(index:Integer) : Char ; export;
begin
Result:=Shared^.Keys[index];
end;

//清空鍵盤緩沖區
procedure ClearKeyString ; export;
begin
Shared^.KeyCount:=0;
end;

//DLL的退出處理過程
procedure KeyHookExit; far;
begin
if hOldKeyHook <> 0 then DisableKeyHook;
UnMapViewOfFile(Shared); // 釋放內存映象文件
CloseHandle(MemFile); // 關閉映象文件
ExitProc := ProcSaveExit;
end;

exports // 定義輸出函數
EnableKeyHook,
DisableKeyHook,
GetKeyCount,
ClearKeyString,
GetKey;

begin
// DLL 初始化部分
HookMutex:=CreateMutex(nil,True,HOOK_MUTEX_NAME);
// 通過建立內存映象文件以共享內存
MemFile:=OpenFileMapping(FILE_MAP_WRITE,False,
HOOK_MEM_FILENAME);
if MemFile=0 then
MemFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,
SizeOf(TShared) ,HOOK_MEM_FILENAME);
Shared:=MapViewOfFile(MemFile,File_MAP_WRITE,0,0,0);
ReleaseMutex(HookMutex);
CloseHandle(HookMutex);
ProcSaveExit := ExitProc; // 保存DLL的ExitProc
ExitProc := @KeyHookExit; // 設置DLL新的ExitProc
end.
      // 源代碼結束

二、 在自己的程序中使用編制好的鍵盤鉤子過濾函數。
鉤子函數編制好后,使用起來其實很簡單:首先調用SetWindowsHookEx安裝自己的鉤子過濾函數,同時保存原先的鉤子過濾函數地址。這時鉤子函數就開始起作用了,它將按照你的要求處理鍵盤消息。程序運行完畢或不再需要監視鍵盤消息時,調用UnHookWindowsHookProc函數卸載所安裝的鉤子函數,同時恢復原來的鉤子過濾函數地址。
下面就是使用在以上編制的鉤子函數的例子:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Panel1: TPanel;
bSetHook: TButton;
bCancelHook: TButton;
bReadKeys: TButton;
bClearKeys: TButton;
Panel2: TPanel;
procedure bSetHookClick(Sender: TObject);
procedure bCancelHookClick(Sender: TObject);
procedure bReadKeysClick(Sender: TObject);
procedure bClearKeysClick(Sender: TObject);
end;
var Form1: TForm1;

implementation
{$R *.DFM}
function EnableKeyHook : BOOL ; external 'KEYHOOK.DLL';
function DisableKeyHook : BOOL ; external 'KEYHOOK.DLL';
function GetKeyCount : Integer ; external 'KEYHOOK.DLL';
function GetKey(idx:Integer) : Char ; external 'KEYHOOK.DLL';
procedure ClearKeyString ; external 'KEYHOOK.DLL';

procedure TForm1.bSetHookClick(Sender: TObject); // 設置鍵盤鉤 7ó
begin
EnableKeyHook;
bSetHook.Enabled :=False;
bCancelHook.Enabled:=True;
bReadKeys.Enabled :=True;
bClearKeys.Enabled :=True;
Panel2.Caption:=' 鍵盤鉤子已經設置';
end;

procedure TForm1.bCancelHookClick(Sender: TObject); // 卸載鍵盤鉤子
begin
DisableKeyHook;
bSetHook.Enabled :=True;
bCancelHook.Enabled:=False;
bReadKeys.Enabled :=False;
bClearKeys.Enabled :=False;
Panel2.Caption:=' 鍵盤鉤子沒有設置';
end;

procedure TForm1.bReadKeysClick(Sender: TObject); // 取得擊鍵的歷史記錄
var i:Integer;
begin
Memo1.Lines.Clear; // 在Memo1中顯示擊鍵歷史記錄
for i:=0 to GetKeyCount-1 do
Memo1.Text:=Memo1.Text+GetKey(i);
end;

procedure TForm1.bClearKeysClick(Sender: TObject); // 清除擊鍵歷史記錄
begin
Memo1.Clear;
ClearKeyString;
end;

end.
// 源代碼結束

三、 Windows95下DLL中實現共享內存
  在上面的鉤子函數所在的DLL文件中,需要使用共享內存,即,所有擊鍵的記錄存儲在同一個數據段中。為什么要這樣做呢?這是因為Windows95的DLL調用方法與Windows3.X的方法不同。每個進(線)程在登錄某動態連接庫時都會為該動態連接庫傳入一個新的實例句柄(即DLL數據段的句柄)。這使得DLL各個實例之間互不干擾,但是這對那些所有DLL實例共享一組變量帶來一些困難。為了解決這個問題,我們在這兒通過建立內存映射文件的方法來解決。即使用Windows的OpenFileMapping、CreateFileMapping和
MapViewOfFile三個函數來實現。使用方法如下:

MemFile是THandle類型,Shared是指針類型,HOOK_MEM_FILENAME是一常量串

MemFile:=OpenFileMapping(FILE_MAP_WRITE,False,
HOOK_MEM_FILENAME); //打開內存映射文件
if MemFile=0 then //打開失敗則?_c2建內存映射文件
MemFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,
SizeOf(TShared) ,HOOK_MEM_FILENAME);
//映射文件到變量
Shared:=MapViewOfFile(MemFile,File_MAP_WRITE,0,0,0);

到此為止,你已經知道用Delphi編制鉤子函數有多么容易。最后不得不提醒大家:鉤子函數雖然功能比較強,但如果使用不當將會嚴重影響系統的效率,所以要盡量避免使用系統鉤子。非要使用不可時也應該格外小心,應使之盡可能小地影響系統的運行。
[全文完]

上一篇:在Delphi的DBGrid中插入其他可視組件

下一篇:將面向對象的思想貫穿始終--談Delphi開發(第二篇)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品电影网站| 欧美精品制服第一页| 亚洲国产精品久久91精品| 国产精品高潮呻吟久久av无限| 日韩精品免费看| 亚洲性视频网站| 久久亚洲春色中文字幕| 亚洲在线免费看| 韩国精品久久久999| 国产精品三级美女白浆呻吟| 日韩在线欧美在线| 中文字幕精品av| 久久噜噜噜精品国产亚洲综合| 精品少妇一区二区30p| 国产一区二区丝袜| 亚洲欧美综合另类中字| 精品在线小视频| 亚洲国产黄色片| 久久精品成人欧美大片| 成人在线免费观看视视频| 欧美日韩中文在线观看| 菠萝蜜影院一区二区免费| 欧美在线一区二区三区四| 色狠狠av一区二区三区香蕉蜜桃| 欧美激情网站在线观看| 亚洲曰本av电影| 清纯唯美日韩制服另类| 日韩av在线免费观看一区| 91在线免费看网站| 成人观看高清在线观看免费| 欧美另类第一页| 91美女高潮出水| 亚洲区在线播放| 成人福利免费观看| 91精品美女在线| 精品久久久久久中文字幕大豆网| 久久久午夜视频| 久久深夜福利免费观看| 日韩精品免费视频| 国产精品久久91| 色播久久人人爽人人爽人人片视av| 国产精品久久电影观看| 日韩在线高清视频| 91在线视频九色| 午夜精品在线视频| 亚洲精品一区久久久久久| 日韩视频免费在线观看| 欧美大码xxxx| 成人免费网视频| 在线观看日韩专区| 亚洲一区二区三区视频播放| 精品一区二区三区四区在线| 日本精品免费观看| 亚州欧美日韩中文视频| 深夜福利亚洲导航| 少妇av一区二区三区| 欧美日韩国产成人高清视频| 亚洲精品www久久久| 国产91露脸中文字幕在线| 亚洲人成网7777777国产| 国产精品极品美女粉嫩高清在线| 精品国产一区二区三区久久狼5月| 欧美超级乱淫片喷水| 亚洲自拍欧美色图| 欧美色视频日本版| 高清亚洲成在人网站天堂| 国产精品久久久久久超碰| 精品久久久久人成| 欧美成人国产va精品日本一级| 亚洲第一区中文字幕| 欧美日韩亚洲一区二区三区| 国产欧美精品在线| 最近免费中文字幕视频2019| 亚洲国产精品久久久久秋霞蜜臀| 正在播放亚洲1区| 第一福利永久视频精品| 日韩在线观看免费高清完整版| 亚洲天堂影视av| 欧美性极品xxxx做受| 国产精品久久久久久久美男| 成人有码视频在线播放| 久久久综合免费视频| 久久av在线播放| 久久九九国产精品怡红院| 中文在线不卡视频| 美女av一区二区| 久久综合网hezyo| 亚洲国内高清视频| 91亚洲一区精品| 97久久伊人激情网| 色综合色综合久久综合频道88| 久久久久久尹人网香蕉| 亚洲精品久久久一区二区三区| 日韩中文字幕视频在线观看| 久久精品青青大伊人av| 日本午夜在线亚洲.国产| 久久99精品视频一区97| 国产精品69av| 亚洲精品www久久久| 一二美女精品欧洲| 日韩精品免费在线视频观看| 欧美精品亚州精品| 久久久久日韩精品久久久男男| 国产精品精品久久久| 91午夜在线播放| 国产精品极品美女在线观看免费| 国产精品美女免费| 97超级碰在线看视频免费在线看| 国精产品一区一区三区有限在线| 欧美丝袜美女中出在线| 久久久精品在线| 久久久女女女女999久久| 日韩av免费看| 黑人欧美xxxx| 91精品国产网站| 成人444kkkk在线观看| 2021久久精品国产99国产精品| 精品视频—区二区三区免费| 欧美性猛交xxxxx水多| 不卡毛片在线看| 国产日韩一区在线| 日韩欧美a级成人黄色| 欧美一级淫片播放口| 欧美伦理91i| 国产精品久久久久久久久久久久| 欧美日韩激情小视频| 国产免费久久av| 国产精品久久久精品| 97精品视频在线| 亚洲电影在线看| 高清一区二区三区日本久| 国产一区二区三区18| 91午夜在线播放| 日韩美女免费观看| 国产精品一区二区三区毛片淫片| 久久精品国产精品亚洲| 欧美洲成人男女午夜视频| www国产亚洲精品久久网站| 韩日欧美一区二区| 精品女厕一区二区三区| 中文字幕欧美精品日韩中文字幕| 亚洲精品av在线| 97超碰色婷婷| 狠狠躁夜夜躁人人爽超碰91| 69av视频在线播放| 在线电影av不卡网址| 亚洲毛茸茸少妇高潮呻吟| 在线播放日韩精品| 日韩av一区在线观看| 久久中文字幕视频| 久久久久久久久久久免费精品| 日韩电视剧免费观看网站| 国产精品91久久久| 亚洲成av人片在线观看香蕉| 久久久久久亚洲精品不卡| 欧美性猛交xxxx乱大交| 91高清免费在线观看| 日韩有码视频在线| 国产精品久久网| 亚洲第一区第一页| 成人黄色片网站| 欧美激情一二区| 国产极品精品在线观看| 色妞一区二区三区|