1. Computing

THook Delphi Class with Source Code

Use Windows Hooks in your Delphi applications

From , former About.com Guide

Keyboard Hook Delphi example

Keyboard Hook Delphi example

Code submitted by Jens Borrisholt. Text by Zarko Gajic.

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 Hooks

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

Hooking mechanism relies on Windows messages and callback functions.

Types of Hooks

Different hook types enable an application to monitor a different aspect of the system's message-handling mechanism.

For example:
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.pas

The 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 example

To show you how to use the hooks.pas, here's a section of the keyboard hook demo application:

Download hooks.pas + demo application

 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;
 
Ready, set, hook :)

©2013 About.com. All rights reserved.