SystemParametersInfo(Spi_screensaverrunning,1,@temp,0) 函数用于 Win9x/Me 中可以<br>是系统进入屏幕保护状态,达到屏蔽 Ctrl+Alt+Del 这样的特殊系统组合键,但是在 WinNT<br>/2000 下无效。在 NT 4.0 + SP3/Win 2000 环境下,需要用到低级键盘钩子,才能捕获到<br>这类按键。程序中需要用到 KBDLLHOOKSTRUCT 这个结构,但在 Delphi 中没有声明,还要<br>用到几个常量,Delphi 也没有声明,估计是被省略掉了。键盘钩子函数如果要变成全局钩<br>子,必须存放在 DLL 中;如果仅是对于特定线程有效,可以放在 EXE 中。下面是我的代码<br>例子,在 Delphi 6 中编译通过:<br><br>unit Main;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> Dialogs, ExtCtrls, StdCtrls;<br><br>type<br> TMainForm = class(TForm)<br> EnableBtn: TButton;<br> DisableBtn: TButton;<br> AboutBtn: TButton;<br> ExitBtn: TButton;<br> Bell1: TBevel;<br> Image: TImage;<br> procedure AboutBtnClick(Sender: TObject);<br> procedure FormCreate(Sender: TObject);<br> procedure EnableBtnClick(Sender: TObject);<br> procedure DisableBtnClick(Sender: TObject);<br> procedure ExitBtnClick(Sender: TObject);<br> procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);<br> procedure FormDestroy(Sender: TObject);<br> private<br> { Private declarations }<br> public<br> { Public declarations }<br> end;<br><br>var<br> MainForm: TMainForm;<br><br>implementation<br><br>uses Hook;<br><br>{$R *.dfm}<br><br>type<br> // Declaration from VC++ WINUSER.H<br> //<br> PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;<br> KBDLLHOOKSTRUCT = record<br> vkCode: DWORD;<br> scanCode: DWORD;<br> flags: DWORD;<br> time: DWORD;<br> dwExtraInfo: DWORD;<br> end;<br><br>const<br> LLKHF_ALTDOWN = KF_ALTDOWN shr 8;<br> WH_KEYBOARD_LL = 13;<br><br>var<br> hhkNTKeyboard: HHOOK; // 钩子句柄<br><br>// 低级键盘钩子回调函数<br>//<br>function LowLevelKeyboardFunc(nCode: Integer; w_Param: WPARAM;<br> l_Param: LPARAM): LRESULT; stdcall;<br>var<br> blEatKeystroke: Boolean;<br> p: PKBDLLHOOKSTRUCT;<br>begin<br> blEatKeystroke := False;<br> if nCode = HC_ACTION then<br> begin<br> case w_Param of<br> WM_KEYDOWN,<br> WM_SYSKEYDOWN,<br> WM_KEYUP,<br> WM_SYSKEYUP:<br> begin<br> p := PKBDLLHOOKSTRUCT(l_Param);<br><br> // 进行按键过滤<br> blEatKeystroke := (((p^.vkCode = VK_TAB) and<br> ((p^.flags and LLKHF_ALTDOWN) <> 0)) or<br> ((p^.vkCode = VK_ESCAPE) and<br> ((p^.flags and LLKHF_ALTDOWN) <> 0)) or<br> ((p^.vkCode = VK_ESCAPE) and<br> ((GetKeyState(VK_CONTROL) and $8000) <> 0)) or<br> ((p^.vkCode = VK_DELETE) and<br> ((p^.flags and LLKHF_ALTDOWN) <> 0) and<br> ((GetKeyState(VK_CONTROL) and $8000) <> 0)));<br> end;<br> end; // End of Case<br> end;<br> if blEatKeystroke then<br> begin<br> Result := 1; // 捕获这些组合键,按键消息由自己处理,必须返回 1<br> Hook.ShowHookInfo; // 显示一个窗口,你可以改为自己的处理代码<br> end<br> else<br> // 其他的按键,交由别的线程处理(过滤)<br> Result := CallNextHookEx(0, nCode, w_Param, l_Param);<br>end;<br><br>procedure TMainForm.AboutBtnClick(Sender: TObject);<br>begin<br> Application.MessageBox(<br> PChar('Windows NT 键盘钩子演示程序'#13#10#13#10'作者:Phoenix2000,2001年7月。'),<br> '关于本程序', 0);<br>end;<br><br>procedure TMainForm.FormCreate(Sender: TObject);<br>begin<br> hhkNTKeyboard := 0; // 钩子句柄初值<br>end;<br><br>procedure TMainForm.EnableBtnClick(Sender: TObject);<br>begin<br> // 挂上键盘钩子<br> //<br> hhkNTKeyboard := SetWindowsHookEx(WH_KEYBOARD_LL,<br> LowLevelKeyboardFunc,<br> HInstance, 0);<br> if hhkNTKeyboard <> 0 then<br> Application.MessageBox('系统键盘钩子已经启动了!', '信息', 64)<br> else<br> Application.MessageBox('无法启动系统键盘钩子!', '错误', 16);<br>end;<br><br>procedure TMainForm.DisableBtnClick(Sender: TObject);<br>begin<br> // 解除键盘钩子<br> //<br> if hhkNTKeyboard = 0 then<br> Application.MessageBox('系统键盘钩子已经被禁止了!', '警告', 48)<br> else<br> begin<br> UnhookWindowsHookEx(hhkNTKeyboard); // 卸载钩子<br> hhkNTKeyboard := 0;<br> Hook.CleanHookForm; // 此行代码与钩子无关,不要误解,是我自己的窗体清除<br> Application.MessageBox('成功卸载系统键盘钩子!', '信息', 64)<br> end;<br>end;<br><br>procedure TMainForm.ExitBtnClick(Sender: TObject);<br>begin<br> Close;<br>end;<br><br>procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);<br>begin<br> CanClose := (hhkNTKeyboard = 0);<br> if not CanClose then<br> Application.MessageBox('请先卸载系统键盘钩子,然后再退出本程序!', '警告', 48);<br>end;<br><br>procedure TMainForm.FormDestroy(Sender: TObject);<br>begin<br> if hhkNTKeyboard <> 0 then<br> begin<br> UnhookWindowsHookEx(hhkNTKeyboard);<br> hhkNTKeyboard := 0;<br> end;<br> Hook.CleanHookForm;<br>end;<br><br>end.<br><br>以上的代码在 NT 4.0 + SP3/Win 2000 下能捕获 Alt + Tab、Alt + ESC、Ctrl + ESC 这<br>样的组合键,而 Ctrl + Alt + Del 无法捕获。有兴趣的朋友自己研究一下又没有别的办<br>法,或是我的代码由否不妥之处。另外,NT 环境下用低级键盘钩子,只有在 NT 4.0 + SP3<br>以上的版本才有效,在 NT 4 + SP2 都是无效的。在 Win2000 下当然有效了。<br>