为什么我的鼠标HOOK始终无法进行全局的捕捉呢?(100分)

S

sowen

Unregistered / Unconfirmed
GUEST, unregistred user!
我的DLL里其实很简单<br>一个<br>StartHook;export;<br><br>调用 <br><br>myHook := SetWindowsHookEx(WH_MOUSE,myHookProc,hInstance,0);<br><br>然后 myHookProc 里是如下:<br><br>function myHookProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM):LRESULT;stdcall;<br>var<br>&nbsp; X, Y : Integer;<br>begin<br>result:=0;<br>if (wParam = WM_LBUTTONDOWN) or (wParam=WM_NCLBUTTONDOWN) then<br>begin<br>&nbsp; X := PMouseHookStruct(lParam).pt.X;<br>&nbsp; Y := PMouseHookStruct(lParam).pt.Y;<br>&nbsp; log('Stop Hook at' + inttostr(X) + ';' + inttostr(Y));<br>&nbsp; UnhookWindowsHookEx(myHook);<br>&nbsp; exit;<br>end;<br><br>if (wParam = WM_NCMouseMove) or (wParam=WM_MOUSEMOVE) then<br>begin<br>&nbsp; X := PMouseHookStruct(lParam).pt.X;<br>&nbsp; Y := PMouseHookStruct(lParam).pt.Y;<br>&nbsp; log(inttostr(X) + ';' + inttostr(Y));<br>end;<br><br>result := CallNextHookEx(myHook, iCode, wParam, lParam);<br>end;<br><br>目的是让用户 starthook 之后,移动鼠标到任意一点点击鼠标左键后得到座标<br><br>可是我怎么也无法实现,经过LOG分析,鼠标移出调用 starthook 函数的窗体就没有记录了。<br><br>我到底做错了什么呢?<br>
 
問題可能在於你Log的寫法; 因為如果為Global的Hook,當由其它進程的消息處理時, 是將<br>你指定的dll載入到該進程中, 再執行其中的Code; 所以, 第一, 你無法在 Hook procedure<br>中處理釋放的Hook procedure; 因為如果在其它進程執行時, myHook變量值會是0, 因為跟<br>本不是在該進程中去設定Hook; 如果要釋放的話, 要以跨行程的機制通知設定Hook的進程<br>才可以釋放; 至於Log應該是有用的, 要看你Log函數的寫法! 不過要注意的全局變量的使用<br>因為不同進程中, 會有不同的全局變量, 你可以將Log函數再貼出, 看看問題在那裏
 
原来楼上的兄弟已经抢先了!我没有更新网页,望见谅!
 
事实上,我有取消用 LOG,而采用 sendmessage 往触发hook的窗体发送座标,而且是成功的,但鼠标一旦离开那个窗体就立刻失效<br><br>不过可能是因为 WndProc 是只能捕获自身窗体的消息吧<br><br>如果程序本身是没有问题,我怎么让鼠标移动出窗体后还能让触发窗体得到鼠标当时座标呢?<br><br>我原来的LOG也非常简单<br><br>procedure log(app:string);<br>var<br>&nbsp; lFile:TextFile;<br>&nbsp; l,fn:string;<br>begin<br>&nbsp; fn:='e:/Log.txt';<br>&nbsp; Assign(lFile,fn);<br>&nbsp; //rewrite(lFile);<br>&nbsp; append(lFile);<br>&nbsp; l:=DateTimeToStr(Now) + ':' + app;<br>&nbsp; Writeln(lFile,l);<br>&nbsp; closeFile(lFile);<br>end;<br><br>
 
在鼠标移动到你的窗口之外的时候,同样可以捕捉到鼠标事件啊,我把鼠标移动的事件处理也加进来<br>把,请看上边,我已经修改了.
 
你编的程序基本上没有什么问题,我仔细研究了你的程序,我最大的疑点就是,你的log()函数,可能覆盖了以前的内容.<br>另外为了安全,最好在用事件之前,先判断一下icode;如果小于0;就不允许做处理就返回.<br>下面是我仿造你的库改动了一下.目的是做个示范:记得要推出程序的时候要调用:unhook过程;<br>unit udll;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;<br>var<br>&nbsp;myhook:Thandle;<br>procedure starthook;stdcall;export;<br>procedure unhook;stdcall;export;<br>function myHookProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM):LRESULT;stdcall;<br>procedure log(ss:string);<br><br><br>implementation<br>procedure starthook;stdcall;<br>begin<br>myhook:=SetWindowsHookEx(WH_MOUSE,myHookProc,hInstance,0);<br>end;<br><br>function myHookProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM):LRESULT;stdcall;<br>var<br>&nbsp; X, Y : Integer;<br>begin<br>result:=0;<br>if iCode&lt;0 then //为了hook的安全此处应该判断...<br>&nbsp;begin<br>&nbsp; result := CallNextHookEx(myHook, iCode, wParam, lParam);<br>&nbsp; exit;<br>&nbsp;end;<br>if (wParam = WM_LBUTTONDOWN) or (wParam=WM_NCLBUTTONDOWN) then<br>begin<br>&nbsp; X := PMouseHookStruct(lParam).pt.X;<br>&nbsp; Y := PMouseHookStruct(lParam).pt.Y;<br>&nbsp; log(#13+#10+'leftbutton click at' +'['+ inttostr(X) + ';' + inttostr(Y)+']');<br>end;<br>if (wParam = WM_NCMouseMove) or (wParam=WM_MOUSEMOVE) then<br>begin<br>&nbsp; X := PMouseHookStruct(lParam).pt.X;<br>&nbsp; Y := PMouseHookStruct(lParam).pt.Y;<br>&nbsp; log(' &nbsp;['+inttostr(X) + ';' + inttostr(Y)+']');<br>end;//一样的嘛,怎么会捕捉不到呢.<br><br><br>result := CallNextHookEx(myHook, iCode, wParam, lParam);<br>end;<br>procedure unhook;stdcall;export;<br>begin<br>&nbsp;unhookwindowshookex(myhook);<br>end;<br>procedure log(ss:string);<br>var<br>&nbsp;file1:Tmemorystream;<br>begin<br>&nbsp;try<br>&nbsp; file1:=tmemorystream.Create;<br>&nbsp; try<br>&nbsp; file1.LoadFromFile('e:/delphi/log.txt');<br>&nbsp; except<br>&nbsp; end;<br>&nbsp; file1.Position:=file1.size;<br>&nbsp; file1.Write(ss[1],length(ss));<br>&nbsp; file1.SaveToFile('e:/delphi/log.txt');<br>&nbsp;finally<br>&nbsp; file1.free;<br>&nbsp;end;<br>end;<br>end.<br><br><br>library prjdll;<br><br>uses<br>&nbsp; udll in 'udll.pas';<br><br>{$R *.RES}<br><br>exports<br>&nbsp;starthook,unhook;<br>begin<br>end.<br><br>
 
给你个全局捕捉的例子吧:http://service.lonetear.com/delphi/dispdoc.asp?id=1300
 
顶部