简单解释用到的Api函数: function SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId: DWORD): HHOOK; stdcall; 功能:设置钩子。如果指定了某个确定的线程就只监视那个线程,即是线程钩子;如果为空,即是监视所有线程的全局钩子。 参数:第一个参数是钩子的类型; 第二个参数是钩子函数的地址; 第三个参数是包含钩子函数的模块句柄; 第四个参数指定监视的线程; 返回值: 如果成功返回所设钩子的句柄,失败返回False。 function UnhookWindowsHookEx(hhk: HHOOK): BOOL; stdcall; 功能:卸载某个钩子。 参数:要卸载的钩子的句柄。 返回值:成功为True 失败为False。 function GetKeyState(nVirtKey: Integer): SHORT; stdcall; 功能:得到键盘上某个键的状态。 参数:按键的虚拟键值。 返回值:一个16位数,如果按下了,那么返回值的最高位为1即16进制800000,没有按下就 返回0。 更详细的请看Delphi自带的Win32 SDK手册。 不再多说了,说多了就偏离重点了。要是你连钩子函数都不会用可以参考我以前写的一篇文章《学用钩子函数》 程序如下: 还要记得要放两个Button控件到Form1上并设置相应的鼠标单击事件。 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; {按键消息的结构,Delphi中也没有,自己定义吧。这也就我为什么说用C写 这样的程序更好的原因之一。还必须注意的是这个结构在Windows NT 4 sp3以上系统 中才能使用} tagKBDLLHOOKSTRUCT = packed record vkCode: DWORD;//虚拟键值 scanCode: DWORD;//扫描码值(没有用过,我也不懂^_^) {一些扩展标志,这个值比较麻烦,MSDN上说得也不太明白,但是 根据这个程序,这个标志值的第六位数(二进制)为1时ALT键按下为0相反。} flags: DWORD; time: DWORD;//消息时间戳 dwExtraInfo: DWORD;//和消息相关的扩展信息 end; KBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT; PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT; //这个是低级键盘钩子的索引值,Delphi中没有,必须自己定义 const WH_KEYBOARD_LL = 13; //定义一个常量好和上面哪个结构中的flags比较而得出ALT键是否按下 const LLKHF_ALTDOWN = $20; var Form1: TForm1; hhkLowLevelKybd: HHOOK; implementation { 功能:低级键盘钩子的回调函数,在里面过滤消息 参数:nCode 是Hook的标志 WParam 表示消息的类型 LParam 是一个指向我们在上面定义的哪个结构KBDLLHOOKSTRUCT的指针 返回值:如果不是0的话windows就把这个消息丢掉,程序就不会再收到这个消息了。 } function LowLevelKeyboardProc(nCode: Integer; WParam: WPARAM;LParam: LPARAM):LRESULT; stdcall; var fEatKeystroke: BOOL; p: PKBDLLHOOKSTRUCT; begin Result := 0; fEatKeystroke := FALSE; p := PKBDLLHOOKSTRUCT (lParam); //nCode值为HC_ACTION时表示WParam和LParam参数包涵了按键消息 if (nCode = HC_ACTION) then begin //拦截按键消息并测试是否是Ctrl+Esc、Alt+Tab、和Alt+Esc功能键。 case wParam of WM_KEYDOWN, WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP: fEatKeystroke := ((p.vkCode = VK_TAB) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or ((p.vkCode = VK_ESCAPE) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or ((p.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000) <> 0)); end; end; if fEatKeystroke = True then Result := 1; if nCode <> 0 then Result := CallNextHookEx(0, nCode, wParam, lParam); end; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin //设置低级键盘钩子 if hhkLowLevelKybd = 0 then begin hhkLowLevelKybd := SetWindowsHookExW(WH_KEYBOARD_LL, LowLevelKeyboardProc, Hinstance, 0); if hhkLowLevelKybd <> 0 then MessageBox(Handle, '低级键盘钩子设置成功!', '提示', MB_OK) else MessageBox(Handle, '低级键盘钩子设置失败!', '提示', MB_OK); end else MessageBox(Handle, '低级键盘钩子已设置!', '提示', MB_OK); end; procedure TForm1.Button2Click(Sender: TObject); begin //卸载低级键盘钩子 if hhkLowLevelKybd <> 0 then if UnhookWindowsHookEx(hhkLowLevelKybd) <> False then begin MessageBox(Handle, '低级键盘钩子卸载成功!', '提示', MB_OK); hhkLowLevelKybd := 0; end else MessageBox(Handle, '低级键盘钩子卸载失败!', '提示', MB_OK) else MessageBox(Handle, '没有发现低级键盘钩子!', '提示', MB_OK); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin //在Form关闭的时候检测,如果没有卸载钩子就卸载之 if hhkLowLevelKybd <> 0 then UnhookWindowsHookEx(hhkLowLevelKybd); end; end. 程序在Delphi6+Windows2000 sp2中编译并测试通过。
屏蔽 Var Temp:integer; begin SystemParametersInfo(Spi_screensaverrunning,1,@temp,0); end; 恢复 Var Temp:integer; begin SystemParametersInfo(spi_screensaverrunning,0,@temp,0); end;
