关于全局钩子,富翁帮忙看一下.(100分)

  • 主题发起人 主题发起人 gzhk
  • 开始时间 开始时间
G

gzhk

Unregistered / Unconfirmed
GUEST, unregistred user!
刚刚学习钩子,可是在调用的时候总会报错,请帮我看一下那里有错.<br>*****钩子的功能为:当接收到系统打印对列中有任务后,发送WM_SPOOLERSTATUS消息给调用程序,以实现对打印任务实时监控.<br>________________________________________________________________<br>library PrinterHook;<br>uses<br>&nbsp; SysUtils,<br>&nbsp; Classes,<br>&nbsp; Windows,<br>&nbsp; Messages;<br><br>var fHHook:HHook;<br>&nbsp; &nbsp; Apphandle:HWND;<br>{$R *.res}<br>//钩子处理过程<br>function ProcessHook(Code: Integer;WP:WParam;LP:LParam): LRESULT;stdcall;<br>begin<br>&nbsp; Result:=0;<br>&nbsp; if PMSG(lP).message=WM_SPOOLERSTATUS then<br>&nbsp; &nbsp; SendMessage(AppHandle,WM_SPOOLERSTATUS,WP,LP);<br>&nbsp; Result := CallNextHookEx(fHHook, Code, WP, LP);<br>end;<br>//注册钩子<br>function RegsiterHook(handle:HWND):boolean;stdcall;export;<br>begin<br>&nbsp; AppHandle:=handle;<br>&nbsp; fHHOOK:=SetWindowsHookEx(WH_GETMESSAGE,@ProcessHook,hInstance,0);<br>&nbsp; result:=true;<br>&nbsp; MessageBox(handle,'ok!','information',mb_ok);//Test...<br>end;<br>//撤消钩子<br>function UnRegsiterHook:boolean;stdcall;export;<br>begin<br>&nbsp; result:=UnhookWindowsHookEx(FHHOOK);<br>end;<br><br>exports<br>&nbsp; RegsiterHook,<br>&nbsp; UnRegsiterHook;<br>begin<br>end.<br>____________________________________________
 
code<br>Specifies whether the hook procedure must process the message. If code is HC_ACTION, the hook procedure must process the message. If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx. <br><br>改成这样试试:<br>function ProcessHook(Code: Integer;WP:WParam;LP:LParam): LRESULT;stdcall;<br>begin<br>&nbsp; Result:=0;<br>&nbsp; if Code = HC_ACTION then<br>&nbsp; begin<br>&nbsp; &nbsp; if PMSG(lP).message=WM_SPOOLERSTATUS then<br>&nbsp; &nbsp; &nbsp; SendMessage(AppHandle,WM_SPOOLERSTATUS,WP,LP);<br>&nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; Result := CallNextHookEx(fHHook, Code, WP, LP);<br>end;<br><br>
 
谢谢,经调试不会提示出错了,但是新的问题又有了, 在<br>if PMSG(lP).message=WM_SPOOLERSTATUS then<br>&nbsp; &nbsp; &nbsp; SendMessage(AppHandle,WM_SPOOLERSTATUS,WP,LP);<br>这一步,无法拦截到WM_SPOOLERSTATUS 消息?或者不知道那位能给我讲一WM_SPOOLERSTATUS 这个消息在系统中的运作流程?谢谢<br>&nbsp;
 
不是截不到那个消息,应该是你的DLL里面的AppHandle已经不是原来的AppHandle。你去找找这方面的例子吧,网上多的是。
 
确实是JamesBond_L说的情况,句柄为0已不再是原来的那个?更加不解???富翁帮我看下<br>谢谢楼上的和楼下的了.
 
DLL裡面的全局變量無法保存。你可以在其他地方保存,有個有效的方法就是CreateFileMapping在建立內存映射文件,往裡面寫HANDLE。下次用時就讀取。
 
http://fulldelphi.vip.sina.com/text/mousehook.htm<br>{在应用程序中跟踪MOUSE的坐标(hook)} <br>&nbsp; <br>{为什么选这个话题?因为跟踪MOUSE坐标很常见,容易又特别不容易,非常说明WINDOWS95下编程的特点。 <br>{ 如果您看不懂,请买DELPHI 2 UNLEASHED RMB133,当然他没这个程序,但有一些写WIN HOOK必须具备的知识。本程序得到AIMING大虾的大力协助,事实上我的程序是在他的基础上改写的,他的是从DELPHI HELP中改写出来的。调试程序花了我两个礼拜,最好你能花同样的时间,那么你就会收获很多! }<br><br>第一步,建一DLL,DELPHI中NEW-》DLL SAVE AS GETKEY<br><br>library getKey;<br><br>uses<br>SysUtils,<br>Windows,<br>HookMain in 'hookmain.pas';<br><br>exports<br>OpenGetKeyHook,<br>CloseGetKeyHook,<br>GetPublicP;<br><br>begin<br>NextHook := 0;<br>procSaveExit := ExitProc;<br>DLLproc := @DLLMain;<br>ExitProc := @HookExit;<br>DLLMain(DLL_PROCESS_ATTACH);<br>end.<br><br>第二步,建一UNIT ,HOOK MAIN。关键在于CreateFileMapping 和 消息 WM_NCMouseMove, WM_MOUSEMOVE:<br><br>unit HookMain; <br><br>interface <br>uses Windows, Messages, Dialogs, SysUtils; <br><br>//type DataBuf = Array [1..2] of DWORD;<br>type mydata=record<br>data1:array [1..2] of DWORD;<br>data2:TMOUSEHOOKSTRUCT;<br>end;<br>var hObject : THandle;<br>pMem : Pointer; <br>NextHook: HHook;<br>procSaveExit: Pointer; <br><br>function HookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export; <br>function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; export; <br>function CloseGetKeyHook: BOOL; export; <br>function GetPublicP : Pointer;stdcall; export; <br>Procedure DLLMain(dwReason:DWord); far; <br>procedure HookExit; far; <br><br>implementation <br><br>Procedure UnMapMem; <br>begin <br>if Assigned(pMem) then <br>begin <br>UnMapViewOfFile(pMem); <br>pMem := Nil <br>end; <br>end; <br><br>Procedure MapMem; <br>begin <br>hObject := CreateFileMapping($FFFFFFFF,Nil,Page_ReadWrite,0,$FFFF,pChar('_IOBuffer')); <br>if hObject = 0 then Raise Exception.Create('创建公用数据的Buffer不成功!'); <br>pMem := MapViewOfFile(hObject,FILE_MAP_WRITE,0,0,SizeOf(mydata));<br>// 1 or SizeOf(DataBuf) ???? <br>// 创建SizeOf(DataBuf)的数据区<br>if not Assigned(pMem) then <br>begin <br>UnMapMem; <br>Raise Exception.Create('创建公用数据的映射关系不成功!'); <br>end; <br>end; <br>Procedure DLLMain(dwReason:DWord); far; <br>begin <br>Case dwReason of <br>DLL_PROCESS_ATTACH : <br>begin <br>pMem := nil; <br>hObject := 0; <br>MapMem; //以下的公有数据,如tHWND,tMessageID将直接使用本Buf. <br>end; <br>DLL_PROCESS_DETACH : UnMapMem; <br>DLL_THREAD_ATTACH, <br>DLL_THREAD_DETACH :; //缺省 <br>end; <br>end; <br><br>procedure HookExit; far; <br>begin <br>CloseGetKeyHook; <br>ExitProc := procSaveExit;<br>end;<br><br>function GetPublicP : Pointer;export;<br>begin //这里引出了公用数据区的指针,你可以在你的应用程序中自由操作它。但建议去掉此接口。<br>Result := pMem;<br>end;<br><br>function HookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export;<br>begin<br>Result := 0;<br>If iCode &lt; 0<br>Then Result := CallNextHookEx(NextHook, iCode, wParam, lParam);<br><br><br>// This is probably closer to what you would want to do...<br>case wparam of<br>WM_LBUTTONDOWN:<br>begin<br>end;<br>WM_LBUTTONUP:<br>begin<br>end;<br>WM_LBUTTONDBLCLK:<br>begin<br>end;<br>WM_RBUTTONDOWN:<br>begin<br>messagebeep(1);<br>end;<br>WM_RBUTTONUP:<br>begin<br>end;<br>WM_RBUTTONDBLCLK:<br>begin<br>end;<br>WM_MBUTTONDOWN:<br>begin<br>end;<br>WM_MBUTTONUP:<br>begin<br>end;<br>WM_MBUTTONDBLCLK:<br>begin<br>end;<br>WM_NCMouseMove, WM_MOUSEMOVE:<br>begin<br>mydata(pmem^).data2:=pMOUSEHOOKSTRUCT(lparam)^;<br>// messagebeep(1);<br>//SendMessage(DataBuf(pMem^)[1],DataBuf(pMem^)[2],wParam,lParam );<br>SendMessage(mydata(pMem^).data1[1],mydata(pMem^).data1[2],wParam,integer(@(mydata(pmem^).data2)) );<br>end;<br>end; //发送消息<br>end;<br><br>function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; export;<br>begin<br>Result := False;<br>if NextHook &lt;&gt; 0 then Exit; //已经安装了本钩子<br>// DataBuf(pMem^)[1] := Sender; //填数据区<br>// DataBuf(pMem^)[2] := MessageID; //填数据区<br>mydata(pmem^).data1[1]:=sender;<br>mydata(pmem^).data1[2]:=messageid;<br><br>NextHook := SetWindowsHookEx(WH_mouse, HookHandler, HInstance, 0);<br>Result := NextHook &lt;&gt; 0; <br>end; <br><br>function CloseGetKeyHook: BOOL; export; <br>begin <br>if NextHook &lt;&gt; 0 then <br>begin <br>UnhookWindowshookEx(NextHook); //把钩子链链接到下一个钩子处理上. <br>NextHook := 0; <br>end; <br>Result := NextHook = 0; <br>end; <br><br>end. <br><br><br>第三步,测试DLL,建一PROJECT。关键在于override WndProc<br><br>unit Unit1;<br><br>interface<br><br>uses<br>Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>StdCtrls, ExtCtrls;<br><br>type<br>TForm1 = class(TForm)<br>uncapture: TButton;<br>capture: TButton;<br>Exit: TButton;<br>Panel1: TPanel;<br>show: TLabel;<br><br>Label1: TLabel;<br>counter: TLabel;<br>procedure ExitClick(Sender: TObject);<br>procedure uncaptureClick(Sender: TObject);<br>procedure captureClick(Sender: TObject);<br>private<br>{ Private declarations }<br>public<br>{ Public declarations }<br>procedure WndProc(var Message: TMessage); override;<br>end;<br><br>var<br>Form1: TForm1;<br>var num : integer; <br>const MessageID = WM_User + 100;<br>implementation<br><br>{$R *.DFM}<br>function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; external 'GetKey.DLL'; <br>function CloseGetKeyHook: BOOL; external 'GetKey.DLL'; <br><br>procedure TForm1.ExitClick(Sender: TObject);<br>begin<br>close;<br>end;<br><br>procedure TForm1.uncaptureClick(Sender: TObject);<br>begin<br>if CloseGetKeyHook then //ShowMessage('结束记录...');<br>show.caption:='结束记录...';<br>end;<br><br>procedure TForm1.captureClick(Sender: TObject);<br>begin<br>// if OpenGetKeyHook(self.Handle,MessageID) then ShowMessage('开始记录...');<br><br>if OpenGetKeyHook(Form1.Handle,MessageID) then<br>//ShowMessage('开始记录...');<br>show.caption:='开始记录...';<br>num := 0;<br><br><br>end;<br><br>procedure TForm1.WndProc(var Message: TMessage);<br>var x,y:integer;<br>begin<br>if Message.Msg = MessageID then<br>begin<br>// Panel1.Caption := IntToStr(Num);<br>x:=PMouseHookStruct( message.lparam)^.pt.x ;<br>y:=PMouseHookStruct( message.lparam)^.pt.y ;<br><br>panel1.caption:='x='+inttostr(x)+' y='+inttostr(y);<br>inc(Num);<br>counter.Caption := IntToStr(Num);<br>end<br>else Inherited;<br>end;<br><br>end.
 
http://dev.csdn.net/develop/article/21/21439.shtm<br>在給個地址給你參考。
 
非常谢谢!JamesBond_L,在你的指导下偶已经可以拦截到这个消息了.不知道可不可以交个朋友MSN:gzhk@263.net<br>另对thx1180也表示感谢.
 
后退
顶部