library TheHook;
uses
Windows,
Messages,
SysUtils;
{Define a record for recording and passing information process wide}
type
PHookRec = ^THookRec;
THookRec =
packed record
TheHookHandle : HHOOK;
TheAppWinHandle : HWND;
TheCtrlWinHandle : HWND;
TheKeyCount : DWORD;
end;
var
hObjHandle : THandle;
{Variable for the file mapping object}
lpHookRec : PHookRec;
{Pointer to our hook record}
procedure MapFileMemory(dwAllocSize : DWORD);
begin
{Create a process wide memory mapped variable}
hObjHandle := CreateFileMapping($FFFFFFFF,
NIL,
PAGE_READWRITE,
0,
dwAllocSize,
'
HookRecMemBlock');
if (hObjHandle = 0)
then begin
MessageBox(0,
'
Hook DLL',
'
Could not create file map object',
MB_OK);
exit;
end;
{Get a pointer to our process wide memory mapped variable}
lpHookRec := MapViewOfFile(hObjHandle,
FILE_MAP_WRITE,
0,
0,
dwAllocSize);
if (lpHookRec =
NIL)
then begin
CloseHandle(hObjHandle);
MessageBox(0,
'
Hook DLL',
'
Could not map file',
MB_OK);
exit;
end;
end;
procedure UnMapFileMemory;
begin
{Delete our process wide memory mapped variable}
if (lpHookRec <>
NIL)
then begin
UnMapViewOfFile(lpHookRec);
lpHookRec :=
NIL;
end;
if (hObjHandle > 0)
then begin
CloseHandle(hObjHandle);
hObjHandle := 0;
end;
end;
function GetHookRecPointer : pointer
stdcall;
begin
{Return a pointer to our process wide memory mapped variable}
result := lpHookRec;
end;
{The function that actually processes the keystrokes for our hook}
function KeyBoardProc(Code : integer;
wParam : integer;
lParam : integer): integer;
stdcall;
var
KeyUp : bool;
{Remove comments for additional functionability
IsAltPressed : bool;
IsCtrlPressed : bool;
IsShiftPressed : bool;
}
begin
result := 0;
case Code
of
HC_ACTION :
begin
if (wParam = WM_LBUTTONDOWN)
or (lparam=WM_LBUTTONDOWN)
then
begin
Inc(lpHookRec^.TheKeyCount);
PostMessage(lpHookRec^.TheCtrlWinHandle,
WM_KEYDOWN,
0,
0);
PostMessage(lpHookRec^.TheCtrlWinHandle,
WM_KEYUP,
0,
0);
end;
end;
{HC_ACTION}
HC_NOREMOVE :
begin
{This is a keystroke message, but the keystroke message}
{has not been removed from the message queue, since an}
{application has called PeekMessage() specifying PM_NOREMOVE}
result := 0;
exit;
end;
end;
{case code}
if (Code < 0)
then
{Call the next hook in the hook chain}
result :=
CallNextHookEx(lpHookRec^.TheHookHandle,
Code,
wParam,
lParam);
end;
procedure StartKeyBoardHook;
stdcall;
begin
{If we have a process wide memory variable}
{and the hook has not already been set...}
if ((lpHookRec <>
NIL)
AND
(lpHookRec^.TheHookHandle = 0))
then begin
{Set the hook and remember our hook handle}
lpHookRec^.TheHookHandle := SetWindowsHookEx(WH_MOUSE,
@KeyBoardProc,
hInstance,
0);
end;
end;
procedure StopKeyBoardHook;
stdcall;
begin
{If we have a process wide memory variable}
{and the hook has already been set...}
if ((lpHookRec <>
NIL)
AND
(lpHookRec^.TheHookHandle <> 0))
then begin
{Remove our hook and clear our hook handle}
if (UnHookWindowsHookEx(lpHookRec^.TheHookHandle) <> FALSE)
then
begin
lpHookRec^.TheHookHandle := 0;
end;
end;
end;
procedure DllEntryPoint(dwReason : DWORD);
begin
case dwReason
of
Dll_Process_Attach :
begin
{If we are getting mapped into a process, then get}
{a pointer to our process wide memory mapped variable}
hObjHandle := 0;
lpHookRec :=
NIL;
MapFileMemory(sizeof(lpHookRec^));
end;
Dll_Process_Detach :
begin
{If we are getting unmapped from a process then, remove}
{the pointer to our process wide memory mapped variable}
UnMapFileMemory;
end;
end;
end;
exports
KeyBoardProc
name '
KEYBOARDPROC',
GetHookRecPointer
name '
GETHOOKRECPOINTER',
StartKeyBoardHook
name '
STARTKEYBOARDHOOK',
StopKeyBoardHook
name '
STOPKEYBOARDHOOK';
begin
{Set our Dll's main entry point}
DLLProc := @DllEntryPoint;
{Call our Dll's main entry point}
DllEntryPoint(Dll_Process_Attach);
end.