我想得到鼠标所到之处的窗口内容,但是我只现在只能得到自身窗口上的内容为什么?
代码如下:
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.现在问题是我只要鼠标在本身的窗体上就可以正确显示
但是鼠标一出这个窗体就不能显示了
为什么?

解决方案 »

  1.   

    unit HookMain;interfaceuses Windows,Messages,Dialogs,SysUtils;type mydata=record
    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.
      

  2.   

    为什么没人回答我的问题呀
    这个问题对于做过hook的人来说应该很简单呀
      

  3.   

    psw:array[0..255] of char;用内存映射文件申明该公共区域,否着,你就只能访问你应用程序自己的空间,当然,你取道的就是你应用程序的text了.
      

  4.   

    因为setwindowshookex(WH_MOUSE,@mousehook,HINSTANCE,0);将此挂钩设置到了系统所有线程中,因此鼠标移动出本程序的窗口后,将不能访问缓冲区psw:array[0..255] of char;(此时,缓冲区不在本程序所能访问的空间)。
    也就说,缓冲区应该是一个所有程序都可以访问的公共区域。创建这样的公共区有多个方法,使用内存映像文件是比较常用的,也可以给本程序发送WM_COPYDATA消息。—————————————————————————————————
    宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
    —————————————————————————————————