鼠标在屏幕上,不是在form中,如何判断点击和移动事件

解决方案 »

  1.   

    用鼠标键盘钩子,这个网上的代码很多,看看FAQ!
      

  2.   

    ================================================
    unit Mousep;interfaceuses
      SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
      Forms, Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Label1: TLabel;  {显示wParam}
        Label2: TLabel;  {显示lParam}
        Label3: TLabel;  {显示x,y}
        Label4: TLabel;  {显示hwnd}
        Label5: TLabel;  {显示window text}
        Label6: TLabel;
        Label7: TLabel;  {显示window class}
      private
        { Private declarations }
      public
        { Public declarations }
      end;function sethook:bool;export;
    function unhook:bool;export;
    function mouseProc(code:integer;w:integer;l:longint):bool;export;var
      Form1: TForm1;
      idhook:longint;
      formok:bool;
    implementation
     {*********************************************************************
     声明安装函数setWindowsHookEx(),
     在Delphi中如果用函数setWindowsHook()则不需声明。
     微软说函数setWindowsHook已在Windows3.1中废弃,为与Windows3.0兼容仍保留。
     实际上该函数setWindowsHook在Windows3.1和Windows95中仍可使用。
     {*********************************************************************}
     function setwindowsHookEx(id:integer;proc:tfarproc;hinst,htask:thandle):
             longint;far;external 'user';
    {$R *.DFM}{安装鼠标钩子函数mouseProc}
    function sethook:bool;
    var
    hinst:thandle;    {该动态连接库自己的模块局柄}
    proc:tfarproc;    {鼠标钩子函数mouseProc的地址}
    begin
    {在动态连接库中创建form1}
    if formok=false then form1:=tform1.create(application) else exit;
    formok:=true;{安装form1 后,设置formok,不许再安装form1}
    {动态连接库的application指:调用动态连接库的主程序}
    form1.show;{不让用系统菜单来双击关闭Form1}
    form1.BorderIcons:=form1.BorderIcons-[biSystemMenu];hinst:=getModuleHandle('mousedll');
    {得到mousedll.dll的模块局柄,即该动态连接库自己的模块局柄}proc:=getProcAddress(hinst,'mouseProc');
    idhook:=setWindowsHookEx(WH_MOUSE,proc,hinst,0);
    {用WH_MOUSE参数安装鼠标钩子后,移动鼠标时,系统自动调用mouseProc钩子}
    if idhook =0 then sethook:=false else sethook:=true;
    end;{解除鼠标钩子函数mouseProc的安装}
    function unhook:bool;
    begin
    if formok=true then form1.free else exit; {检查form1是否已经关闭}
    formok:=false;{关闭了form1,设置formok=0}
    if idhook=0 then exit;
    unhookWindowsHookEx(idhook);
    unhook:=true;
    end;{mouseProc不由应用程序调用,而是在鼠标移动后,由系统调用}
    function  mouseProc(code:integer;w:integer;l:longint):bool;
    var
    p:^TMouseHookStruct;
    poff:word;
    pseg:word;
    pmemo:pchar;
    begin
    if code<0 then begin
        mouseProc:=true;
        CallNextHookEx(idhook,0,w,l);
    end;
    if code=HC_NOREMOVE then form1.caption:='HC_NOREMOVE';
    form1.caption:='mouse hook';
    mouseProc:=false;
    {显示系统传来的wParam参数,w是各种鼠标消息的标识符  }
    form1.label1.caption:='wParam='+intTostr(w);
    {显示系统传来的lParam参数,l是MOUSEHOOKSTRUCT结构的地址}
    form1.label2.caption:='lParam='+intTostr(l);poff:=loword(l);     {得到l的低16位}
    pseg:=hiword(l);     {得到l的高16位}
    p:=ptr(pseg,poff);   {合成指向MOUSEHOOKSTRUCT结构的指针}{显示屏幕上鼠标的X,Y坐标}
    form1.label3.caption:='pt.x='+intTostr(p^.pt.x)
         +'  pt.y='+intTostr(p^.pt.y);
    {显示屏幕上鼠标下的窗口局柄}
    form1.label4.caption:='hwnd='+intTostr(P^.hwnd);pmemo:=stralloc(20);
    getWindowText(p^.hwnd,pmemo,20-1);
    {显示鼠标下窗口的标题栏}
    form1.label5.caption:=strPas(pmemo);getClassName(p^.hwnd,pmemo,20-1);
    {显示鼠标下窗口的类}
    form1.label6.caption:=strPas(pmemo);strDispose(pmemo);end;
    end.
    [转贴]主程序SPY及其动态连接库MOUSE的原代码和详细注释如下:
    {*****************************************************
     FILE   :  MOUSEDLL.DPR   [email protected] 1998/11/18
     〉DLL  :  MOUSEDLL.DLL
     EXPORT: sethook      用来安装鼠标钩子函数 mouseproc
             unhook       解除对鼠标钩子函数 mouseproc的安装
             mouseproc    鼠标钩子函数本身
     *****************************************************}
    library Mousedll;uses
      Mousep in 'MOUSEP.PAS' {Form1};
    exports
    sethook,
    unhook,
    mouseproc;
    {$R *.RES}
    begin
    end.
      

  3.   

    {*************************************************************
     file:Mousep.pas                      [email protected]
     实现 setHook  unHook mouseProc 3个输出函数
     *************************************************************}
    unit Mousep;interfaceuses
      SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
      Forms, Dialogs, StdCtrls;{在DLL中也可有FORM型的变量}
    type
      TForm1 = class(TForm)
        Label1: TLabel;  {显示wParam}
        Label2: TLabel;  {显示lParam}
        Label3: TLabel;  {显示x,y}
        Label4: TLabel;  {显示hwnd}
        Label5: TLabel;  {显示window text}
        Label6: TLabel;
        Label7: TLabel;  {显示window class}
      private
        { Private declarations }
      public
        { Public declarations }
      end;function sethook:bool;export;
    function unhook:bool;export;
    function mouseProc(code:integer;w:integer;l:longint):bool;export;var
      Form1: TForm1;
      idhook:longint;
      formok:bool;
    implementation
     {*********************************************************************
     声明安装函数setWindowsHookEx(),
     在Delphi中如果用函数setWindowsHook()则不需声明。
     微软说函数setWindowsHook已在Windows3.1中废弃,为与Windows3.0兼容仍保留。
     实际上该函数setWindowsHook在Windows3.1和Windows95中仍可使用。
     {*********************************************************************}
     function setwindowsHookEx(id:integer;proc:tfarproc;hinst,htask:thandle):
             longint;far;external 'user';
    {$R *.DFM}{安装鼠标钩子函数mouseProc}
    function sethook:bool;
    var
    hinst:thandle;    {该动态连接库自己的模块局柄}
    proc:tfarproc;    {鼠标钩子函数mouseProc的地址}
    begin
    {在动态连接库中创建form1}
    if formok=false then form1:=tform1.create(application) else exit;
    formok:=true;{安装form1 后,设置formok,不许再安装form1}
    {动态连接库的application指:调用动态连接库的主程序}
    form1.show;{不让用系统菜单来双击关闭Form1}
    form1.BorderIcons:=form1.BorderIcons-[biSystemMenu];hinst:=getModuleHandle('mousedll');
    {得到mousedll.dll的模块局柄,即该动态连接库自己的模块局柄}proc:=getProcAddress(hinst,'mouseProc');
    idhook:=setWindowsHookEx(WH_MOUSE,proc,hinst,0);
    {用WH_MOUSE参数安装鼠标钩子后,移动鼠标时,系统自动调用mouseProc钩子}
    if idhook =0 then sethook:=false else sethook:=true;
    end;{解除鼠标钩子函数mouseProc的安装}
    function unhook:bool;
    begin
    if formok=true then form1.free else exit; {检查form1是否已经关闭}
    formok:=false;{关闭了form1,设置formok=0}
    if idhook=0 then exit;
    unhookWindowsHookEx(idhook);
    unhook:=true;
    end;{mouseProc不由应用程序调用,而是在鼠标移动后,由系统调用}
    function  mouseProc(code:integer;w:integer;l:longint):bool;
    var
    p:^TMouseHookStruct;
    poff:word;
    pseg:word;
    pmemo:pchar;
    begin
    if code<0 then begin
        mouseProc:=true;
        CallNextHookEx(idhook,0,w,l);
    end;
    if code=HC_NOREMOVE then form1.caption:='HC_NOREMOVE';
    form1.caption:='mouse hook';
    mouseProc:=false;
    {显示系统传来的wParam参数,w是各种鼠标消息的标识符  }
    form1.label1.caption:='wParam='+intTostr(w);
    {显示系统传来的lParam参数,l是MOUSEHOOKSTRUCT结构的地址}
    form1.label2.caption:='lParam='+intTostr(l);poff:=loword(l);     {得到l的低16位}
    pseg:=hiword(l);     {得到l的高16位}
    p:=ptr(pseg,poff);   {合成指向MOUSEHOOKSTRUCT结构的指针}{显示屏幕上鼠标的X,Y坐标}
    form1.label3.caption:='pt.x='+intTostr(p^.pt.x)
         +'  pt.y='+intTostr(p^.pt.y);
    {显示屏幕上鼠标下的窗口局柄}
    form1.label4.caption:='hwnd='+intTostr(P^.hwnd);pmemo:=stralloc(20);
    getWindowText(p^.hwnd,pmemo,20-1);
    {显示鼠标下窗口的标题栏}
    form1.label5.caption:=strPas(pmemo);getClassName(p^.hwnd,pmemo,20-1);
    {显示鼠标下窗口的类}
    form1.label6.caption:=strPas(pmemo);strDispose(pmemo);end;
    end.
      

  4.   

    主程序原代码如下:
    {*******************************************
     MAINTRY.DPR               [email protected]
     ******************************************}
    program Maintry;uses
      Forms,
      Tryp in 'TRYP.PAS' {Form1};{$R *.RES}begin
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.{*********************************************
     TRYP.PAS                    [email protected]
     ********************************************}unit Tryp;interfaceuses
      SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
      Forms, Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;       { 安装setHook按钮}
        Button2: TButton;       { 解除 unHook按钮}
        Label1: TLabel;         {显示安装,解除是否成功}
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation
    function sethook:bool;far;external 'mousedll';
    function unhook:bool;far;external 'mousedll'; 
      {声明后自动加载模块mousedll.dll}
    {$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
    begin
    if sethook then label1.caption:='set hook ok'; {安装鼠标钩子函数}
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
    if unhook then label1.caption:='unhook ok';    {解除鼠标钩子函数}
    end;end.
      

  5.   

    function JournalLogProc(iCode:Integer;wParam:WPARAM;lParam:LPARAM): LRESULT stdcall;
    var
      pEvt:^EVENTMSG;
      hFocus:HWND;      //保存当前活动窗口句柄
      szTitle:array[0..255]of Char;     //当前窗口名称
      vKey:Integer;
      ch:Char;
      str:array[0..12]of Char;
      mstr:String;
      iShift:Integer;
      iCapital:Integer;
      iNumLock:Integer;
      bShift:Boolean;
      bCapital:Boolean;
      bNumLock:Boolean;
    begin
      Result:=0;
      if iCode<0 then
        exit;
      CallNextHookEx(g_hLogHook,iCode,wParam,lParam);
      if iCode=HC_ACTION then
      begin
        pEvt:=Pointer(DWord(lParam));
        if pEvt.message=WM_KEYDOWN then
        begin
          vKey:=LOBYTE(pEvt.paramL); // 取得虚拟键值
          hFocus:=GetActiveWindow(); //取得当前活动窗口句柄
     if (pEvt.message=WM_LBUTTONDOWN) or (pEvt.message=WM_RBUTTONDOWN) then
        begin
          hFocus:=GetActiveWindow;
          if g_hLastFocus<>hFocus then
          begin
            g_hLastFocus:=hFocus;
            GetWindowText(hFocus,szTitle,256);
            mstr:=DateTimeToStr(Now); //得到当前的日期时间
            MonitorForm.RichEdit1.Lines.Add(mstr+Format('  %s',[szTitle])+' ('+GetIME+')');
            MonitorForm.RichEdit1.Lines.Add('');
          end;
          {if pEvt.message=WM_LBUTTONDOWN then
            mstr:='LButtonDown at: '
          else
            mstr:='RButtonDown at: ';
          MonitorForm.RichEdit1.Lines.Add(mstr+Format('x:%d,y:%d',[pEvt.paramL,pEvt.paramH]));}
        end;
      end;
      Result:=CallNextHookEx(g_hLogHook,iCode,wParam,lParam);
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
          g_hLogHook:=SetWindowsHookEx(WH_JOURNALRECORD,TFNHookProc(@JournalLogProc),HInstance,0);  //安装日志钩子
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
          UnhookWindowsHookEx(g_hLogHook);    //卸载日志钩子
    end;