unit UnitHookDLL;interfaceuses 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;implementationprocedure 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.
上面是DLL代码,下面是调用的主窗体unit Unitmain;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,UnitHookConst;type TForm1 = class(TForm) capture: TButton; Panel1: TPanel; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Label1: TLabel; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; Button1: TButton; procedure captureClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } procedure WndProc(var Messages: TMessage); override; end;var Form1: TForm1; hMappingFile : THandle; pShMem : PShareMem; const MessageID = WM_User + 100;implementation {$R *.DFM} 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.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; edit3.text:='HWND:'+inttostr(pShMem^.data2.hwnd); panel1.caption:='x='+inttostr(x)+' y='+inttostr(y); edit2.text:='WindowsText:'+string(pShMem^.buffer); getClassName(pShMem^.data2.hwnd,s,255); edit1.text:='ClassName:"'+string(s)+'"'; end else if Messages.Msg = MessageID+1 then begin edit4.text:=inttostr(pShMem^.data2.hwnd); edit5.text:='WindowsText:'+string(pShMem^.buffer); getClassName(pShMem^.data2.hwnd,s,255); edit6.text:='ClassName:"'+string(s)+'"'; end else Inherited; 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.Button1Click(Sender: TObject); begin if capture.caption<>'开始' then begin edit4.text:=''; edit5.text:=''; edit6.text:=''; GetRbutton; end; end;procedure TForm1.FormCreate(Sender: TObject); begin pShMem := nil; end;end.
如果只想获取当前活动窗口的句柄和标题, 那不用钩子也可以啊。得到当前活动窗体标题: function GetActiveWindowText: string; var hnd: HWND; stlen: Integer; begin hnd := GetForegroundWindow; stlen := GetWindowTextLength(hnd); SetLength(Result, stlen); GetWindowText(hnd, PChar(Result), stlen+1); end;这个函数返回值就是标题, hnd是窗体句柄。
var
hMappingFile : THandle;
pShMem : PShareMem;
FirstProcess : boolean;
NextHook: HHook; function StartHook(sender : HWND;MessageID : WORD) : BOOL; stdcall;
function StopHook: BOOL; stdcall;
procedure GetRbutton; stdcall;implementationprocedure 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.
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls,UnitHookConst;type
TForm1 = class(TForm)
capture: TButton;
Panel1: TPanel;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Label1: TLabel;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Button1: TButton;
procedure captureClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure WndProc(var Messages: TMessage); override;
end;var
Form1: TForm1;
hMappingFile : THandle;
pShMem : PShareMem;
const MessageID = WM_User + 100;implementation {$R *.DFM}
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.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;
edit3.text:='HWND:'+inttostr(pShMem^.data2.hwnd);
panel1.caption:='x='+inttostr(x)+' y='+inttostr(y);
edit2.text:='WindowsText:'+string(pShMem^.buffer);
getClassName(pShMem^.data2.hwnd,s,255);
edit1.text:='ClassName:"'+string(s)+'"';
end
else if Messages.Msg = MessageID+1 then
begin
edit4.text:=inttostr(pShMem^.data2.hwnd);
edit5.text:='WindowsText:'+string(pShMem^.buffer);
getClassName(pShMem^.data2.hwnd,s,255);
edit6.text:='ClassName:"'+string(s)+'"';
end
else Inherited;
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.Button1Click(Sender: TObject);
begin
if capture.caption<>'开始' then
begin
edit4.text:='';
edit5.text:='';
edit6.text:='';
GetRbutton;
end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
pShMem := nil;
end;end.
那不用钩子也可以啊。得到当前活动窗体标题:
function GetActiveWindowText: string;
var
hnd: HWND;
stlen: Integer;
begin
hnd := GetForegroundWindow;
stlen := GetWindowTextLength(hnd);
SetLength(Result, stlen);
GetWindowText(hnd, PChar(Result), stlen+1);
end;这个函数返回值就是标题,
hnd是窗体句柄。