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.
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.
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.
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.
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.