我写的mousehook为什么只在自己程序理有效?(300分)

  • 主题发起人 主题发起人 cAkk
  • 开始时间 开始时间
C

cAkk

Unregistered / Unconfirmed
GUEST, unregistred user!
目的是要捕获鼠标在屏幕上所在的窗口句柄,先DLL和form都自定义一个消息,<br>然后安装Hook时,把form的句柄传过去,当DLL捕获鼠标消息时,向该句柄发送<br>自定义消息,鼠标所在窗口句柄放在wParam里面:<br><br>DLL如下:<br>=================<br>library capwnd;<br><br>uses<br>&nbsp; SysUtils, Classes,windows,messages;<br>var<br>&nbsp; hNextHookProc: HHook;<br>&nbsp; procSaveExit: Pointer;<br>&nbsp; receiver,msg_id:integer;<br><br>const STR_MSGMOUSEPOS:pchar='WM_MOUSEPOS';<br><br>function MousePosHookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;<br>var h:hwnd;<br>begin<br>&nbsp; if iCode &amp;lt; 0 then<br>&nbsp; &nbsp; Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam)<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp; if wParam = WM_MOUSEMOVE then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; h:=windowfrompoint(PMouseHookStruct(lParam).pt);<br>&nbsp; &nbsp; &nbsp; if h&amp;lt;&amp;gt;0 then postmessage(receiver,msg_id,PMouseHookStruct(lParam).hwnd,0);<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Result := 0;<br>&nbsp; end;<br>end;<br><br>function EnableMouseHook(hld:hwnd): BOOL; export;<br>begin<br>&nbsp; Result := False;<br>&nbsp; receiver:=hld;<br>&nbsp; if hNextHookProc &amp;lt;&amp;gt; 0 then Exit;<br>&nbsp; hNextHookProc := SetWindowsHookEx(WH_MOUSE, MousePosHookHandler,HInstance, 0);<br>&nbsp; Result :=hNextHookProc &amp;lt;&amp;gt; 0 ;<br>end;<br><br>function DisableMouseHook: BOOL; export;<br>begin<br>&nbsp; if hNextHookProc &amp;lt;&amp;gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; UnhookWindowshookEx(hNextHookProc);<br>&nbsp; &nbsp; hNextHookProc := 0;<br>&nbsp; end;<br>&nbsp; Result := hNextHookProc = 0;<br>end;<br><br>procedure MouseHookExit;<br>begin<br>&nbsp; if hNextHookProc &amp;lt;&amp;gt; 0 then DisableMouseHook;<br>&nbsp; ExitProc := procSaveExit;<br>end;<br><br>procedure IntoDll; stdcall;<br>begin<br>&nbsp; msg_id:=RegisterWindowMessage(STR_MSGMOUSEPOS);<br>&nbsp; receiver:=0;<br>end;<br><br>exports<br>&nbsp; EnableMouseHook,<br>&nbsp; DisableMouseHook;<br>begin<br>&nbsp; Intodll;<br>&nbsp; hNextHookProc := 0;<br>&nbsp; procSaveExit := ExitProc;<br>&nbsp; ExitProc := @MouseHookExit;<br>end.<br><br><br>form如下:<br>==========<br>unit main;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure FormClose(Sender: TObject; var Action: TCloseAction);<br>&nbsp; &nbsp; procedure WndProc(var Mess: TMessage); override;<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; msg_id:integer;<br>const STR_MSGMOUSEPOS:pchar='WM_MOUSEPOS';<br><br>implementation<br>function EnableMouseHook(hld:hwnd): BOOL; external 'capwnd.DLL';<br>function DisableMouseHook: BOOL; external 'capwnd.DLL';<br><br>{$R *.DFM}<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp;msg_id:=RegisterWindowMessage(STR_MSGMOUSEPOS);<br>&nbsp;EnableMouseHook(handle);<br>end;<br><br>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br>begin<br>&nbsp; DisableMouseHook;<br>end;<br>procedure TForm1.WndProc(var Mess: TMessage);<br>begin<br>&nbsp; if (mess.msg=msg_id) then<br>&nbsp; &nbsp; &nbsp;caption:=inttostr(mess.WParam);<br>&nbsp; &nbsp;inherited;<br>end;<br><br>end.<br>
 
&gt;&gt;if wParam = WM_MOUSEMOVE then<br>这样不行,用wm_mousemove消息,鼠标移动,不是产生许多许多消息了!!!<br><br><br>&nbsp; &nbsp;
 
cAkk:<br>&nbsp; 赶快感谢o*o与hubdog吧,我是更局他们的提示改写的。<br><br>library capwnd;<br><br>uses<br>&nbsp; SysUtils,<br>&nbsp; Classes,<br>&nbsp; windows,<br>&nbsp; messages;<br><br>type TCommonData = record<br>&nbsp; &nbsp; &nbsp; &nbsp;HookID:HHook;<br>&nbsp; &nbsp; &nbsp; &nbsp;CallBackHandle:HWnd;<br>&nbsp; &nbsp; &nbsp;end;<br>var<br>&nbsp; hNextHookProc: HHook;<br>&nbsp; procSaveExit: Pointer;<br>&nbsp; receiver,msg_id:integer;<br>var &nbsp;HMapFile:THandle;<br>&nbsp; &nbsp; &nbsp;CommonData:^TCommonData;<br><br>const STR_MSGMOUSEPOS:pchar='WM_MOUSEPOS';<br><br>function MousePosHookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;<br>var h:hwnd;<br>begin<br>&nbsp; if iCode &lt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);<br>&nbsp; end<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp; if wParam = WM_MOUSEMOVE then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; h:=windowfrompoint(PMouseHookStruct(lParam).pt);<br>&nbsp; &nbsp; &nbsp; if h&lt;&gt;0 then postmessage(CommonData.CallBackHandle,msg_id,PMouseHookStruct(lParam).hwnd,0);<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Result := 0;<br>&nbsp; end;<br>end;<br><br>function EnableMouseHook(hld:hwnd): BOOL; export;<br>begin<br>&nbsp; Result := False;<br>&nbsp; CommonData.CallBackHandle:=hld;<br>&nbsp; if hNextHookProc &lt;&gt; 0 then Exit;<br>&nbsp; hNextHookProc := SetWindowsHookEx(WH_MOUSE, MousePosHookHandler,Hinstance, 0);<br>&nbsp; Result :=hNextHookProc &lt;&gt; 0 ;<br>end;<br><br>function DisableMouseHook: BOOL; export;<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; UnhookWindowshookEx(hNextHookProc);<br>&nbsp; &nbsp; hNextHookProc := 0;<br>&nbsp; end;<br>&nbsp; Result := hNextHookProc = 0;<br>end;<br><br>procedure MouseHookExit;<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then DisableMouseHook;<br>&nbsp; ExitProc := procSaveExit;<br>end;<br><br>procedure MapCommonData;<br>var FirstCall: Boolean;<br>begin<br>&nbsp; HMapFile:=OpenFileMapping(FILE_MAP_WRITE, False, 'sjhdfasdfasdfasd');<br>&nbsp; FirstCall:=(HMapFile = 0);<br>&nbsp; if FirstCall then<br>&nbsp; &nbsp; HMapFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TCommonData),'sjhdfasdfasdfasd');<br>&nbsp; CommonData:= MapViewOfFile(HMapFile, FILE_MAP_WRITE, 0, 0, 0);<br>&nbsp; if FirstCall then FillChar(CommonData^, SizeOf(TCommonData), 0);<br>end;<br><br><br>procedure IntoDll; stdcall;<br>begin<br>&nbsp; msg_id:= RegisterWindowMessage(STR_MSGMOUSEPOS);<br>&nbsp; receiver:=0;<br>end;<br><br>exports<br>&nbsp; EnableMouseHook,<br>&nbsp; DisableMouseHook;<br>begin<br>&nbsp; Intodll;<br>&nbsp; MapCommonData;<br>&nbsp; hNextHookProc := 0;<br>&nbsp; procSaveExit := ExitProc;<br>&nbsp; ExitProc := @MouseHookExit;<br>end.<br>
 
&gt;&gt; &nbsp; &nbsp; &nbsp;if h&lt;&gt;0 then postmessage(receiver,msg_id,PMouseHookStruct(lParam).hwnd,0);<br>PMouseHookStruct(lParam).hwnd一定指向h吗?<br>也许接收这个消息的永远是当前窗口(setcapture了?)
 
忘了说明,我已经在NT4+SP6下测试通过了。<br><br>BTW:<br>&nbsp; cAkk,你之所以不正确,是因为没留意以前的类似问题。呵呵。我又得 300分 &nbsp;{B-)
 
&gt;&gt;PMouseHookStruct(lParam).hwnd一定指向h吗?<br>&gt;&gt;也许接收这个消息的永远是当前窗口(setcapture了?)<br><br>我没有setcapture呀! 而且win32 api里面是这么说的:指向应该接受<br>该消息的窗口呀!<br><br>前卫: 你改了什么地方? 为什么这么改? 拜托解释一下. 代码太长,我实在<br>&nbsp; &nbsp; &nbsp; 懒的去比较改动的地方.
 
就是将receiver放到共享内存中.<br>&lt;font color=red&gt;<br>type TCommonData = record<br>&nbsp; &nbsp; &nbsp; &nbsp;HookID:HHook;<br>&nbsp; &nbsp; &nbsp; &nbsp;CallBackHandle:HWnd;<br>&nbsp; &nbsp; &nbsp;end;<br>var<br>&nbsp; hNextHookProc: HHook;<br>&nbsp; procSaveExit: Pointer;<br>&nbsp; receiver,msg_id:integer;<br>var &nbsp;HMapFile:THandle;<br>&nbsp; &nbsp; &nbsp;CommonData:^TCommonData;<br><br><br><br>&nbsp; &nbsp; &nbsp; if h《》0 then postmessage(CommonData.CallBackHandle,msg_id,PMouseHookStruct(lParam).hwnd,0);<br>&nbsp; &nbsp; <br>&lt;/font&gt;<br><br>&lt;font color=red&gt;<br>procedure MapCommonData;<br>var FirstCall: Boolean;<br>begin<br>&nbsp; HMapFile:=OpenFileMapping(FILE_MAP_WRITE, False, 'sjhdfasdfasdfasd');<br>&nbsp; FirstCall:=(HMapFile = 0);<br>&nbsp; if FirstCall then<br>&nbsp; &nbsp; HMapFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TCommonData),'sjhdfasdfasdfasd');<br>&nbsp; CommonData:= MapViewOfFile(HMapFile, FILE_MAP_WRITE, 0, 0, 0);<br>&nbsp; if FirstCall then FillChar(CommonData^, SizeOf(TCommonData), 0);<br>end;<br>&lt;/font&gt;<br>begin<br>&nbsp; Intodll;<br>&lt;font color=red&gt; &nbsp;MapCommonData; &nbsp; &lt;/font&gt;<br>&nbsp; hNextHookProc := 0;<br>&nbsp; procSaveExit := ExitProc;<br>&nbsp; ExitProc := @MouseHookExit;<br>end<br><br>
 
eyes: 即使我把<br>&nbsp; &nbsp; &nbsp; if h&lt;&gt;0 then postmessage(receiver,msg_id,PMouseHookStruct(lParam).hwnd,0);<br>&nbsp; &nbsp; &nbsp; 改成:<br>&nbsp; &nbsp; &nbsp; if h&lt;&gt;0 then postmessage(receiver,msg_id,h,0);<br>&nbsp; &nbsp; &nbsp; 也不成. &nbsp;:-(
 
我想着就是与Win3.1下DLL使用的不同吧,Win32的DLL的数据对不同的进程豆油不同<br>的拷贝!
 
好长的代码,我都眼晕了:)<br>to cAkk:<br>&nbsp; 如果你只是要得到鼠标下的窗口的句柄的话<br>用一个TTimer,在ontimer里<br>begin<br>&nbsp; getcursorpos(apoint);<br>&nbsp; h:=windowfrompoint(apoint);<br>end;<br>这多省事啊?
 
前卫: 为什么要放到mapfile里面? 难道不能直接传递hwnd?<br><br>&nbsp; &nbsp; &nbsp;对了!是不是因为这个hwnd传到DLL里面就没有意义了,因为不在一个地址空间?<br>&nbsp;<br>是不是呀? 你说呀1
 
hubdog: 我原先就是你说的那样做的,现在我也想不起来为什么非要用hook了. :-)<br>&nbsp; &nbsp; &nbsp; &nbsp; 好像是有原因的,但是实在想不起来了...%^$@#$^*(<br><br>前卫:我好像明白了.
 
hwnd是全局的
 
hehe,是因为PMouseHookStruct分配的内存离开dll后就会被释放掉<br>所以必须把pmousehookstruct里的东西放到共享内存中
 
&gt;&gt;hwnd是全局的<br>那为什么我原先的不行? 我想知道原来的代码错在什么地方?
 
To Hubdog:<br>&nbsp; 不是将pmousehookstruct放到共享内存中,是把接受的HWND的Handle放到共享内存
 
hwnd是全局的,但是放hwnd数值的地方不是全局的
 
&gt;&gt;因为PMouseHookStruct分配的内存离开dll后就会被释放掉<br>那如果我改用sendmessage是不是就可以呢? sendmessage会等待消息被处理的.
 
后退
顶部