I
ITBlueCollar
Unregistered / Unconfirmed
GUEST, unregistred user!
写一个程序的时候想用钩子,在用的时候出现一个的问题:<br>用键盘全局钩子没什么问题,但是用WH_CBT或者WH_CALLWNDPROC,WH_SHELL 全局钩子的时候<br>却只能拦截到这个程序本身的消息,不能拦截到其他程序的消息。一个测试程序如下:<br><br>{用于测试全局钩子的Dll文件}<br>library ProjectDllTest;<br>uses<br> SysUtils,<br> Windows,<br> Classes,<br> IniFiles,<br> Messages;<br><br>{$R *.res}<br><br>var<br> KeyboardHook: HHOOK;<br> CBTHandle: HHOOK;<br> IniTest: TIniFile;<br><br>//---------------- keyboard hook -------------------------------<br>{<br>键盘全局钩子消息处理测试函数:<br>}<br>function KeyboardProc(nCode: Integer;wParam: WPARAM; lParam: LPARAM): LRESULT;stdcall;<br>begin<br> if(HC_ACTION = nCode) then<br> begin<br> //如果按下F8,则弹出对话框<br> if(VK_F8 = wParam) then<br> MessageBox(0,'virtual key : F8','get a virtual key',MB_OK);<br> end;<br> Result := CallNextHookEx(KeyboardHook,nCode,wParam,lParam);<br>end;<br><br>// 设置全局键盘钩子<br>function EnableKeyboardHook(): Boolean; stdcall; export;<br>begin<br> KeyboardHook := SetWindowsHookEx(WH_KEYBOARD,@KeyboardProc,hInstance,0);<br> if( KeyboardHook <> 0) then Result := True<br> else Result := False;<br>end;<br><br>// 取消全局键盘钩子<br>function DisableKeyboardHook(): Boolean; stdcall; export;<br>begin<br> if( KeyboardHook <> 0) then<br> begin<br> UnhookWindowsHookEx(KeyboardHook);<br> Result := True;<br> end<br> else Result := False;<br>end;<br><br><br>//--------------------------- CBT Hook test ---------------------------<br>// CBT(computer-based training )全局钩子测试函数<br>function CBTProc(nCode: Integer;wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;<br>begin<br> if( HCBT_CREATEWND = nCode) then<br> begin<br> // 如果消息为 HCBT_CREATEWND,则将该窗口的句柄记录到 log 文件中<br> if(IniTest <> nil) then<br> begin<br> IniTest.WriteString('HCBT_CREATEWND',IntToHex(wParam,2),'Created');<br> end;<br> end<br> else if(HCBT_DESTROYWND = nCode) then<br> begin<br> // 如果消息为 HCBT_DESTROYWND,则将该窗口的句柄记录到 log 文件中<br> if(IniTest <> nil) then<br> begin<br> IniTest.WriteString('HCBT_DESTROYWND',IntToHex(wParam,2),'Destroy');<br> end;<br> end;<br> Result := CallNextHookEx(CBTHandle,nCode,wParam,lParam);<br>end;<br><br>// 设置CBT全局钩子<br>function EnableCBTHook(): Boolean; stdcall; export;<br>begin<br> CBTHandle := SetWindowsHookEx(WH_CBT,@CBTProc,hInstance,0);<br> // 用于记录消息的 log文件<br> IniTest := TIniFile.Create('f:/log.ini');<br> if( IniTest <> nil) then IniTest.WriteString('Enable CBT Hook','Start','OK');<br> if( CBTHandle = 0) then Result := False<br> else Result := True;<br>end;<br><br>//取消 CBT全局钩子<br>function DisableCBTHook(): Boolean; stdcall; export;<br>begin<br> if( IniTest <> nil) then<br> begin<br> IniTest.WriteString('Enable CBT Hook','Finish','OK');<br> IniTest.Destroy;<br> IniTest := nil;<br> end;<br> if( CBTHandle <> 0) then UnhookWindowsHookEx(CBTHandle);<br> Result := True;<br>end;<br><br>exports<br> EnableKeyboardHook, DisableKeyboardHook, EnableCBTHook,DisableCBTHook ;<br>end.<br><br>//----------------------------------------------------------------------------<br>{用于测试的窗体文件}<br>unit Unit1;<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> BtbEnableKeyboardHook: TButton;<br> BtnDisableKeyboardHook: TButton;<br> BtnEnableCBTHook: TButton;<br> BtnDisableCBTHook: TButton;<br> procedure BtbEnableKeyboardHookClick(Sender: TObject);<br> procedure BtnDisableKeyboardHookClick(Sender: TObject);<br> procedure BtnEnableCBTHookClick(Sender: TObject);<br> procedure BtnDisableCBTHookClick(Sender: TObject);<br> private<br> { Private declarations }<br> public<br> { Public declarations }<br> end;<br><br>var<br> Form1: TForm1;<br><br>function EnableKeyboardHook: Boolean; stdcall; external 'ProjectDllTest.dll';<br>function DisableKeyboardHook: Boolean; stdcall; external 'ProjectDllTest.dll';<br>function EnableCBTHook: Boolean; stdcall; external 'ProjectDllTest.dll';<br>function DisableCBTHook: Boolean; stdcall; external 'ProjectDllTest.dll';<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure TForm1.BtbEnableKeyboardHookClick(Sender: TObject);<br>begin<br> EnableKeyboardHook();<br>end;<br><br>procedure TForm1.BtnDisableKeyboardHookClick(Sender: TObject);<br>begin<br> DisableKeyboardHook();<br>end;<br><br>procedure TForm1.BtnEnableCBTHookClick(Sender: TObject);<br>begin<br> EnableCBTHook();<br>end;<br><br>procedure TForm1.BtnDisableCBTHookClick(Sender: TObject);<br>begin<br> DisableCBTHook();<br>end;<br>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br>begin<br> DisableCBTHook();<br>end;<br><br>end.<br><br>运行程序发现,启用键盘钩子按下F8,会弹出两个MessageBox(KeyDown,KeyUp各一个),<br>因此键盘钩子可以正常使用,<br>但是启用CBT钩子之后,CBT钩子却只收到该程序本身的消息,比如在窗口上弹出系统菜<br>单,这个菜单将会被记录到log中,但是在这个程序外创建的窗口就没有任何信息,这是<br>为什么???<br>高手指点指点,多谢!