library eBoardHook;
uses
  Windows,
  Messages,
  HookUnit in 'HookUnit.pas';
exports
  InstallHook,
  UninstallHook,
  IsHooked;
end.unit HookUnit;interface
uses
  Windows,Messages;
  
const
 MSG_HOOK_MOUSE_EVENT='My_MOUSE_EVENT';function InstallHook(Hwnd: Cardinal): Bool; stdcall;export;
function UninstallHook: Bool; stdcall;export;
function IsHooked: Bool;stdcall;export;
implementation
var
  HookHandle: HHook;
  WindowHandle: HWND;
  MouseHookEvent: integer;function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM):
 LRESULT; stdcall;
begin
  if nCode = HC_ACTION then
    begin
      with PMouseHookStruct(lParam)^ do
      PostMessage(WindowHandle,MouseHookEvent, wParam, (pt.x and $FFFF) or (pt.y shl 16));
    end;
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;function InstallHook(Hwnd: Cardinal): Bool; stdcall;export;
begin
  HookHandle := SetWindowsHookEx(WH_MOUSE, @MouseHookProc, HInstance, 0);
  Result := HookHandle>0;
  if Result then
    begin
      WindowHandle := Hwnd;
      if MouseHookEvent=0 then
        // MouseHookEvent:=RegisterWindowMessage(PChar(MSG_HOOK_MOUSE_EVENT));
        MouseHookEvent:=WM_User+1054;
    end;
end;function UninstallHook: Bool; stdcall;export;
begin
  Result := UnhookWindowsHookEx(HookHandle);
  HookHandle := 0;
end;function IsHooked: Bool;stdcall;export;
begin
  Result:=HookHandle>0;
end;end.

解决方案 »

  1.   

    library HookDLL;uses WinTypes, WinProcs, Messages;
    var
      HookCount: integer;
      HookHandle: HHook;
    { This is where you do your special processing. }
    {$IFDEF WIN32}
    function MouseHookCallBack(Code: integer; Msg: WPARAM; MouseHook: LPARAM): LRESULT; stdcall;
    {$ELSE}
    function MouseHookCallBack(Code: integer; Msg: word; MouseHook: longint): longint; export;
    {$ENDIF}
    begin
      { If the value of Code is less than 0, we are not allowed to do anything except pass }
      { it on to the next hook procedure immediately.                                      }
      if Code >= 0 then begin
        { This example does nothing except beep when the right mouse button is pressed. }
        if Msg = WM_RBUTTONDOWN then
          MessageBeep(1);
    { This is probably closer to what you would want to do...
        case Msg of:
          WM_LBUTTONDOWN:
            begin
            end;
          WM_LBUTTONUP:
            begin
            end;
          WM_LBUTTONDBLCLK:
            begin
            end;
          WM_RBUTTONDOWN:
            begin
            end;
          WM_RBUTTONUP:
            begin
            end;
          WM_RBUTTONDBLCLK:
            begin
            end;
          WM_MBUTTONDOWN:
            begin
            end;
          WM_MBUTTONUP:
            begin
            end;
          WM_MBUTTONDBLCLK:
            begin
            end;
          WM_MOUSEMOVE:
            begin
            end;
        end;}    { If you handled the situation, and don't want Windows to process the }
        { message, do *NOT* execute the next line.  Be very sure this is what }
        { want, though.  If you don't pass on stuff like WM_MOUSEMOVE, you    }
        { will NOT like the results you get.                                  }
        Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
      end else
        Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
    end;{ Call InstallHook to set the hook. }
    function InstallHook(SystemHook: boolean; TaskHandle: THandle) : boolean; export;
      { This is really silly, but that's the way it goes.  The only way to get the  }
      { module handle, *not* instance, is from the filename.  The Microsoft example }
      { just hard-codes the DLL filename.  I think this is a little bit better.     }
      function GetModuleHandleFromInstance: THandle;
      var
        s: array[0..512] of char;
      begin
        { Find the DLL filename from the instance value. }
        GetModuleFileName(hInstance, s, sizeof(s)-1);
        { Find the handle from the filename. }
        Result := GetModuleHandle(s);
      end;
    begin
      { Technically, this procedure could do nothing but call SetWindowsHookEx(),  }
      { but it is probably better to be sure about things, and not set the hook    }
      { more than once.  You definitely don't want your callback being called more }
      { than once per message, do you?                                             }
      Result := TRUE;
      if HookCount = 0 then begin
        if SystemHook then
          HookHandle := SetWindowsHookEx(WH_MOUSE, MouseHookCallBack, HInstance, 0)
        else
          { See the Microsoft KnowledgeBase, PSS ID Number: Q92659, for a discussion of }
          { the Windows bug that requires GetModuleHandle() to be used.                 }
          HookHandle := SetWindowsHookEx(WH_MOUSE, MouseHookCallBack,
                                         GetModuleHandleFromInstance, TaskHandle);
        if HookHandle <> 0 then
          inc(HookCount)
        else
          Result := FALSE;
      end else
        inc(HookCount);
    end;{ Call RemoveHook to remove the system hook. }
    function RemoveHook: boolean; export;
    begin
      { See if our reference count is down to 0, and if so then unhook. }
      Result := FALSE;
      if HookCount < 1 then exit;
      Result := TRUE;
      dec(HookCount);
      if HookCount = 0 then
        Result := UnhookWindowsHookEx(HookHandle);
    end;{ Have we hooked into the system? }
    function IsHookSet: boolean; export;
    begin
      Result := (HookCount > 0) and (HookHandle <> 0);
    end;exports
      InstallHook,
      RemoveHook,
      IsHookSet,
      MouseHookCallBack;{ Initialize DLL data. }
    begin
      HookCount := 0;
      HookHandle := 0;
    end.
      

  2.   

    unit Main;interfaceuses
      SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
      Forms, Dialogs, StdCtrls, HookUnit;type
      THookForm = class(TForm)
        SysHookBtn: TButton;
        RemoveHookBtn: TButton;
        TaskHookBtn: TButton;
        procedure FormCreate(Sender: TObject);
        procedure SysHookBtnClick(Sender: TObject);
        procedure RemoveHookBtnClick(Sender: TObject);
        procedure TaskHookBtnClick(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      public
        procedure UpdateButtons;
      end;var
      HookForm: THookForm;implementation{$R *.DFM}procedure THookForm.FormCreate(Sender: TObject);
    begin
      UpdateButtons;
    end;procedure THookForm.FormDestroy(Sender: TObject);
    begin
      while IsHookSet do
        RemoveHook; { Make sure we unhook ourselves. }
    end;procedure THookForm.SysHookBtnClick(Sender: TObject);
    begin
      if not InstallSystemHook then
        ShowMessage('Could not install mouse hook.  SetWindowsHookEx() failed.');
      UpdateButtons;
    end;procedure THookForm.TaskHookBtnClick(Sender: TObject);
    begin
      if not InstallTaskHook then
        ShowMessage('Could not install task hook.  SetWindowsHookEx() failed.');
      UpdateButtons;
    end;procedure THookForm.RemoveHookBtnClick(Sender: TObject);
    begin
      if IsHookSet then
        RemoveHook;
      UpdateButtons;
    end;procedure THookForm.UpdateButtons;
    begin
      SysHookBtn.Enabled := not IsHookSet;
      TaskHookBtn.Enabled := not IsHookSet;
      RemoveHookBtn.Enabled := IsHookSet;
    end;end.
      

  3.   

    interfaceuses WinTypes;function InstallSystemHook: boolean;
    function InstallTaskHook: boolean;
    function RemoveHook: boolean;
    function IsHookSet: boolean;
    { Do not use InstallHook directly.  Use InstallSystemHook or InstallTaskHook. }
    function InstallHook(SystemHook: boolean; TaskHandle: THandle): boolean;implementationuses WinProcs;const
      HOOK_DLL = 'HOOKDLL.DLL';function InstallHook(SystemHook: boolean; TaskHandle: THandle): boolean; external HOOK_DLL;
    function RemoveHook: boolean;  external HOOK_DLL;
    function IsHookSet: boolean;   external HOOK_DLL;function InstallSystemHook: boolean;
    begin
      InstallHook(TRUE, 0);
    end;function InstallTaskHook: boolean;
    begin
      InstallHook(FALSE,
                  {$IFDEF WIN32}
                    GetCurrentThreadID
                  {$ELSE}
                    GetCurrentTask
                  {$ENDIF}
                  );
    end;end.