[400分 + RMB] 求获取鼠标在指定窗体里按下鼠标左键代码!(300分)

  • 主题发起人 主题发起人 jjyy5578
  • 开始时间 开始时间
J

jjyy5578

Unregistered / Unconfirmed
GUEST, unregistred user!
1,以XP自带的计算器为例,获取鼠标在计算器'5'的位置按下鼠标左键的信息 ( [red]重点:比如只知道目标程序整个窗体的句柄和标题的前提下, 5没有HANDLE 只能通过区域来判断[/red])<br><br>2,[red]无论改变屏幕分辨率 或 移动计算器窗口 或 计算器窗口等比例放大[/red] 也可以准确的截取在'5'的位置按下鼠标左键的信息,只要在5的位置按下左键就ShowMessage()<br><br>3,后台运行,程序要小,有无DLL无所谓,不要拿垃圾代码糊弄我.<br><br>4,高手写好后请发至Email:dfw8001@126.com &nbsp;或 QQ-617862323 测试通过马上结算!<br><br>5,因为一次最多只能用300分,解决问题后马上开贴再加100分,另外再加 人民币 具体多少QQ或电话谈
 
tcpmousehook,在google上搜索,带有demo的.
 
希望高手也发我一份,100分奉上
 
函数判断 XY是否在指定区域内<br>function PosInclude(R:Trect;X,Y:integer):boolean;<br> begin<br> &nbsp;if (X&gt;=R.Left) and (X&lt;=R.Right)<br> &nbsp; &nbsp;and (Y&gt;=R.Top) and (Y&lt;=R.Bottom)<br> &nbsp; &nbsp;then result:=true else result:=false;<br> &nbsp; &nbsp;end;<br>OnMouseUp,ONMouseDown,ONMouseMove 中的 X Y 相当于函数的X,Y<br>然后本地坐标和屏幕坐标转化 通过这两个函数<br>ScreenToClient &nbsp;ClientToScreen<br>例如:通过mouse.CursorPos 随时可取得鼠标当前的坐标<br>你想知道此坐标相对于你船体Uform的位置则 <br>var<br> uformMousePoint:TPoint;<br>begin<br> uformMousePoint:=uform.ScreenToClient( mouse.CursorPos);<br>//此时你知道你的某个控件的位置在form上你BoundsRect<br>你只要把 ONMouseDown中<br>PosInclude(ucom.BoundsRect,uformMousePoint.x,uformMousePoint.Y) 就知道是否在5上按下.<br> &nbsp;后台运行是什么意思? 你要全局钩子,截获按下的是什么键? &nbsp;没用的,只能得到鼠标在屏幕那个位置按下,但你不知道别人的计算器放那里,对于那些按键输密码的程序,键盘位置虽然已知,但按键的顺序却又不是固定的.<br> &nbsp;看你要这个东西就没安好心,你以为别人做密码输入的程序的都是笨蛋? 谁真能做这个东西,你400分没用的富翁毕 谁要?别人不知道去 卖 4000RMB. 你那口气就想个了别个400富翁币是给人多大的恩惠一样.懒得贴鼠标钩子给你了.心情不好!
 
to bmsr,<br>你要是高手可以加我QQ谈,说那些没用的干什么?但是看你的水平好像不行<br><br><br>顺便说一句,解决问题了直接加分 另外再加 人民币 &nbsp;具体多少QQ谈
 
楼主的例子和其要求可能是不一致的。<br>在计算器中的“5”是有Handle的。<br><br>MouseHook可以针对“5”的Handle进行勾取鼠标左键消息。但是如果没有Handle的话,那就必须按照父窗体的位置来人为计算了。<br>下面是一段公共代码:<br>library MouseHook;<br>uses<br> &nbsp;MouseIdle in 'MouseIdle.pas';<br>Exports<br> &nbsp;CreateHook,<br> &nbsp;RemoveHook;<br>{$R *.res}<br>begin<br> &nbsp;whHelp := 0;<br> &nbsp;procSaveExit := ExitProc;<br> &nbsp;ExitProc := @HelpHookExit;<br>end.<br>MouseIdle.pas代码:<br>unit MouseIdle;<br>interface<br>uses<br> &nbsp;Windows, Messages, SysUtils;<br>var<br> &nbsp;whHelp: HHook;<br> &nbsp;procSaveExit: Pointer;<br> &nbsp;function CreateHook(HookHandle:LongWORD): Boolean; export;<br> &nbsp;function RemoveHook: Boolean; export;<br> &nbsp;procedure HelpHookExit; far;<br> &nbsp;function HelpProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export;<br>implementation<br>function CreateHook(HookHandle:LongWORD): Boolean;<br>//HookHandle主要是指定要拦截的窗体句柄<br>var<br> &nbsp;ThreadID:LongWord;//获得拥有该窗体的线程句柄<br>begin<br> &nbsp;Result := false;<br> &nbsp;if whHelp &lt;&gt; 0 then Exit;<br> &nbsp;ThreadID := GetWindowThreadProcessId(HookHandle, nil);<br> &nbsp;whHelp := SetWindowsHookEx(WH_CALLWNDPROC, @HelpProc, Hinstance, ThreadID);<br> &nbsp;Result := whHelp &lt;&gt; 0;<br>end;<br><br>function RemoveHook: Boolean;<br>begin<br> &nbsp;if whHelp &lt;&gt; 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;UnHookWindowsHookEx(whHelp);<br> &nbsp; &nbsp;whHelp := 0;<br> &nbsp;end;<br> &nbsp;Result := whHelp = 0;<br>end;<br><br>procedure HelpHookExit;<br>begin<br> &nbsp;if whHelp &lt;&gt; 0 then<br> &nbsp; &nbsp;RemoveHook;<br> &nbsp;Exitproc := procSaveExit;<br>end;<br><br>function HelpProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export;<br>var<br> &nbsp;HandleStr : string;<br>begin<br> &nbsp;Result := 0;<br> &nbsp;if iCode &lt; 0 then Result := CallNextHookEx(whHelp, iCode, wParam, lParam);<br> &nbsp; &nbsp;if pcwpstruct(lParam)^.message = WM_LBUTTONDOWN then<br>//如果拦截到的消息是WM_LBUTTONDOWN,那么做如下的处理<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;HandleStr := inttostr(pcwpstruct(lparam)^.hwnd);<br> &nbsp; &nbsp; &nbsp; &nbsp;Messagebox(0, Pchar('click on:'+HandleStr), 'Hook', 0+64);<br> &nbsp; &nbsp;end;<br>end;<br>end.<br>调用dll的project的代码:<br>procedure TSpyWindowForm.Button1Click(Sender: TObject);<br>begin<br> &nbsp; &nbsp;CreateHook($00290512);//对指定的窗体安装钩子<br>end;<br><br>procedure TSpyWindowForm.Button2Click(Sender: TObject);<br>begin<br> &nbsp; &nbsp;RemoveHook;//卸载钩子<br>end;<br><br>可以挂在“5”上。其中Handle随着机器要更改。那就楼主搞定了
 
挂上也没什么用, 别人键盘录密码都是随即对那10个按键赋值.只能知道安的那个键,并不能知道 对每个键对应的值.何况键盘密码录入的按键根本不是有Handle的按键,比如 招行密码按键,wow验证码按键,只能得到是那个位置按了间,得不到按了什么,这些我都试过了
 
to xiammy, <br>谢谢你回帖,但是我的目标程序是没有Handle的,我只是拿计算器打个比方,你的方法行不通的
 
to bmsr,<br>你要是说WOW密码验证的时候得不到具体按的是什么,你可以加我,我给你看一下代码
 
DELPHI]判断鼠标按键<br>if GetAsyncKeyState(VK_LButton)&lt;&gt;0 then ... //左键]<br>if GetAsyncKeyState(VK_MButton)&lt;&gt;0 then ... //中键<br>if GetAsyncKeyState(VK_RButton)&lt;&gt;0 then ... //右键
 
谢谢楼主,你这么一提醒,我倒是想到了方法,只要能截屏,就可以通过截得得屏幕再在相应位置截取相应大小小块矩形小块,然后进行图象识别,就可以得到当时的键盘, 图象识别麻烦,那就干脆整个保存当时的屏幕,和当时鼠标按键记录.最后在自己计算机上单步模拟就行了.<br> 这样问题就简化成截屏和鼠标记录了.这两个我好想都会,哈哈! 我试试!
 
to bmsr,<br>真替你高兴,我也会继续努力的,大家加油
 
这个满足你,不行再给你贴一个:<br>Question/Problem/Abstract:<br><br>Capture mouse moves and clicks in all System. <br>Answer:<br><br><br>In this article, you have an example of installation of a hook type Shell at system level. <br><br>You will be able to control the movement and button clicks that take place in all Windows, (not only in your application) <br><br>As it is a hook at system level, this must go separated in a DLL. <br>To know more than the operation of the hook, the DLL and the communication between the DLL and our application, take a look to the <br>article: <br><br>http://www.delphi3000.com/articles/article_883.asp <br><br>since it is similar to this trick, and I won't repeat the explanations here. <br><br><br><br>hook's DLL<br><br><br><br>library hookMouse; <br><br>{Demo de hook de Ratón a nivel de sistema, Radikal.} <br><br>uses Windows, Messages; <br><br>const <br>CM_MANDA_DATOS = WM_USER + $1000; <br><br>type <br>TCompartido = record <br> &nbsp; Receptor, <br> &nbsp; wHitTestCode, <br> &nbsp; x,y, <br> &nbsp; Ventana &nbsp; &nbsp; &nbsp; &nbsp; : hwnd; <br>end; <br>PCompartido &nbsp; =^TCompartido; <br><br><br>var <br>hookDeMouse &nbsp;: Hhook; <br>FicheroM &nbsp; &nbsp; : THandle; <br>Compartido &nbsp; : PCompartido; <br><br><br>function CallBackDelhook( Code &nbsp; &nbsp;: Integer; <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;wParam &nbsp;: WPARAM; <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lParam &nbsp;: LPARAM <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;) &nbsp; &nbsp; &nbsp; : LRESULT; stdcall; <br><br>var <br> &nbsp;DatosMouse &nbsp; &nbsp; : PMousehookStruct; <br> &nbsp;Intentos &nbsp; &nbsp; &nbsp; : integer; <br><br>{Esta es la funcion CallBack a la cual llamará el hook.} <br>{This is the CallBack function called by he hook} <br>begin <br>{Si hay un nuevo evento de raton...} <br>{if there is a new mouse event...} <br>if code=HC_ACTION then <br>begin <br> &nbsp;{Miramos si existe el fichero} <br> &nbsp;{if the mapfile exists} <br> &nbsp;FicheroM:=OpenFileMapping(FILE_MAP_WRITE,False,'ElReceptor'); <br> &nbsp;{Si no existe, no enviamos nada a la aplicacion receptora} <br> &nbsp;{If dont, send nothing to receiver application} <br> &nbsp;if FicheroM&lt;&gt;0 then <br> &nbsp;begin <br> &nbsp; &nbsp;Compartido:=MapViewOfFile(FicheroM,FILE_MAP_WRITE,0,0,0); <br><br> &nbsp; &nbsp;{Apuntamos hacia los datos del evento del raton} <br> &nbsp; &nbsp;DatosMouse:=Pointer(lparam); <br><br> &nbsp; &nbsp;{Los guardamos en el fichero de memoria} <br> &nbsp; &nbsp;Compartido^.Ventana:=DatosMouse^.hwnd; <br> &nbsp; &nbsp;Compartido^.x:=DatosMouse^.pt.x; <br> &nbsp; &nbsp;Compartido^.y:=DatosMouse^.pt.y; <br><br> &nbsp; &nbsp;{Avisamos al receptor para que atienda el nuevo evento} <br> &nbsp; &nbsp;{Say to receiver that there is a new event} <br> &nbsp; &nbsp;PostMessage(Compartido^.Receptor,CM_MANDA_DATOS,wParam,lParam); <br><br> &nbsp; &nbsp;UnmapViewOfFile(Compartido); <br> &nbsp; &nbsp;CloseHandle(FicheroM); <br> &nbsp;end; <br>end; <br>{Llamamos al siguiente hook de la cadena} <br>{call to next hook of the chain} <br>Result := CallNexthookEx(hookDeMouse, Code, wParam, lParam) <br>end; <br><br>procedure hookOn; stdcall; <br>{Procedure que instala el hook} <br>{procedure for install the hook} <br>begin <br> &nbsp;hookDeMouse:=SetWindowshookEx(WH_MOUSE, @CallBackDelhook, HInstance , 0); <br>end; <br><br>// stops this type of watch <br>procedure hookOff; &nbsp;stdcall; <br>begin <br>{procedure para desinstalar el hook} <br>{procedure to uninstall the hook} <br> &nbsp;UnhookWindowshookEx(hookDeMouse); <br>end; <br><br>exports <br>{Exportamos las procedures...} <br>{Export the procedures} <br>hookOn, <br>hookOff; <br><br>begin <br>end. <br><br><br><br><br><br><br>Demo application <br><br><br><br><br><br><br>Put a TMemo (Memo1) in your form <br><br>Put two TLabels (Label1 and Label2) <br><br>Put this code in the form's unit <br><br><br><br><br>unit Unit1; <br><br>interface <br><br>uses <br> &nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, <br> &nbsp;StdCtrls, ExtCtrls; <br><br>const <br> &nbsp;NombreDLL &nbsp; &nbsp; &nbsp; = 'hookMouse.dll'; <br> &nbsp;CM_MANDA_DATOS &nbsp;= WM_USER + $1000; <br><br><br>type <br>TCompartido = record <br> &nbsp; Receptor, <br> &nbsp; wHitTestCode, <br> &nbsp; x,y, <br> &nbsp; Ventana &nbsp; &nbsp; &nbsp; &nbsp; : hwnd; <br>end; <br>PCompartido &nbsp; =^TCompartido; <br>ThookMouse=procedure; stdcall; <br><br>type <br> &nbsp;TForm1 = class(TForm) <br> &nbsp; &nbsp;Memo1: TMemo; <br> &nbsp; &nbsp;Panel1: TPanel; <br> &nbsp; &nbsp;Label1: TLabel; <br> &nbsp; &nbsp;Label2: TLabel; <br> &nbsp; &nbsp;procedure FormCreate(Sender: TObject); <br> &nbsp; &nbsp;procedure FormDestroy(Sender: TObject); <br> &nbsp;private <br> &nbsp; &nbsp;{ Private declarations } <br> &nbsp; &nbsp;FicheroM &nbsp; &nbsp; &nbsp; : THandle; <br> &nbsp; &nbsp;Compartido &nbsp; &nbsp; : PCompartido; <br> &nbsp; &nbsp;HandleDLL &nbsp; &nbsp; &nbsp;: THandle; <br> &nbsp; &nbsp;hookOn, <br> &nbsp; &nbsp;hookOff &nbsp; &nbsp; &nbsp; &nbsp;: ThookMouse; <br><br><br> &nbsp; &nbsp;procedure LlegaDelhook(var message: TMessage); message &nbsp;CM_MANDA_DATOS; <br> &nbsp;public <br> &nbsp; &nbsp;{ Public declarations } <br> &nbsp;end; <br><br>var <br> &nbsp;Form1: TForm1; <br><br>implementation <br><br>{$R *.DFM} <br><br>procedure TForm1.FormCreate(Sender: TObject); <br>begin <br> &nbsp;HandleDLL:=LoadLibrary( PChar(ExtractFilePath(Application.Exename)+ <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NombreDLL ) ); <br> &nbsp;if HandleDLL = 0 then raise Exception.Create('No se pudo cargar la DLL'); <br><br> &nbsp;@hookOn :=GetProcAddress(HandleDLL, 'hookOn'); <br> &nbsp;@hookOff:=GetProcAddress(HandleDLL, 'hookOff'); <br><br> &nbsp;if not assigned(hookOn) or <br> &nbsp; &nbsp; not assigned(hookOff) &nbsp;then <br> &nbsp; &nbsp; raise Exception.Create('No se encontraron las funciones en la DLL'+#13+ <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Cannot find the required DLL functions'); <br><br> &nbsp;{Creamos el fichero de memoria} <br> &nbsp;FicheroM:=CreateFileMapping( $FFFFFFFF, <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nil, <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PAGE_READWRITE, <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0, <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SizeOf(Compartido), <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'ElReceptor'); <br><br> &nbsp; {Si no se creó el fichero, error} <br> &nbsp; if FicheroM=0 then <br> &nbsp; &nbsp; raise Exception.Create( 'Error al crear el fichero'+ <br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '/Error while create file'); <br><br> &nbsp; {Direccionamos nuestra estructura al fichero de memoria} <br> &nbsp; Compartido:=MapViewOfFile(FicheroM,FILE_MAP_WRITE,0,0,0); <br><br> &nbsp; {Escribimos datos en el fichero de memoria} <br> &nbsp; Compartido^.Receptor:=Handle; <br> &nbsp; hookOn; <br>end; <br><br>procedure TForm1.LlegaDelhook(var message: TMessage); <br>var <br> &nbsp;DatosMouse &nbsp; &nbsp; : PMousehookStruct; <br> &nbsp;NombreVentana &nbsp;: array [0..200] of char; <br> &nbsp;Accion &nbsp; &nbsp; &nbsp; &nbsp; : string; <br>begin <br> &nbsp;with Compartido^ do <br> &nbsp;begin <br> &nbsp; &nbsp;{Coordenadas del raton} <br> &nbsp; &nbsp;{Mouse coordinates} <br> &nbsp; &nbsp;Label1.caption:='['+IntToStr(x)+':'+IntToStr(y)+']'; <br> &nbsp;end; <br> &nbsp;{Nombre de la ventana donde esta el raton} <br> &nbsp;{Window Name} <br> &nbsp;GetWindowText(Compartido^.Ventana,@NombreVentana,200); <br> &nbsp;Label2.Caption:=NombreVentana; <br><br> &nbsp;case Message.wParam of <br> &nbsp; &nbsp;WM_LBUTTONDBLCLK &nbsp; &nbsp; : Accion:='WM_LBUTTONDBLCLK &nbsp;'; <br> &nbsp; &nbsp;WM_LBUTTONDOWN &nbsp;: Accion:='WM_LBUTTONDOWN &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_LBUTTONUP &nbsp; &nbsp; &nbsp; &nbsp; : Accion:='WM_LBUTTONUP &nbsp; &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_MBUTTONDBLCLK &nbsp; &nbsp; : Accion:='WM_MBUTTONDBLCLK &nbsp;'; <br> &nbsp; &nbsp;WM_MBUTTONDOWN &nbsp; &nbsp; &nbsp; : Accion:='WM_MBUTTONDOWN &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_MBUTTONUP &nbsp; &nbsp; &nbsp; &nbsp; : Accion:='WM_MBUTTONUP &nbsp; &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_MOUSEMOVE &nbsp; &nbsp; &nbsp; &nbsp; : Accion:='WM_MOUSEMOVE &nbsp; &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_NCHITTEST &nbsp; &nbsp; &nbsp; &nbsp; : Accion:='WM_NCHITTEST &nbsp; &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_NCLBUTTONDBLCLK &nbsp; : Accion:='WM_NCLBUTTONDBLCLK'; <br> &nbsp; &nbsp;WM_NCLBUTTONDOWN &nbsp; &nbsp; : Accion:='WM_NCLBUTTONDOWN &nbsp;'; <br> &nbsp; &nbsp;WM_NCLBUTTONUP &nbsp; &nbsp; &nbsp; : Accion:='WM_NCLBUTTONUP &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_NCMBUTTONDBLCLK &nbsp; : Accion:='WM_NCMBUTTONDBLCLK'; <br> &nbsp; &nbsp;WM_NCMBUTTONDOWN &nbsp; &nbsp; : Accion:='WM_NCMBUTTONDOWN &nbsp;'; <br> &nbsp; &nbsp;WM_NCMBUTTONUP &nbsp; &nbsp; &nbsp; : Accion:='WM_NCMBUTTONUP &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_NCMOUSEMOVE &nbsp; &nbsp; &nbsp; : Accion:='WM_NCMOUSEMOVE &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_NCRBUTTONDBLCLK &nbsp; : Accion:='WM_NCRBUTTONDBLCLK'; <br> &nbsp; &nbsp;WM_NCRBUTTONDOWN &nbsp; &nbsp; : Accion:='WM_NCRBUTTONDOWN &nbsp;'; <br> &nbsp; &nbsp;WM_NCRBUTTONUP &nbsp; &nbsp; &nbsp; : Accion:='WM_NCRBUTTONUP &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_RBUTTONDBLCLK &nbsp; &nbsp; : Accion:='WM_RBUTTONDBLCLK &nbsp;'; <br> &nbsp; &nbsp;WM_RBUTTONDOWN &nbsp; &nbsp; &nbsp; : Accion:='WM_RBUTTONDOWN &nbsp; &nbsp;'; <br> &nbsp; &nbsp;WM_RBUTTONUP &nbsp; &nbsp; &nbsp; &nbsp; : Accion:='WM_RBUTTONUP &nbsp; &nbsp; &nbsp;'; <br> &nbsp;end; <br> &nbsp;Memo1.Lines.Append(Accion); <br><br>end; <br><br>procedure TForm1.FormDestroy(Sender: TObject); <br>begin <br>{Desactivamos el hook} <br>{Uninstall the hook} <br>if Assigned(hookOff) then hookOff; <br><br>{Liberamos la DLL} <br>{Free the DLL} <br>if HandleDLL&lt;&gt;0 then <br> &nbsp;FreeLibrary(HandleDLL); <br><br>{Cerramos la vista del fichero y el fichero} <br>{Close the memfile and the View} <br>if FicheroM&lt;&gt;0 then <br>begin <br> &nbsp; UnmapViewOfFile(Compartido); <br> &nbsp; CloseHandle(FicheroM); <br>end; <br>end; <br><br><br>end. <br><br><br>Make and compile the DLL, and then make and compile the application demo. <br>Try to put everything in the same directory, so that the <br>application demo finds the DLL. <br>If everything goes well, Label1 will show the coordinates of the mouse in real time, and in the Memo1 they will go the types of messages <br>that the hook goes capturing appearing. <br><br>IMPORTANT: Dont forget to set the event handlers (if you copy & paste the source code)
 
//使用鼠标钩子<br>//Hookdll.dpr(钩子DLL的工程文件)<br>//========================================================================<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ This is the core of the system and task hook. &nbsp;Some notes: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp;1) &nbsp;You will definitely want to give the file a more descriptive name &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;to avoid possible collisions with other DLL names. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp;2) &nbsp;Edit the MouseHookCallBack function to do what you need when a &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;mouse message is received. &nbsp;If you are hooking something other &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;mouse messages, see the SetWindowsHookEx topic in the help for the }<br>{ &nbsp; &nbsp; &nbsp;proper WH_xxxx constant, and any notes about the particular type &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;of hook. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp;3) &nbsp;If an application that uses the DLL crashes while the hook is &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;installed, all manner of wierd things can happen, depending on the }<br>{ &nbsp; &nbsp; &nbsp;sort of thing you are doing in the callback. &nbsp;The best suggestion &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;is to use a utility that displays loaded DLLs and forcibly unload &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;the DLL. &nbsp;You could also write a simple app that checks to see if &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;the DLL is loaded, and if so, call FreeModule until it returns 0. &nbsp;}<br>{ &nbsp;4) &nbsp;If you make changes to the DLL but the changes don't seem to be &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;working, you may have the DLL already loaded in memory. &nbsp;Remember, }<br>{ &nbsp; &nbsp; &nbsp;loading a DLL that is already in memory just increments a usage &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;count in Windows and uses the already loaded copy. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp;5) &nbsp;Remember when you are hooking in at the *system* level, your &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;callback function is being called for everything in the OS. &nbsp;Try &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;to keep the processing in the callback as tight and fast as you &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;possibly can. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp;6) &nbsp;Be careful of the uses clause. &nbsp;If you include stuff like Dialogs, }<br>{ &nbsp; &nbsp; &nbsp;you will end up linking in a lot of the VCL, and have a DLL that &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;comes out compiled to around 250k. &nbsp;You would probably be better &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;served using WM_USER messages to communicate with the application. }<br>{ &nbsp;7) &nbsp;I have successfully hooked mouse messages without the use of a &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;DLL, but many of the hooks say they require the callback to be in &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;a DLL, so I am hesitant to include this method. &nbsp;It certainly &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;makes the build/test cycle *much* easier, but since it is not &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;&quot;sanctioned&quot; by MS, I would stay away from it and discourage it. &nbsp; }<br>{ &nbsp;8) &nbsp;Remember that 32-bit processes can only load 32-bit DLLs, and &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;16-bit processes can only load 16-bit DLLs. &nbsp;That means that if &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;you set a system hook and your DLL is compiled under Delphi 1, &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;only 16-bit processes are going to fire the system hook. &nbsp;So, if &nbsp; }<br>{ &nbsp; &nbsp; &nbsp;it were running on a Windows 98 machine, not much of anything &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp;is going to fire your &quot;system&quot; hook. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br><br>library HookDLL;<br><br>uses WinTypes, WinProcs, Messages;<br><br><br>{ Global variables }<br>{$IFDEF WIN32}<br><br>{ For a system-wide hook, global variables must be Memory Mapped to be<br> &nbsp;accessible by all processes because the data segment of 32-bit DLL is private<br> &nbsp;to each process using it. }<br>type<br> &nbsp;PSharedData = ^TSharedData;<br> &nbsp;TSharedData = record<br> &nbsp; &nbsp;{ In this record, mirror the global variables of the 16-bit version }<br> &nbsp; &nbsp;HookCount: integer;<br> &nbsp; &nbsp;HookHandle: HHook;<br> &nbsp; &nbsp;MonitorWnd: HWND;<br> &nbsp; &nbsp;WM_MONITORMOUSEMOVE: UINT;<br> &nbsp;end;<br><br>var<br> &nbsp;{ global data for the DLL for a single process }<br> &nbsp;hMapObject: THandle;<br> &nbsp;SharedData: PSharedData;<br><br>{$ELSE}<br><br>{ 16 bit Windows }<br>type<br> &nbsp;UINT = Longint;<br><br>var<br> &nbsp;HookCount: integer;<br> &nbsp;HookHandle: HHook;<br> &nbsp;MonitorWnd: HWND;<br> &nbsp;WM_MONITORMOUSEMOVE: UINT;<br>{$ENDIF}<br><br>const<br> &nbsp;MESSAGE_MONITOR_MOUSE_MOVE = 'DFSHookDLLMonitorMouseMoveMessage';<br><br><br>function GetMonitorMouseMoveMsg: UINT; export;<br>begin<br> &nbsp;{$IFDEF WIN32}<br> &nbsp;if SharedData = NIL then<br> &nbsp; &nbsp;Result := 0<br> &nbsp;else<br> &nbsp; &nbsp;Result := SharedData^.WM_MONITORMOUSEMOVE;<br> &nbsp;{$ELSE}<br> &nbsp;Result := WM_MONITORMOUSEMOVE;<br> &nbsp;{$ENDIF}<br>end;<br><br>{ This is where you do your special processing. }<br>{$IFDEF WIN32}<br>function MouseHookCallBack(Code: integer; Msg: WPARAM; MouseHook: LPARAM): LRESULT; stdcall;<br>{$ELSE}<br>function MouseHookCallBack(Code: integer; Msg: word; MouseHook: longint): longint; export;<br>{$ENDIF}<br>var<br> &nbsp;{$IFDEF WIN32}<br> &nbsp;HookHandle: HHOOK;<br> &nbsp;MonitorWnd: HWND;<br> &nbsp;WM_MONITORMOUSEMOVE: UINT;<br> &nbsp;{$ENDIF}<br> &nbsp;MouseHookStruct: PMouseHookStruct absolute MouseHook;<br>begin<br> &nbsp;{$IFDEF WIN32}<br> &nbsp;{ Access the shared data. Do check if SharedData is assigned, because under<br> &nbsp; &nbsp;some circumstances the hook filter can be called after all processes have<br> &nbsp; &nbsp;detached }<br> &nbsp;if SharedData &lt;&gt; NIL then<br> &nbsp;begin<br> &nbsp; &nbsp;MonitorWnd := SharedData^.MonitorWnd;<br> &nbsp; &nbsp;HookHandle := SharedData^.HookHandle;<br> &nbsp; &nbsp;WM_MONITORMOUSEMOVE := SharedData^.WM_MONITORMOUSEMOVE;<br> &nbsp;end<br> &nbsp;else<br> &nbsp;begin<br> &nbsp; &nbsp;WM_MONITORMOUSEMOVE := 0;<br> &nbsp; &nbsp;MonitorWnd := 0;<br> &nbsp; &nbsp;HookHandle := 0; { It seems that this handle is not used in the CallNextHookEx<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; function anyway. Several sources on the microsoft web site<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indicate this. }<br> &nbsp;end;<br> &nbsp;{$ENDIF}<br><br> &nbsp;{ If the value of Code is less than 0, we are not allowed to do anything }<br> &nbsp;{ except pass it on to the next hook procedure immediately. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br> &nbsp;if (Code &gt;= 0) and (MonitorWnd &lt;&gt; 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;{ This example sends the coordinates of all mouse move messages to the<br> &nbsp; &nbsp; &nbsp;monitoring app (the one that installed the hook). }<br> &nbsp; &nbsp;if (Msg = WM_MOUSEMOVE) and (MouseHookStruct &lt;&gt; NIL) then<br> &nbsp; &nbsp; &nbsp;PostMessage(MonitorWnd, WM_MONITORMOUSEMOVE, MouseHookStruct^.pt.x,<br> &nbsp; &nbsp; &nbsp; &nbsp;MouseHookStruct^.pt.y);<br><br> &nbsp; &nbsp;{ You could do any number of things here based on the different mouse<br> &nbsp; &nbsp; &nbsp;messages...<br> &nbsp; &nbsp;case Msg of:<br> &nbsp; &nbsp; &nbsp;WM_LBUTTONDOWN:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;WM_LBUTTONUP:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;WM_LBUTTONDBLCLK:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;WM_RBUTTONDOWN:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;WM_RBUTTONUP:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;WM_RBUTTONDBLCLK:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;WM_MBUTTONDOWN:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;WM_MBUTTONUP:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;WM_MBUTTONDBLCLK:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;WM_MOUSEMOVE:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;}<br><br> &nbsp; &nbsp;{ If you handled the situation, and don't want Windows to process the }<br> &nbsp; &nbsp;{ message, do *NOT* execute the next line. &nbsp;Be very sure this is what }<br> &nbsp; &nbsp;{ want, though. &nbsp;If you don't pass on stuff like WM_MOUSEMOVE, you &nbsp; &nbsp;}<br> &nbsp; &nbsp;{ will NOT like the results you get. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br> &nbsp; &nbsp;Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);<br> &nbsp;end<br> &nbsp;else<br> &nbsp; &nbsp;Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);<br>end;<br><br>{ Call InstallHook to set the hook. }<br>function InstallHook(SystemHook: boolean; TaskHandle: THandle;<br> &nbsp;AMonitorWnd: HWND) : boolean; export;<br> &nbsp;{ This is really silly, but that's the way it goes. &nbsp;The only way to get the &nbsp;}<br> &nbsp;{ module handle, *not* instance, is from the filename. &nbsp;The Microsoft example }<br> &nbsp;{ just hard-codes the DLL filename. &nbsp;I think this is a little bit better. &nbsp; &nbsp; }<br> &nbsp;function GetModuleHandleFromInstance: THandle;<br> &nbsp;var<br> &nbsp; &nbsp;s: array[0..512] of char;<br> &nbsp;begin<br> &nbsp; &nbsp;{ Find the DLL filename from the instance value. }<br> &nbsp; &nbsp;GetModuleFileName(hInstance, s, sizeof(s)-1);<br> &nbsp; &nbsp;{ Find the handle from the filename. }<br> &nbsp; &nbsp;Result := GetModuleHandle(s);<br> &nbsp;end;<br>begin<br> &nbsp;{ Technically, this procedure could do nothing but call SetWindowsHookEx(), &nbsp;}<br> &nbsp;{ but it is probably better to be sure about things, and not set the hook &nbsp; &nbsp;}<br> &nbsp;{ more than once. &nbsp;You definitely don't want your callback being called more }<br> &nbsp;{ than once per message, do you? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br> &nbsp;{$IFDEF WIN32}<br> &nbsp;Result := FALSE;<br> &nbsp;if SharedData = NIL then<br> &nbsp; &nbsp;exit<br> &nbsp;else<br> &nbsp; &nbsp;with SharedData^ do<br> &nbsp; &nbsp;begin<br> &nbsp;{$ENDIF}<br> &nbsp; &nbsp; &nbsp;Result := TRUE;<br> &nbsp; &nbsp; &nbsp;if HookCount = 0 then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;MonitorWnd := AMonitorWnd;<br> &nbsp; &nbsp; &nbsp; &nbsp;if SystemHook then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HookHandle := SetWindowsHookEx(WH_MOUSE, MouseHookCallBack, HInstance, 0)<br> &nbsp; &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ See the Microsoft KnowledgeBase, PSS ID Number: Q92659, for a<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;discussion of the Windows bug that requires GetModuleHandle() to be<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;used. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HookHandle := SetWindowsHookEx(WH_MOUSE, MouseHookCallBack,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetModuleHandleFromInstance, TaskHandle);<br> &nbsp; &nbsp; &nbsp; &nbsp;if HookHandle &lt;&gt; 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;inc(HookCount)<br> &nbsp; &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result := FALSE;<br> &nbsp; &nbsp; &nbsp;end<br> &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp;inc(HookCount);<br> &nbsp;{$IFDEF WIN32}<br> &nbsp; &nbsp;end;<br> &nbsp;{$ENDIF}<br>end;<br><br>{ Call RemoveHook to remove the system hook. }<br>function RemoveHook: boolean; export;<br>begin<br> &nbsp;{ See if our reference count is down to 0, and if so then unhook. }<br> &nbsp;Result := FALSE;<br> &nbsp;{$IFDEF WIN32}<br> &nbsp;if SharedData = NIL then<br> &nbsp; &nbsp;exit<br> &nbsp;else<br> &nbsp; &nbsp;with SharedData^ do<br> &nbsp; &nbsp;begin<br> &nbsp;{$ENDIF}<br> &nbsp; &nbsp; &nbsp;if HookCount &lt; 1 then exit;<br> &nbsp; &nbsp; &nbsp;Result := TRUE;<br> &nbsp; &nbsp; &nbsp;dec(HookCount);<br> &nbsp; &nbsp; &nbsp;if HookCount = 0 then<br> &nbsp; &nbsp; &nbsp; &nbsp;Result := UnhookWindowsHookEx(HookHandle);<br> &nbsp;{$IFDEF WIN32}<br> &nbsp; &nbsp;end;<br> &nbsp;{$ENDIF}<br>end;<br><br>{ Have we hooked into the system? }<br>function IsHookSet: boolean; export;<br>begin<br> &nbsp;{$IFDEF WIN32}<br> &nbsp;if SharedData = NIL then<br> &nbsp; &nbsp;Result := FALSE<br> &nbsp;else<br> &nbsp; &nbsp;with SharedData^ do<br> &nbsp;{$ENDIF}<br> &nbsp; &nbsp; &nbsp;Result := (HookCount &gt; 0) and (HookHandle &lt;&gt; 0);<br>end;<br><br>{$IFDEF WIN32}<br>{ Shared data management }<br>procedure AllocSharedData;<br>var<br> &nbsp;Init: boolean;<br>begin<br> &nbsp;if hMapObject = 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;// Create a named file mapping object.<br> &nbsp; &nbsp;hMapObject := CreateFileMapping(<br> &nbsp; &nbsp; &nbsp;THandle($FFFFFFFF), &nbsp;// use paging file<br> &nbsp; &nbsp; &nbsp;NIL, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // no security attributes<br> &nbsp; &nbsp; &nbsp;PAGE_READWRITE, &nbsp; &nbsp; &nbsp;// read/write access<br> &nbsp; &nbsp; &nbsp;0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // size: high 32-bits<br> &nbsp; &nbsp; &nbsp;SizeOf(TSharedData), // size: low 32-bits<br> &nbsp; &nbsp; &nbsp;'DFSHookDLLSharedDataBlock'); // name of map object, THIS MUST BE UNIQUE!<br> &nbsp; &nbsp;// The first process to attach initializes memory.<br> &nbsp; &nbsp;Init := GetLastError &lt;&gt; ERROR_ALREADY_EXISTS;<br> &nbsp; &nbsp;if hMapObject = 0 then exit;<br> &nbsp; &nbsp;// Get a pointer to the file-mapped shared memory.<br> &nbsp; &nbsp;SharedData := MapViewOfFile(<br> &nbsp; &nbsp; &nbsp;hMapObject, &nbsp; &nbsp; // object to map view of<br> &nbsp; &nbsp; &nbsp;FILE_MAP_WRITE, // read/write access<br> &nbsp; &nbsp; &nbsp;0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// high offset: &nbsp;map from<br> &nbsp; &nbsp; &nbsp;0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// low offset: &nbsp; beginning<br> &nbsp; &nbsp; &nbsp;0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // default: map entire file<br> &nbsp; &nbsp;if SharedData = NIL then exit;<br> &nbsp; &nbsp;// Initialize memory if this is the first process.<br> &nbsp; &nbsp;if Init then<br> &nbsp; &nbsp; &nbsp;FillChar(SharedData^, SizeOf(TSharedData), 0);<br> &nbsp; &nbsp;SharedData^.WM_MONITORMOUSEMOVE := RegisterWindowMessage(<br> &nbsp; &nbsp; &nbsp;MESSAGE_MONITOR_MOUSE_MOVE);<br> &nbsp;end;<br>end;<br><br>procedure FreeSharedData;<br>begin<br> &nbsp;if hMapObject &lt;&gt; 0 then<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;UnMapViewOfFile(SharedData);<br> &nbsp; &nbsp; &nbsp; &nbsp;CloseHandle(hMapObject);<br> &nbsp; &nbsp; &nbsp;except<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp;SharedData := NIL;<br> &nbsp; &nbsp; &nbsp;hMapObject := 0;<br> &nbsp; &nbsp;end;<br>end;<br><br>procedure EntryPointProc(Reason: Integer);<br>begin<br> &nbsp;case Reason of<br> &nbsp; &nbsp;DLL_PROCESS_DETACH: FreeSharedData;<br> &nbsp; &nbsp;DLL_PROCESS_ATTACH: AllocSharedData;<br> &nbsp; &nbsp;DLL_THREAD_ATTACH: {} ;<br> &nbsp; &nbsp;DLL_THREAD_DETACH: {} ;<br> &nbsp;end;<br>end;<br>{$ENDIF}<br><br><br>exports<br> &nbsp;GetMonitorMouseMoveMsg,<br> &nbsp;InstallHook,<br> &nbsp;RemoveHook,<br> &nbsp;IsHookSet,<br> &nbsp;MouseHookCallBack;<br><br><br>{ Initialize DLL data. }<br>begin<br> &nbsp;{$IFDEF WIN32}<br> &nbsp;SharedData := NIL;<br> &nbsp;hMapObject := 0;<br> &nbsp;DllProc := @EntryPointProc;<br> &nbsp;EntryPointProc(DLL_PROCESS_ATTACH); // Must call manually in the Delphi world<br> &nbsp;{$ELSE}<br> &nbsp;HookCount := 0;<br> &nbsp;HookHandle := 0;<br> &nbsp;WM_MONITORMOUSEMOVE := RegisterWindowMessage(MESSAGE_MONITOR_MOUSE_MOVE);<br> &nbsp;{$ENDIF}<br>end.<br><br>//========================================================================<br><br>//Hookunit.pas(钩子DLL的单元文件)<br>//========================================================================<br>{ This is a simple DLL import unit to give us access to the functions in }<br>{ the HOOKDLL.PAS file. &nbsp;This is the unit your project will use. &nbsp; &nbsp; &nbsp; &nbsp; }<br>unit Hookunit;<br><br>interface<br><br>uses WinTypes;<br><br>{$IFNDEF WIN32}<br>type<br> &nbsp;UINT = Longint;<br>{$ENDIF}<br><br>function GetMonitorMouseMoveMsg: UINT;<br>function InstallSystemHook(AMonitorWnd: HWND): boolean;<br>function InstallTaskHook(AMonitorWnd: HWND): boolean;<br>function RemoveHook: boolean;<br>function IsHookSet: boolean;<br>{ Do not use InstallHook directly. &nbsp;Use InstallSystemHook or InstallTaskHook. }<br>function InstallHook(SystemHook: boolean; TaskHandle: THandle;<br> &nbsp;AMonitorWnd: HWND): boolean;<br><br>implementation<br><br>uses WinProcs;<br><br>const<br> &nbsp;{$IFDEF WIN32}<br> &nbsp;HOOK_DLL = 'HOOKDLL.DLL';<br> &nbsp;{$ELSE}<br> &nbsp;HOOK_DLL = 'HOOKDLL';<br> &nbsp;{$ENDIF}<br><br>function GetMonitorMouseMoveMsg: UINT; external HOOK_DLL;<br>function InstallHook(SystemHook: boolean; TaskHandle: THandle;<br> &nbsp;AMonitorWnd: HWND): boolean; external HOOK_DLL;<br>function RemoveHook: boolean; external HOOK_DLL;<br>function IsHookSet: boolean; external HOOK_DLL;<br><br>function InstallSystemHook(AMonitorWnd: HWND): boolean;<br>begin<br> &nbsp;Result := InstallHook(TRUE, 0, AMonitorWnd);<br>end;<br><br>function InstallTaskHook(AMonitorWnd: HWND): boolean;<br>begin<br> &nbsp;Result := InstallHook(FALSE,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{$IFDEF WIN32}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetCurrentThreadID,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{$ELSE}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetCurrentTask,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{$ENDIF}<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AMonitorWnd<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );<br>end;<br><br>end.<br><br>//========================================================================<br><br>//调用钩子的主程序代码<br>//========================================================================<br>unit Main;<br><br>interface<br><br>uses<br> &nbsp;SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,<br> &nbsp;Forms, Dialogs, StdCtrls, HookUnit;<br><br>type<br> &nbsp;THookForm = class(TForm)<br> &nbsp; &nbsp;SysHookBtn: TButton;<br> &nbsp; &nbsp;RemoveHookBtn: TButton;<br> &nbsp; &nbsp;TaskHookBtn: TButton;<br> &nbsp; &nbsp;lblMousePos: TLabel;<br> &nbsp; &nbsp;procedure FormCreate(Sender: TObject);<br> &nbsp; &nbsp;procedure SysHookBtnClick(Sender: TObject);<br> &nbsp; &nbsp;procedure RemoveHookBtnClick(Sender: TObject);<br> &nbsp; &nbsp;procedure TaskHookBtnClick(Sender: TObject);<br> &nbsp; &nbsp;procedure FormDestroy(Sender: TObject);<br> &nbsp;protected<br> &nbsp; &nbsp;procedure WndProc(var Message: TMessage); override;<br> &nbsp; &nbsp;procedure UpdateButtons;<br> &nbsp; &nbsp;procedure UpdateMousePosInfo(X, Y: integer);<br> &nbsp;end;<br><br>var<br> &nbsp;HookForm: THookForm;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure THookForm.FormCreate(Sender: TObject);<br>begin<br> &nbsp;UpdateButtons;<br>end;<br><br>procedure THookForm.FormDestroy(Sender: TObject);<br>begin<br> &nbsp;while IsHookSet do<br> &nbsp; &nbsp;RemoveHook; { Make sure we unhook ourselves. }<br>end;<br><br>procedure THookForm.SysHookBtnClick(Sender: TObject);<br>begin<br> &nbsp;if not InstallSystemHook(Handle) then<br> &nbsp; &nbsp;ShowMessage('Could not install mouse hook. &nbsp;SetWindowsHookEx() failed.');<br> &nbsp;UpdateButtons;<br>end;<br><br>procedure THookForm.TaskHookBtnClick(Sender: TObject);<br>begin<br> &nbsp;if not InstallTaskHook(Handle) then<br> &nbsp; &nbsp;ShowMessage('Could not install task hook. &nbsp;SetWindowsHookEx() failed.');<br> &nbsp;UpdateButtons;<br>end;<br><br>procedure THookForm.RemoveHookBtnClick(Sender: TObject);<br>begin<br> &nbsp;if IsHookSet then<br> &nbsp; &nbsp;RemoveHook;<br> &nbsp;UpdateButtons;<br>end;<br><br>procedure THookForm.UpdateButtons;<br>begin<br> &nbsp;SysHookBtn.Enabled := not IsHookSet;<br> &nbsp;TaskHookBtn.Enabled := not IsHookSet;<br> &nbsp;RemoveHookBtn.Enabled := IsHookSet;<br> &nbsp;if not IsHookSet then<br> &nbsp; &nbsp;lblMousePos.Caption := 'Hook not set';<br>end;<br><br>procedure THookForm.WndProc(var Message: TMessage);<br>begin<br> &nbsp;if Message.Msg = GetMonitorMouseMoveMsg then<br> &nbsp; &nbsp;UpdateMousePosInfo(Message.WParam, Message.LParam)<br> &nbsp;else<br> &nbsp; &nbsp;inherited WndProc(Message);<br>end;<br><br>procedure THookForm.UpdateMousePosInfo(X, Y: integer);<br>begin<br> &nbsp;lblMousePos.Caption := Format('X = %d, Y = %d', [X, Y]);<br>end;<br><br>end.<br><br>//========================================================================<br> &nbsp;<br><br><br>来自:stuwei, 时间:2003-4-3 22:29:00, ID:1736906<br>截取消息wm_mousemove<br> &nbsp;<br><br><br>来自:明月春秋, 时间:2003-4-4 17:03:00, ID:1738351<br>当我打开子窗体时,鼠标在子窗体上移动,些时,鼠标钩子,还能截取到消息吗,<br>而且,我要的鼠标的位置 ,是相对于主窗体 <br> &nbsp;<br><br><br>来自:小笨苯, 时间:2003-4-4 18:00:00, ID:1738621<br>上面的代码是全局钩子,不管当前是那个窗体处于激活状态,也不管是不是你的程序的窗体处于激活状态,<br>都能取到鼠标的位置。<br>&gt;&gt;我要的鼠标的位置 ,是相对于主窗体 <br>这个可以自己转换一下嘛。ClientToScreen , ScreenToClient
 
to cqwty,<br>朋友 可以加QQ谈吗?
 
十一第一件事就是交了一个朋友,不错,分地送上
 
后退
顶部