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