unit untMouseHook;interface uses Windows, Messages, Dialogs, SysUtils, untMouseHookConst; var hMappingFile :THandle; //Handle for Mapping file pSharedMem :^TSharedMem; //Pointer for Shared Memory HookHandle :HHook; //Handle for the hookfunction StartHook(Sender:HWnd; MessageID:word):BOOL; stdcall; function StopHook:BOOL; stdcall; implementationfunction MouseProc(nCode:integer; wParam:WParam; lParam:LParam): LRESULT; stdcall; begin Result := 0; if nCode<0 then Result:=CallNextHookEx(HookHandle,nCode,wParam,lParam); //Rule of API call, which referred to Win32 Hooks topic in MSDNif ( (wParam = WM_LBUTTONUP ) or ( wParam = WM_NCLBUTTONUP) ) then SendMessage(pSharedMem^.InstHandle,pSharedMem^.MessageID,0,0); //Sends Message to Instance to which was injected this DLL end;function StartHook(Sender:HWnd; MessageID:word):BOOL; begin Result := False; if HookHandle<>0 then Exit; //Already Installed the hook pSharedMem^.InstHandle := Sender; pSharedMem^.MessageID := MessageID; HookHandle := SetWindowsHookEx(WH_MOUSE,MouseProc,hInstance,0); Result := HookHandle <> 0; end;function StopHook:BOOL; begin if HookHandle <> 0 then begin UnhookWindowsHookEx(HookHandle); HookHandle := 0; end; Result := HookHandle = 0; end; initializationhMappingFile := OpenFileMapping(FILE_MAP_WRITE,False,MappingFileName); //Try to open an existing mapping file as MappingFileName specified if hMappingFile = 0 then //Not exist hMappingFile := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,sizeof(TSharedMem),MappingFileName); //Here $FFFFFFFF is a invalid file handle, which cause this file being created in Windows page file.if hMappingFile = 0 then //Still unable to create a mapping file Exception.Create('Unable to create shared memory. Make sure your system have enough memory and page file space.');pSharedMem := MapViewOfFile(hMappingFile,FILE_MAP_WRITE or FILE_MAP_READ,0,0,0); //Details of this API call, refer to MapViewOfFile in MSDN if pSharedMem = nil then //Create a pointer to the mapped file begin CloseHandle(hMappingFile); Exception.Create('Unable to map shared memory. Program halt.'); end;HookHandle := 0; //Whether HookHandle = 0 is used to judge if this hooked was installed //In function StartHook, we will later give a value to HookHandle finalizationUnMapViewOfFile(pSharedMem); CloseHandle(hMappingFile); end.
公用模块源代码:untMouseHookConst.pas
unit untMouseHookConst;interface uses Windows; const MappingFileName='_TOEFLDllMouse'; type TSharedMem=record InstHandle :DWord; MessageID :DWord; end;implementation end.
EXE模块源代码:untMain.pas
unit untMain;interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, untMouseHookConst, StdCtrls, ExtCtrls;type TfrmMain = class(TForm) lblMain: TLabel; tmrMain: TTimer; procedure tmrMainTimer(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } procedure WndProc(var Messages:TMessage); override; end;const MessageID = WM_User+121; DLLFileName = 'dllTOEFLHook.dll';var frmMain :TfrmMain; hMappingFile :THandle; pSharedMem :^TSharedMem; time_counter :integer;implementation { $R *.dfm } function StartHook(Sender:HWnd; MessageID:word):BOOL; stdcall; external DLLFileName; function StopHook:BOOL; stdcall; external DLLFileName; procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction); begin if not StopHook then Exception.Create('Unable to uninstall the mouse hook. Abnormal termination.'); end;procedure TfrmMain.FormCreate(Sender: TObject); begin pSharedMem := nil; if not StartHook(frmMain.Handle,MessageID) then //Sends handle and MessageID to DLL Exception.Create('Unable to install a mouse hook. Program halt.'); time_counter := 0; end;procedure TfrmMain.tmrMainTimer(Sender: TObject); begin inc(time_counter); lblMain.Caption := IntToStr(time_counter); end;procedure TfrmMain.WndProc(var Messages: TMessage); //Override WndProc, see MSDN for details begin if pSharedMem = nil then begin hMappingFile := OpenFileMapping(FILE_MAP_WRITE,False,MappingFileName); if hMappingFile = 0 then Exception.Create('Unable to access shared memory. Program halt.'); pSharedMem := MapViewOfFile(hMappingFile,FILE_MAP_WRITE or FILE_MAP_READ,0,0,0); if pSharedMem = nil then begin CloseHandle(hMappingFile); Exception.Create('Unable to map to shared memory. Program halt.'); end; end; if pSharedMem = nil then exit; //Halt program if unable to create/open/map shared memory.if Messages.Msg = MessageID then //Global mouse On_Left_Button_Up begin time_counter := 0; lblMain.Caption := 'CLICK!'; tmrMain.Interval := 0; tmrMain.Interval := 1000; //Cause timer to restart timing end else Inherited; //Do traditional WndProc without override