dll
......................................................
library GetKey;{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }uses
  SysUtils,
  Classes,
  Windows,
  HookMain in 'HookMain.pas';{$R *.res}
exports
  OpenGetKeyHook,
  CloseGetKeyHook,
  GetX,
  GetY,
  TestDll;begin
 // InstalledHook:=0;
end.
//////////////////////////dll单元文件/////////////////////////
unit HookMain;interfaceuses Windows,Messages,Dialogs,SysUtils;type
  TShareData=record   //公用信息以及消息的数据结构
    data1:array[1..2] of DWORD;       //接收消息的进程句柄和消息ID
    data2:TMOUSEHOOKSTRUCT;  //鼠标钩子消息参数
    data3:string;
  end;const
  VirtualFileName = 'ShareDllData';
  DataSize = sizeof (TShareData);var
  hMapFile:THandle;    // 内存映射文件句柄
  ShareData:^TShareData; //共享数据指针
  keyInstalledHook:HHook;       //安装的钩子句柄
    mouseInstalledHook:HHook;       //安装的钩子句柄  function keyHookHandler(iCode:Integer;wParam:WPARAM;lParam:LPARAM):
    LRESULT;stdcall;export;
      function mouseHookHandler(iCode:Integer;wParam:WPARAM;lParam:LPARAM):
    LRESULT;stdcall;export;
  function OpenGetKeyHook(sender:HWND;MessageID:WORD):BOOL;stdCall;export;
  function CloseGetKeyHook:BOOL;stdCall;export;
    function GetX:integer;stdcall;export;
  function GetY:integer;stdcall;export;
   function TestDll(i:integer):string;stdcall;
implementation
 var ST:string;
 function TestDll(i:integer):string;stdcall;  //返回键盘值
begincase i  of
     WM_LBUTTONUP:
        begin
    st:=st+'('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '左键)'+#13;
        end;
          WM_LBUTTONDBLCLK:
        begin
 st:=st+'('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '双击左键)'+#13;
        end;
        WM_RBUTTONUP:
        begin
 st:=st+'('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '右键)'+#13;
        end;
        WM_MBUTTONUP:
        begin
 st:=st+'('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '中键)'+ #13;
        end;
        WM_MBUTTONDBLCLK:
        begin
 st:=st+'('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '双击中键)'+ #13;
        end ;
      end;   //判断鼠标按键结束    if ((GetKeyState(VK_SHIFT) AND 128)=128)and ((getkeystate(VK_CAPITAL)   and   1)=1)  then
    //按下CTRL的时候
   begin
   case i  of
      48:
    begin
    ST:=ST+')';
    end;
      49:
    begin
    ST:=ST+'!';
    end;
      50:
    begin
    ST:=ST+'@';
    end;
      51:
    begin
    ST:=ST+'#';
    end;
      52:
    begin
    ST:=ST+'$';
    end;
      53:
    begin
    ST:=ST+'%';
    end;
      54:
    begin
    ST:=ST+'^';
    end;
      55:
    begin
    ST:=ST+'&';
    end;
      56:
    begin
    ST:=ST+'*';
    end;
      57:
    begin
    ST:=ST+'(';
    end;
       192:
    begin
    ST:=ST+'~';
    end;
       189:
    begin
    ST:=ST+'_';
    end;
       187:
    begin
    ST:=ST+'+';
    end;
      219:
    begin....省略一段       //吧键值转换后相加
Result:=ST; //返回键值ST
end;function mouseHookHandler(iCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;export;
begin
  ShareData^.data2:=pMOUSEHOOKSTRUCT(lparam)^; {将钩子消息数据保存到映射内存文件}
TestDll( wParam );
  Result:=CallNextHookEx(mouseInstalledHook,iCode,wParam,lParam); {调用钩子链中下一个过程}
end;function keyHookHandler(iCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;export;
begin
 if lparam > 0 then  //弹起的消息LPARAM值小于0
begin
TestDll( wParam );
  end;
Result:=CallNextHookEx(keyInstalledHook,iCode,wParam,lParam); {调用钩子链中下一个过程}
end;function OpenGetKeyHook(sender:HWND;MessageID:WORD):BOOL;stdCall;export;
begin
  Result:=False;
  if keyInstalledHook = 0 then                  {没有安装钩子}
  begin
    ShareData^.data1[1]:=sender;
    ShareData^.data1[2]:=MessageID ;
    keyInstalledHook := SetWindowsHookEx(WH_KEYBOARD,keyHookHandler,HInstance,0);    mouseInstalledHook := SetWindowsHookEx(WH_mouse,mouseHookHandler,HInstance,0);
    Result:=keyInstalledHook<>0;  end;
end;function CloseGetKeyHook:BOOL;stdCall;export;
begin
  if keyInstalledHook<>0 then                 {安装钩子}
  begin
    UnhookWindowshookEx(keyInstalledHook);    {将钩子从钩子链接除}
    UnhookWindowshookEx(mouseInstalledHook);    {将钩子从钩子链接除}
    keyInstalledHook:=0;
  end;
  Result:=keyInstalledHook=0;
end;
   function GetX:integer;stdcall;export;
begin
  result :=  ShareData^.data2.pt.X;   {返回鼠标位置的X坐标}
end;function GetY:integer;stdcall;export;
begin
   result :=  ShareData^.data2.pt.Y ;  {返回鼠标位置的Y坐标}
end;initialization
  keyInstalledHook:=0;
  hMapFile:= CreateFileMapping ($FFFFFFFF,nil,
      Page_ReadWrite, 0, DataSize, VirtualFileName);{建立内存映射文件}
  if hMapFile = 0 then                                  {处理错误}
      Raise Exception.Create('创建公用数据的Buffer不成功!');
   ShareData := MapViewOfFile ( hMapFile, File_Map_Write,
       0, 0, DataSize);       {获得内存映射文件的句柄}
finalization
   UnMapViewOfFile(ShareData);  {释放内存映射文件}
   CloseHandle (hMapFile);
end./////////////////////////////////////exe////////////////////////////
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;const
  MessageID=WM_User+100;type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Panel2: TPanel;
    GroupBox1: TGroupBox;
    Memo1: TMemo;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Memo1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }  end;var
  Form1: TForm1;
  num:integer;implementation{$R *.dfm}function OpenGetKeyHook(sender:HWND;MessageID:WORD):BOOL;stdCall;external'GetKey.DLL';
function CloseGetKeyHook:BOOL;stdCall;external'GetKey.DLL';
function GetX:integer;stdcall;external'GetKey.DLL';
function GetY:integer;stdcall;external'GetKey.DLL';
function TestDll(i:integer):string;stdcall;external 'GetKey.DLL';procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenGetKeyHook(Form1.Handle,MessageID) then  {挂接钩子过程}
   Memo1.Lines.add('开始记录');
end;procedure TForm1.Button2Click(Sender: TObject);
begin
 if CloseGetKeyHook then                        {接触钩子过程挂接}
 begin
    Memo1.Lines.add('结束记录');
   Memo1.Lines.add(' ');
 end;
end;procedure TForm1.Button3Click(Sender: TObject);
begin
  close;
end;VAR ST : STRING;procedure TForm1.Button4Click(Sender: TObject);
begin Memo1.Lines.add(TestDll(0));
end;procedure TForm1.Memo1Change(Sender: TObject);
beginend;end.这个是挂全局钩子,我运行之后发现只能钩住在这个程序上发生的事件,当我鼠标移动出这个程序窗口,就勾不到任何消息了````怎么回事?``````

解决方案 »

  1.   

    这个钩子是我从书上例子转变过来的,附上原来的'消息版'全局钩子,这个钩子能正常使用unit HookMain;interfaceuses Windows,Messages,Dialogs,SysUtils;type
      TShareData=record   //公用信息以及消息的数据结构
        data1:array[1..2] of DWORD;       //接收消息的进程句柄和消息ID
        data2:TMOUSEHOOKSTRUCT;  //鼠标钩子消息参数
        data3:string;
      end;const
      VirtualFileName = 'ShareDllData';
      DataSize = sizeof (TShareData);var
      hMapFile:THandle;    // 内存映射文件句柄
      ShareData:^TShareData; //共享数据指针
      keyInstalledHook:HHook;       //安装的钩子句柄
        mouseInstalledHook:HHook;       //安装的钩子句柄
          h1:HWND;
          title:PChar;   
          count:integer;  function keyHookHandler(iCode:Integer;wParam:WPARAM;lParam:LPARAM):
        LRESULT;stdcall;export;
          function mouseHookHandler(iCode:Integer;wParam:WPARAM;lParam:LPARAM):
        LRESULT;stdcall;export;
      function OpenGetKeyHook(sender:HWND;MessageID:WORD):BOOL;stdCall;export;
      function CloseGetKeyHook:BOOL;stdCall;export;
        function GetX:integer;stdcall;export;
      function GetY:integer;stdcall;export;
       function TestDll(i:string):string;stdcall;
    implementation          var ts:string;
     function TestDll(i:string):string;stdcall;
    begin
    ts:=ts+i;
    Result:=ts;
    end;
    function mouseHookHandler(iCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;export;
    begin
      ShareData^.data2:=pMOUSEHOOKSTRUCT(lparam)^; {将钩子消息数据保存到映射内存文件}
    SendMessage(ShareData^.data1[1],
          ShareData^.data1[2],wParam,lParam);{向主窗口发送鼠标消息}
      Result:=CallNextHookEx(mouseInstalledHook,iCode,wParam,lParam); {调用钩子链中下一个过程}
    end;function keyHookHandler(iCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;export;
    beginSendMessage(ShareData^.data1[1],
          ShareData^.data1[2],wParam,lParam);{向主窗口发送鼠标消息}
          TestDll(screen.ActiveForm.Caption);  Result:=CallNextHookEx(keyInstalledHook,iCode,wParam,lParam); {调用钩子链中下一个过程}
    end;function OpenGetKeyHook(sender:HWND;MessageID:WORD):BOOL;stdCall;export;
    begin
      Result:=False;
      if keyInstalledHook = 0 then                  {没有安装钩子}
      begin
        ShareData^.data1[1]:=sender;
        ShareData^.data1[2]:=MessageID ;
        keyInstalledHook := SetWindowsHookEx(WH_KEYBOARD,keyHookHandler,HInstance,0);    mouseInstalledHook := SetWindowsHookEx(WH_mouse,mouseHookHandler,HInstance,0);
        Result:=keyInstalledHook<>0;  end;
    end;function CloseGetKeyHook:BOOL;stdCall;export;
    begin
      if keyInstalledHook<>0 then                 {安装钩子}
      begin
        UnhookWindowshookEx(keyInstalledHook);    {将钩子从钩子链接除}
        UnhookWindowshookEx(mouseInstalledHook);    {将钩子从钩子链接除}
        keyInstalledHook:=0;
      end;
      Result:=keyInstalledHook=0;
    end;
       function GetX:integer;stdcall;export;
    begin
      result :=  ShareData^.data2.pt.X;   {返回鼠标位置的X坐标}
    end;function GetY:integer;stdcall;export;
    begin
       result :=  ShareData^.data2.pt.Y ;  {返回鼠标位置的Y坐标}
    end;initialization
      keyInstalledHook:=0;
      hMapFile:= CreateFileMapping ($FFFFFFFF,nil,
          Page_ReadWrite, 0, DataSize, VirtualFileName);{建立内存映射文件}
      if hMapFile = 0 then                                  {处理错误}
          Raise Exception.Create('创建公用数据的Buffer不成功!');
       ShareData := MapViewOfFile ( hMapFile, File_Map_Write,
           0, 0, DataSize);       {获得内存映射文件的句柄}
    finalization
       UnMapViewOfFile(ShareData);  {释放内存映射文件}
       CloseHandle (hMapFile);
    end.
    ////////////////////////exe///////////////unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;const
      MessageID=WM_User+100;type
      TForm1 = class(TForm)
        Panel1: TPanel;
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        Panel2: TPanel;
        GroupBox1: TGroupBox;
        Memo1: TMemo;
        Button4: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
        procedure Panel1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
         procedure WndProc(var Message:TMessage);override;
      end;var
      Form1: TForm1;
      num:integer;implementation{$R *.dfm}function OpenGetKeyHook(sender:HWND;MessageID:WORD):BOOL;stdCall;external'GetKey.DLL';
    function CloseGetKeyHook:BOOL;stdCall;external'GetKey.DLL';
    function GetX:integer;stdcall;external'GetKey.DLL';
    function GetY:integer;stdcall;external'GetKey.DLL';
    function TestDll(i:string):string;stdcall;external 'GetKey.DLL';procedure TForm1.Button1Click(Sender: TObject);
    begin
      if OpenGetKeyHook(Form1.Handle,MessageID) then  {挂接钩子过程}
       Memo1.Lines.add('开始记录');
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
     if CloseGetKeyHook then                        {接触钩子过程挂接}
     begin
        Memo1.Lines.add('结束记录');
       Memo1.Lines.add(' ');
     end;
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
      close;
    end;VAR ST : STRING;procedure TForm1.WndProc(var Message:TMessage);
    begin
      if( Message.Msg=MessageID) and (Message.lParam > 0)  then    //弹起某个按键的LPARAM值是负数
      begin
        with Memo1.Lines do
        begin
          case Message.WParam  of
            WM_LBUTTONUP:
            begin
       ST:=ST + '('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '释放左键!)';
            end;
            WM_LBUTTONDBLCLK:
            begin
       ST:=ST + '('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '双击左键!)';
            end;
            WM_RBUTTONUP:
            begin
       ST:=ST + '('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '释放右键!)';
            end;
            WM_MBUTTONUP:
            begin
       ST:=ST + '('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '释放中键!)';
            end;
            WM_MBUTTONDBLCLK:
            begin
       ST:=ST + '('+ IntToStr(GetX) + ','+ IntToStr(GetY ) + '双击中键!)';
            end ;
          end;   //判断鼠标按键结束
        if ((GetKeyState(VK_SHIFT) AND 128)=128)and ((getkeystate(VK_CAPITAL)   and   1)=1)  then
       begin
       case Message.WParam  of
          48:
        begin
        ST:=ST+')';
        end;
          49:
        begin
        ST:=ST+'!';
        end;
          50:
        begin
        ST:=ST+'@';
        end;
          51:
        begin
        ST:=ST+'#';
        end;
          52:
        begin
        ST:=ST+'$';
        end;
          53:
        begin
        ST:=ST+'%';
        end;
          54:
        begin
        ST:=ST+'^';
        end;
          55:
        begin
        ST:=ST+'&';
        end;
          56:
        begin
        ST:=ST+'*';
        end;
          57:
        begin
        ST:=ST+'(';
        end;
           192:
        begin
        ST:=ST+'~';
        end;
           189:
        begin
        ST:=ST+'_';
        end;
           187:
        begin
        ST:=ST+'+';
        end;
       ////省略一段`````````
       end;   end;  Inherited;
    end;procedure TForm1.Button4Click(Sender: TObject);
    begin  Memo1.Lines.add(st);
    end;procedure TForm1.Panel1Click(Sender: TObject);
    beginend;end.
      

  2.   

    你挂接的不是全局HOOK,看SetWindowsHookEx的第三个参数。这种方式不是全局HOOK,google搜索一下全局HOOK代码看看吧!function   OpenGetKeyHook(sender:HWND;MessageID:WORD):BOOL;stdCall;export; 
    begin 
        Result:=False; 
        if   keyInstalledHook   =   0   then                                     {没有安装钩子} 
        begin 
            ShareData^.data1[1]:=sender; 
            ShareData^.data1[2]:=MessageID   ; 
            keyInstalledHook   :=   SetWindowsHookEx(WH_KEYBOARD,keyHookHandler,HInstance,0);         mouseInstalledHook   :=   SetWindowsHookEx(WH_mouse,mouseHookHandler,HInstance,0); 
            Result:=keyInstalledHook < >0;     end; 
    end; 
      

  3.   

      if   ((GetKeyState(VK_SHIFT)   AND   128)=128)and   ((getkeystate(VK_CAPITAL)       and       1)=1)     then 
            //按下CTRL的时候 
          begin 
          case   i     of 
                48: 
            begin 
            ST:=ST+ ") "; 
            end; 
                49: 
            begin 
            ST:=ST+ "! "; 
            end; 
                50: 
            begin 
            ST:=ST+ "@ "; 
            end; 
                51: 
            begin 
            ST:=ST+ "# "; 
            end; 
                52: 
            begin 
            ST:=ST+ "$ "; 
            end; 
                53: 
            begin 
            ST:=ST+ "% "; 
            end; 
                54: 
            begin 
            ST:=ST+ "^ "; 
            end; 
                55: 
            begin 
            ST:=ST+ "& "; 
            end; 
                56: 
            begin 
            ST:=ST+ "* "; 
            end; 
                57: 
            begin 
            ST:=ST+ "( "; 
            end; 
                  192: 
            begin 
            ST:=ST+ "~ "; 
            end; 
                  189: 
            begin 
            ST:=ST+ "_ "; 
            end; 
                  187: 
            begin 
            ST:=ST+ "+ "; 
            end; 
          end;ST:=ST+I;//当我鼠标移动出了程序窗口,就收不到鼠标移动消息了....省略一段               //吧键值转换后相加 
    Result:=ST;   //返回键值ST 
    end;