library dllMouse; uses SysUtils, Classes, UnitHookDLL in 'UnitHookDLL.pas', UnitHookConst in 'UnitHookConst.pas'; {$R *.res} { function StartHook(sender : HWND;MessageID : WORD) : BOOL; stdcall; function StopHook: BOOL; stdcall; procedure GetRbutton; stdcall;} exports StartHook, StopHook,GetRbutton; begin end. { 截获鼠标消息例子. 截获所有进程的鼠标消息,需要用到系统钩子,即要用到dll才能够截取,因此挂 钩函数封装在dll动态链接库中.由于需要跨进程共享数据,所以在dll使用内存映像 文件来共享数据. } unit UnitHookDLL; // download by http://www.codefans.net interface uses Windows, Messages, Dialogs, SysUtils,UnitHookConst; var hMappingFile : THandle; pShMem : PShareMem; FirstProcess : boolean; NextHook: HHook; function StartHook(sender : HWND;MessageID : WORD) : BOOL; stdcall; function StopHook: BOOL; stdcall; procedure GetRbutton; stdcall; implementation procedure GetRbutton; stdcall; begin pShMem^.IfRbutton:=true; end; function HookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export; begin Result := 0; If iCode < 0 Then Result := CallNextHookEx(NextHook, iCode, wParam, lParam); case wparam of WM_LBUTTONDOWN: begin end; WM_LBUTTONUP: begin end; WM_LBUTTONDBLCLK: begin end; WM_RBUTTONDOWN: begin if pShMem^.IfRbutton then begin pShMem^.IfRbutton := false; pShMem^.data2:=pMOUSEHOOKSTRUCT(lparam)^; getwindowtext(pShMem^.data2.hwnd,pShMem^.buffer,1024); SendMessage(pShMem^.data1[1],pShMem^.data1[2]+1,wParam,integer(@(pShMem^.data2)) ); // 窗口 消息 坐标 end; end; WM_RBUTTONUP: begin end; WM_RBUTTONDBLCLK: begin end; WM_MBUTTONDOWN: begin end; WM_MBUTTONUP: begin end; WM_MBUTTONDBLCLK: begin end; WM_NCMouseMove, WM_MOUSEMOVE: begin pShMem^.data2:=pMOUSEHOOKSTRUCT(lparam)^; getwindowtext(pShMem^.data2.hwnd,pShMem^.buffer,1024); SendMessage(pShMem^.data1[1],pShMem^.data1[2],wParam,integer(@(pShMem^.data2)) ); // 窗口 消息 坐标 end; end; end; function StartHook(sender : HWND;MessageID : WORD) : BOOL; function GetModuleHandleFromInstance: THandle; var s: array[0..512] of char; begin GetModuleFileName(hInstance, s, sizeof(s)-1); Result := GetModuleHandle(s); end; begin Result := False; if NextHook <> 0 then Exit; pShMem^.data1[1]:=sender; pShMem^.data1[2]:=messageid; NextHook := SetWindowsHookEx(WH_mouse, HookHandler, HInstance, 0); //全局 //SetWindowsHookEx(WH_mouse, HookHandler, GetModuleHandleFromInstance, GetCurrentThreadID); //实例 Result := NextHook <> 0; end; function StopHook: BOOL; begin if NextHook <> 0 then begin UnhookWindowshookEx(NextHook); NextHook := 0; //SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,0); end; Result := NextHook = 0; end; initialization hMappingFile := OpenFileMapping(FILE_MAP_WRITE,False,MappingFileName); if hMappingFile=0 then begin hMappingFile := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TShareMem),MappingFileName); FirstProcess:=true; end else FirstProcess:=false; if hMappingFile=0 then Exception.Create('不能建立共享内存!'); pShMem := MapViewOfFile(hMappingFile,FILE_MAP_WRITE or FILE_MAP_READ,0,0,0); if pShMem = nil then begin CloseHandle(hMappingFile); Exception.Create('不能映射共享内存!'); end; if FirstProcess then begin pShmem^.IfRbutton := false; end; NextHook:=0; finalization UnMapViewOfFile(pShMem); CloseHandle(hMappingFile); end. unit Unitmain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,UnitHookConst; type TForm1 = class(TForm) edt1: TEdit; edt2: TEdit; capture: TButton; edt3: TEdit; btn2: TButton; lbl1: TLabel; edt4: TEdit; edt5: TEdit; edt6: TEdit; pnl1: TPanel; procedure captureClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure btn2Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public procedure WndProc(var Messages: TMessage); override; end; var Form1: TForm1; hMappingFile : THandle; pShMem : PShareMem; const MessageID = WM_User + 100; implementation {$R *.DFM} //dllMouse.dll DllMouse.DLL function StartHook(sender : HWND;MessageID : WORD) : BOOL;stdcall; external 'dllMouse.dll'; function StopHook: BOOL;stdcall; external 'dllMouse.dll'; procedure GetRbutton; stdcall; external 'dllMouse.dll'; procedure TForm1.captureClick(Sender: TObject); begin if capture.caption='开始' then begin if StartHook(Form1.Handle,MessageID) then capture.caption:='停止'; end else begin if StopHook then capture.caption:='开始'; end; end; procedure TForm1.btn2Click(Sender: TObject); begin if capture.caption<>'开始' then begin edt4.text:=''; edt5.text:=''; edt6.text:=''; GetRbutton; end; end; procedure TForm1.FormCreate(Sender: TObject); begin pShMem := nil; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if capture.caption='开始' then begin end else begin if StopHook then capture.caption:='开始'; end; end; procedure TForm1.WndProc(var Messages: TMessage); var x,y:integer; s:array[0..255]of char; begin if pShMem = nil then begin hMappingFile := OpenFileMapping(FILE_MAP_WRITE,False,MappingFileName); if hMappingFile=0 then Exception.Create('不能建立共享内存!'); pShMem := MapViewOfFile(hMappingFile,FILE_MAP_WRITE or FILE_MAP_READ,0,0,0); if pShMem = nil then begin CloseHandle(hMappingFile); Exception.Create('不能映射共享内存!'); end; end; if pShMem = nil then exit; if Messages.Msg = MessageID then begin x:=pShMem^.data2.pt.x; y:=pShMem^.data2.pt.y; edt3.text:='HWND:'+inttostr(pShMem^.data2.hwnd); pnl1.caption:='x='+inttostr(x)+' y='+inttostr(y); edt2.text:='WindowsText:'+string(pShMem^.buffer); getClassName(pShMem^.data2.hwnd,s,255); edt1.text:='ClassName:"'+string(s)+'"'; end else if Messages.Msg = MessageID+1 then begin edt4.text:=inttostr(pShMem^.data2.hwnd); edt5.text:='WindowsText:'+string(pShMem^.buffer); getClassName(pShMem^.data2.hwnd,s,255); edt6.text:='ClassName:"'+string(s)+'"'; end else Inherited; end; end.