By Jens: Hooks, I’ve seen a lot of people trying to make a clean solution for hooking messages in an application. So I decided some time ago to implement hooks as a class, with nice events and stuff :)
Hook.pas makes it possible to assign a method pointer to a procedure pointer (with some help from assembler).
For example: if you want to trap ALL keystrokes in your application - simply declare an instance of TKeyboardHook, assign an event handler for OnPreExecute or OnPostExecute, or both. Set you KeyboadHook active (KeyboardHook.Active := True) and you are out and running ..
On Windows HooksHere's what the Windows API guide has to say on hooks:
A hook is a point in the system message-handling mechanism where an application can install a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure.
Put shortly, a hook is a function you can create as part of a dll or your application to monitor the 'goings on' inside the Windows operating system.
The idea is to write a function that is called every time a certain event in windows occurs - for example when a user presses a key on the keyboard or moves the mouse.
For a more in depth introduction to hooks, take a look at What Windows hooks are and how to use them within a Delphi application.
Types of HooksDifferent hook types enable an application to monitor a different aspect of the system's message-handling mechanism.
You can use the WH_KEYBOARD hook to monitor keyboard input posted to a message queue;
You can use the WH_MOUSE hook to monitor mouse input posted to a message queue;
You can a WH_SHELL hook procedure when the shell application is about to be activated and when a top-level window is created or destroyed.
Hooks.pasThe hooks.pas unit defines several hook types:
- TCBTHook - called before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the input focus; or before synchronizing with the system message queue.
- TDebugHook - called before calling hook procedures associated with any other hook in the system
- TGetMessageHook - enables an application to monitor messages about to be returned by the GetMessage or PeekMessage function
- TJournalPlaybackHook - enables an application to insert messages into the system message queue.
- TJournalRecordHook - enables you to monitor and record input events (to record a sequence of mouse and keyboard events to play back later by using the WH_JOURNALPLAYBACK Hook).
- TKeyboardHook - enables an application to monitor message traffic for WM_KEYDOWN and WM_KEYUP messages.
- TMouseHook - enables you to monitor mouse messages about to be returned by the GetMessage or PeekMessage function.
- TLowLevelKeyboardHook - enables you to monitor keyboard input events about to be posted in a thread input queue.
- TLowLevelMouseHook - enables you to monitor mouse input events about to be posted in a thread input queue.
TKeyboardHook exampleTo show you how to use the hooks.pas, here's a section of the keyboard hook demo application:
Download hooks.pas + demo application
Ready, set, hook :)
uses hooks, .... var KeyboardHook: TKeyboardHook; .... //MainForm's OnCreate event handler procedure TMainForm.FormCreate(Sender: TObject) ; begin KeyboardHook := TKeyboardHook.Create; KeyboardHook.OnPreExecute := KeyboardHookPREExecute; KeyboardHook.Active := True; end; //handles KeyboardHook's OnPREExecute procedure TMainForm.KeyboardHookPREExecute(Hook: THook; var Hookmsg: THookMsg) ; var Key: Word; begin //Here you can choose if you want to return //the key stroke to the application or not Hookmsg.Result := IfThen(cbEatKeyStrokes.Checked, 1, 0) ; Key := Hookmsg.WPARAM; Caption := Char(key) ; end;