首页  编辑  

trap Windows Messages in a Component

Tags: /超级猛料/Message.消息和事件/   Date Created:

...trap Windows Messages in a Component?

{

 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.