...trap Windows Messages in a Component?
Author: Thomas Stutz
{
  TApplication includes a method called HookMainWindow that allows you to
  insert your own message handler at the top of WndProc to intercept messages sent
  to your application before they're handled by the Application object.
  HookMainWindow() is declared under TApplication as follows:
}
procedure HookMainWindow(Hook : TWindowHook);
{
  HookMainWindow() takes one parameter (Hook of type TWindowHook).
  TWindowHook is a method pointer type that's defined like so:
}
type
  TWindowHook = function(var Message : TMessage) : Boolean of object;
{
  Since TWindowHook is a method pointer, you can define your own method as
  the hook function as long as it follows the nomenclature defined for TWindowHook.
  The return value of the function is of type Boolean.
  This is the equivalent of the "Handled" parameter of OnMessage.
  If your function handles a particular message, you'd return true.
  This will be passed back to the Application's WndProc and message processing for that
  message will be terminated. Otherwise, you'd return False.
  The Component "MessageReceiver" intercepts user-definded messages
  (> WM_USER) und as example the message WM_TIMECHANGE.
}
{*************************************************************************}
{
  TApplication besitzt eine Methode HookMainWindow.
  Damit kann man in die Windows Prozedur (WndProc) "einhaken" und Nachrichten,
  welche an die Applikation geschickt werden, abfangen und behandeln.
  HookMainWindow is wie folgt deklariert:
}
procedure HookMainWindow(Hook : TWindowHook);
{ Und der Parameter TWindowHook (Methoden Pointer) so: }
type
  TWindowHook = function(var Message : TMessage) : Boolean of object;
{
  Der Rückgabewert der Funktion ist vom Type Boolean.
  Dieser enspricht dem "Handled" Parameter von OnMessage.
  Wenn nun eine bestimmte Nachricht behandlet wird, kann True zurückgegeben
  werden, sonst False.
  Die Komponente "MessageReceiver" fängt einerseits benuterdefinierte Nachrichten
  (> WM_USER) und als Beispiel die Nachricht WM_TIMECHANGE ab.
  Im OnCreate() wird Application.HookMainWindow aufgerufen und im OnDestroy() dann
  - falls nötig - Application.UnhookMainWindow.
}
{*************************************************************************}
unit MessageReceiver;
interface
uses
  Windows, Messages, SysUtils, Classes, Forms, Dialogs;
type
  TOnReceiveUserMessage = procedure(Msg: Cardinal; wParam, lParam: Integer;
    var Handled: Boolean) of object;
  TOnReceiveOtherMessage = procedure(var Handled: Boolean) of object;
  TMessageReceiver = class(TComponent)
  private
    { Private declarations }
    FHooked: Boolean;
    FOnReceiveUserMessage: TOnReceiveUserMessage;
    FOnDateTimeChange: TOnReceiveOtherMessage;
    function MessageHook(var Msg: TMessage): Boolean;
  protected
    function DoDateTimeChange(Msg: TMessage): Boolean; dynamic;
    function DoUserMessage(Msg: TMessage): Boolean; dynamic;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property OnDateTimeChange: TOnReceiveOtherMessage
      read FOnDateTimeChange write FOnDateTimeChange;
    property OnReceiveUserMessage: TOnReceiveUserMessage
      read FOnReceiveUserMessage write FOnReceiveUserMessage;
  end;
 Â
procedure Register;
implementation
procedure Register;
begin
  RegisterComponents('System', [TMessageReceiver]);
end;
function TMessageReceiver.MessageHook(var Msg: TMessage): Boolean;
begin
  Result := False;
  // User defined messages
  if (Msg.Msg >= WM_USER) then
    Result := DoUserMessage(Msg)
  else
    // Other messages
    case Msg.Msg of
      WM_TIMECHANGE: Result := DoDateTimeChange(Msg);
      // ...
    end;
end;
function TMessageReceiver.DoDateTimeChange(Msg : TMessage): Boolean;
begin
  Result := False;
  if Assigned(FOnDateTimeChange) then
    FOnDateTimeChange(Result);
end;
function TMessageReceiver.DoUserMessage(Msg: TMessage): Boolean;
begin
  Result := False;
  if Assigned(FOnReceiveUserMessage) then
    FOnReceiveUserMessage(Msg.Msg, Msg.wParam, Msg.LParam, Result);
end;
constructor TMessageReceiver.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FHooked := False;
  if not (csDesigning in ComponentState) then
  begin
    Application.HookMainWindow(MessageHook);
    FHooked := True;
  end;
end;
destructor TMessageReceiver.Destroy;
begin
  if FHooked then Application.UnhookMainWindow(MessageHook);
  inherited Destroy;
end;
end.
printed from
www.swissdelphicenter.ch
developers knowledge base