unit TTimerFWindowHandle;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  MyTTimer = class(TTimer)
    Timer1: TTimer;
  private
    { Private declarations }
    FInterval: Cardinal;
    FWindowHandle: HWND;
    FOnTimer: TNotifyEvent;
    FEnabled: Boolean;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure WndProc(var Msg: TMessage);
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  timer: MyTTimer;
begin
  timer := MyTTimer.Create(Form1);
end;

// BeginExample: TTimerFWindowHandle
// Routine: Classes.AllocateHWnd
// Routine: Classes.DeallocateHWnd
// Method: Forms.TApplication.HandleException

// BeginCode
{
The following code is from the implementation of TTimer. It
shows how the timer component’s constructor creates a hidden
window to respond to Timer messages and how the destructor
frees that window.
}
{
TTimer implements a WndProc method that becomes the window
procedure for the hidden window.
}
procedure MyTTimer.WndProc(var Msg: TMessage);
begin
  with Msg do
    if Msg = WM_TIMER then { check for timer messages }
      try
        Timer; { this calls the OnTimer event handler }
      except
        Application.HandleException(Self);
      end
    else
 { Any other messages are passed to DefWindowProc, which
 tells Windows to handle the message.
 Note that the first parameter, FWindowHandle, is the handle
 of the window receiving this message. It is obtained from the
 call to AllocateHWnd in the constructor. }
      Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
end;
{
The TTimer constructor uses AllocateHWnd to create the
window and save its handle.
}
constructor MyTTimer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FEnabled := True;
  FInterval := 1000;
  FWindowHandle := AllocateHWnd(WndProc);
end;

{ The TTimer destructor calls DeallocateHWnd to free the hidden window. }
destructor MyTTimer.Destroy;
begin
  FEnabled := False;
//  UpdateTimer; done by TTimer Destroy
  DeallocateHWnd(FWindowHandle);
  inherited Destroy;
end;
// EndCode
// EndExample: TTimerFWindowHandle
end.
