程序大概是这样的,没优化,对不起读者了啊<br><br><br>unit main;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> Dialogs, StdCtrls;<br><br>type<br> TForm1 = class(TForm)<br> Button1: TButton;<br> Button2: TButton;<br> Button3: TButton;<br> CheckBox1: TCheckBox;<br> Button4: TButton;<br> procedure Button1Click(Sender: TObject);<br> procedure Button2Click(Sender: TObject);<br> procedure FormClose(Sender: TObject; var Action: TCloseAction);<br> procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);<br> procedure Button3Click(Sender: TObject);<br> procedure Button4Click(Sender: TObject);<br> private<br> { Private declarations }<br> public<br> { Public declarations }<br> end;<br><br> {按键消息的结构,Delphi中也没有,自己定义吧。这也就我为什么说用C写<br> 这样的程序更好的原因之一。还必须注意的是这个结构在Windows NT 4 sp3以上系统<br> 中才能使用}<br> tagKBDLLHOOKSTRUCT = packed record<br> vkCode: DWORD;//虚拟键值<br> scanCode: DWORD;//扫描码值(没有用过,我也不懂^_^)<br> {一些扩展标志,这个值比较麻烦,MSDN上说得也不太明白,但是<br> 根据这个程序,这个标志值的第六位数(二进制)为1时ALT键按下为0相反。}<br> flags: DWORD;<br> time: DWORD;//消息时间戳<br> dwExtraInfo: DWORD;//和消息相关的扩展信息<br> end;<br> KBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT;<br> PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;<br><br> //这个是低级键盘钩子的索引值,Delphi中没有,必须自己定义<br> const WH_KEYBOARD_LL = 13;<br> //定义一个常量好和上面哪个结构中的flags比较而得出ALT键是否按下<br> const LLKHF_ALTDOWN = $20;<br><br> var<br> Form1: TForm1;<br> hhkLowLevelKybd: HHOOK;<br>Function MyEnumCallBack (EnumHandle : HWnd; EnumValue : Integer) : Boolean; Stdcall;<br>Function MyEnumCallBack1 (EnumHandle : HWnd; EnumValue : Integer) : Boolean; Stdcall;<br><br> implementation<br> {<br> 功能:低级键盘钩子的回调函数,在里面过滤消息<br> 参数:nCode 是Hook的标志<br> WParam 表示消息的类型<br> LParam 是一个指向我们在上面定义的哪个结构KBDLLHOOKSTRUCT的指针<br> 返回值:如果不是0的话windows就把这个消息丢掉,程序就不会再收到这个消息了。<br> }<br>function LowLevelKeyboardProc(nCode: Integer;<br>WParam: WPARAM;LParam: LPARAM):LRESULT; stdcall;<br>var h:integer;<br>var<br> fEatKeystroke: BOOL;<br> p: PKBDLLHOOKSTRUCT;<br>begin<br> Result := 0;<br> fEatKeystroke := FALSE;<br> p := PKBDLLHOOKSTRUCT (lParam);<br> //nCode值为HC_ACTION时表示WParam和LParam参数包涵了按键消息<br> if (nCode = HC_ACTION) then begin<br> //拦截按键消息并测试是否是Ctrl+Esc、Alt+Tab、和Alt+Esc功能键。<br> end;<br>form1.caption:=inttostr(p.flags) ;<br> if p.flags=32 then begin<br> form1.caption:='按下';<br> EnumWindows(@MyEnumCallBack,0);<br> end;<br> if p.flags=128 then begin<br> form1.caption:='抬起';<br> UnhookWindowsHookEx(hhkLowLevelKybd);<br> EnumWindows(@MyEnumCallBack1,0);<br> hhkLowLevelKybd := SetWindowsHookExW(WH_KEYBOARD_LL, LowLevelKeyboardProc, Hinstance, 0);<br> end;<br> if nCode <> 0 then<br> Result := CallNextHookEx(0, nCode, wParam, lParam);<br><br> end;<br> {$R *.dfm}<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> Button3.Show;<br> //设置低级键盘钩子<br> if hhkLowLevelKybd = 0 then begin<br> hhkLowLevelKybd := SetWindowsHookExW(WH_KEYBOARD_LL,<br> LowLevelKeyboardProc, Hinstance, 0);<br> if hhkLowLevelKybd <> 0 then<br> else<br> MessageBox(Handle, '低级键盘钩子设置失败!', '提示', MB_OK);<br> end else begin<br> MessageBox(Handle, '低级键盘钩子已设置!', '提示', MB_OK);<br> end;<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br> //卸载低级键盘钩子<br> if hhkLowLevelKybd <> 0 then<br> if UnhookWindowsHookEx(hhkLowLevelKybd) <> False then begin<br> MessageBox(Handle, '低级键盘钩子卸载成功!', '提示', MB_OK);<br> hhkLowLevelKybd := 0;<br> end else<br> MessageBox(Handle, '低级键盘钩子卸载失败!', '提示', MB_OK)<br> else<br> MessageBox(Handle, '没有发现低级键盘钩子!', '提示', MB_OK);<br>end;<br><br>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br>begin<br> //在Form关闭的时候检测,如果没有卸载钩子就卸载之<br> if hhkLowLevelKybd <> 0 then<br> UnhookWindowsHookEx(hhkLowLevelKybd);<br>end;<br><br>Function MyEnumCallBack (EnumHandle : HWnd; EnumValue : Integer) : Boolean; Stdcall;<br> var<br> lpBuf : Array [0..255] of char;<br> begin<br> Result := True;<br> if (GetWindowText(EnumHandle,@lpBuf,255) > 0) //then<br> and (GetWindowLong(EnumHandle, GWL_EXSTYLE or WS_EX_OVERLAPPEDWINDOW) <> 0  
then<br> begin<br> if Pos('Pop',StrPas(lpBuf)) > 0 then begin<br>//SendMessage(EnumHandle,WM_NCLBUTTONDOWN,HTCaption,GetMessagePos);<br>ReleaseCapture;<br> SendMessage(EnumHandle, WM_SYSCOMMAND, SC_move,0);<br>ReleaseCapture;<br>ReleaseCapture;<br>ReleaseCapture;<br>ReleaseCapture;<br>ReleaseCapture;<br>ReleaseCapture;<br>ReleaseCapture;<br>// SendMessage(EnumHandle, WM_SYSCOMMAND, SC_MOVE,0);<br> end;<br> end;<br> end;<br><br>Function MyEnumCallBack1 (EnumHandle : HWnd; EnumValue : Integer) : Boolean; Stdcall;<br> var<br> lpBuf : Array [0..255] of char;<br> begin<br> Result := True;<br> if (GetWindowText(EnumHandle,@lpBuf,255) > 0) //then<br> and (GetWindowLong(EnumHandle, GWL_EXSTYLE or WS_EX_OVERLAPPEDWINDOW) <> 0  
then<br> begin<br> if Pos('Pop',StrPas(lpBuf)) > 0 then begin<br>sendMessage(EnumHandle,CM_DIALOGKEY,VK_RETURN,0);<br><br>// SendMessage(EnumHandle, WM_SYSCOMMAND, SC_DEFAULT,0);<br> end;<br> end;<br> end;<br><br><br>procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);<br>begin<br> CanClose:=CheckBox1.Checked;<br>end;<br><br>procedure TForm1.Button3Click(Sender: TObject);<br>begin<br> EnumWindows(@MyEnumCallBack1,0);<br><br>end;<br><br>procedure TForm1.Button4Click(Sender: TObject);<br>begin<br> CheckBox1.Checked:=true;<br> close;<br>end;<br><br>end.