我想得到鼠标所到之处的窗口内容,但是我只现在只能得到自身窗口上的内容为什么?
代码如下:
unit main;interface
uses windows,Messages;
procedure enablehook;export;
procedure getmouse(var ax,ay:integer; var Apsw:pchar);export;
function mousehook(ncode:integer;wParam:wparam;lparam:pointer):LRESULT;stdcall;
procedure disenablehook;export;
var
newhook:hhook=0;
mousepos:Tpoint;
psw:array[0..255] of char;
implementation
procedure enablehook;export;
begin
if newhook=0 then
newhook:=setwindowshookex(WH_MOUSE,@mousehook,HINSTANCE,0);
end;
function mousehook(ncode:integer;wParam:wparam;lparam:Pointer):LRESULT;
var
l:^mousehookstruct;
begin
result:=0;
l:=lparam;
mousepos:=l.pt;
if ncode<0then
result:=callnexthookex(newhook,ncode,wparam,integer(lparam))
else
begin
sendmessage(windowfrompoint(l.pt),wm_gettext,255,integer(@psw));
end;
end;
procedure disenablehook;
begin
if newhook<>0 then
unhookwindowshookex(newhook);
end;
procedure getmouse(var ax,ay:integer; var Apsw:pchar);
begin
ax:=mousepos.X;
ay:=mousepos.Y;
Apsw:=psw;
end;
end.上面是dll文件的代码
下面是exe文件的代码:unit main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
isstop:bool;
{ Private declarations }
public
{ Public declarations }
end;
procedure enablehook;export;external 'mousehook.dll';
procedure disenablehook;export;external 'mousehook.dll';
procedure getmouse(var ax,ay:integer;var apsw:pchar);export;external 'mousehook.dll';
var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
lx,ly:integer;
lpsw:pchar;
begin
EnableHook;
getmouse(lx,ly,lpsw);
isStop:=false;
while not isStop do
begin
GetMouse(lx,ly,lpsw);
Edit1.Text:=String(lx)+','+String(ly);
Edit2.Text:=lpsw;
Application.ProcessMessages;
end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
isstop:=true;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
isstop:=true;
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
isstop:=true;
disenablehook;
end;end.现在问题是我只要鼠标在本身的窗体上就可以正确显示
但是鼠标一出这个窗体就不能显示了
为什么?
代码如下:
unit main;interface
uses windows,Messages;
procedure enablehook;export;
procedure getmouse(var ax,ay:integer; var Apsw:pchar);export;
function mousehook(ncode:integer;wParam:wparam;lparam:pointer):LRESULT;stdcall;
procedure disenablehook;export;
var
newhook:hhook=0;
mousepos:Tpoint;
psw:array[0..255] of char;
implementation
procedure enablehook;export;
begin
if newhook=0 then
newhook:=setwindowshookex(WH_MOUSE,@mousehook,HINSTANCE,0);
end;
function mousehook(ncode:integer;wParam:wparam;lparam:Pointer):LRESULT;
var
l:^mousehookstruct;
begin
result:=0;
l:=lparam;
mousepos:=l.pt;
if ncode<0then
result:=callnexthookex(newhook,ncode,wparam,integer(lparam))
else
begin
sendmessage(windowfrompoint(l.pt),wm_gettext,255,integer(@psw));
end;
end;
procedure disenablehook;
begin
if newhook<>0 then
unhookwindowshookex(newhook);
end;
procedure getmouse(var ax,ay:integer; var Apsw:pchar);
begin
ax:=mousepos.X;
ay:=mousepos.Y;
Apsw:=psw;
end;
end.上面是dll文件的代码
下面是exe文件的代码:unit main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
isstop:bool;
{ Private declarations }
public
{ Public declarations }
end;
procedure enablehook;export;external 'mousehook.dll';
procedure disenablehook;export;external 'mousehook.dll';
procedure getmouse(var ax,ay:integer;var apsw:pchar);export;external 'mousehook.dll';
var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
lx,ly:integer;
lpsw:pchar;
begin
EnableHook;
getmouse(lx,ly,lpsw);
isStop:=false;
while not isStop do
begin
GetMouse(lx,ly,lpsw);
Edit1.Text:=String(lx)+','+String(ly);
Edit2.Text:=lpsw;
Application.ProcessMessages;
end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
isstop:=true;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
isstop:=true;
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
isstop:=true;
disenablehook;
end;end.现在问题是我只要鼠标在本身的窗体上就可以正确显示
但是鼠标一出这个窗体就不能显示了
为什么?
data1:array [1..2] of DWORD;
data2:TMOUSEHOOKSTRUCT;
end;var hObject : Thandle;
pMem : Pointer;
NextHook: Hhook;
procSaveExit: Pointer;function HookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export;
function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; export;
function CloseGetKeyHook: BOOL; export;
function GetPublicP : Pointer;stdcall; export;
Procedure DLLMain(dwReason:Dword); far;
procedure HookExit; far;implementation
Procedure UnMapMem;
begin
if Assigned(pMem) then
begin
UnMapViewOfFile(pMem);
pMem := Nil;
end;
end;
Procedure MapMem;
begin
hObject := CreateFileMapping($FFFFFFFF,Nil,Page_ReadWrite,0,$FFFF,pChar('_IOBuffer'));
if hObject = 0 then Raise Exception.Create('创建公用数据的Buffer不成功!');
pMem := MapViewOfFile(hObject,FILE_MAP_WRITE,0,0,SizeOf(mydata));
if not Assigned(pMem) then
begin
UnMapMem;
Raise Exception.Create('创建公用数据的映射关系不成功!');
end;
end;Procedure DLLMain(dwReason:Dword); far;
begin
Case dwReason of
DLL_PROCESS_ATTACH :
begin
pMem := nil;
hObject := 0;
MapMem; //以下的公有数据,如tHWNDtMessageID将直接使用本Buf.
End;
DLL_PROCESS_DETACH : UnMapMem;
DLL_THREAD_ATTACH:;
DLL_THREAD_DETACH:; //缺省
end;
end;
procedure HookExit; far;
begin
CloseGetKeyHook;
ExitProc := procSaveExit;
end;
function GetPublicP : Pointer;export;
begin //这里引出了公用数据区的指针,你可以在你的应用程序中自由操作它。但建议去掉此接口。
Result := pMem;
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);
begin
if wparam=WM_LBUTTONUP then
mydata(pmem^).data2:=pMOUSEHOOKSTRUCT(lparam)^;
SendMessage(mydata(pMem^).data1[1],mydata(pMem^).data1[2],wParam,
integer(@(mydata(pmem^).data2))); //发送消息
end;
end;
function OpenGetKeyHook(sender : HWND;MessageID : WORD) : BOOL; export;
begin
Result := False;
if NextHook <> 0 then Exit; //已经安装了本钩子
mydata(pmem^).data1[1]:=sender;
mydata(pmem^).data1[2]:=messageid;
NextHook := SetWindowsHookEx(WH_mouse,HookHandler,Hinstance,0);
Result := NextHook <> 0;
end;
function CloseGetKeyHook: BOOL; export;
begin
if NextHook <> 0 then
begin
UnhookWindowshookEx(NextHook);
NextHook := 0;
end;
Result := NextHook = 0;
end;
end.
这个问题对于做过hook的人来说应该很简单呀
也就说,缓冲区应该是一个所有程序都可以访问的公共区域。创建这样的公共区有多个方法,使用内存映像文件是比较常用的,也可以给本程序发送WM_COPYDATA消息。—————————————————————————————————
宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
—————————————————————————————————