I need a Timer in a 'no form' Delphi unit (there's still a main unit with a form), so I do this:
unit ...
interface
type
TMyTimer = Class(TTimer)
public
procedure OnMyTimer(Sender: TObject);
end;
var
MyTimer: TMyTimer;
implementation
procedure TMyTimer.OnMyTimer(Sender: TObject);
begin
...
end;
initialization
MyTimer := TMyTimer.Create(nil);
with MyTimer do
begin
Interval := 1000;
Enabled := True;
OnTimer := OnMyTimer;
end;
finalization
FreeAndNil(MyTimer);
The problem is that the OnMyTimer procedure is never run. I'll truly appreciate any ideas as to why :-)
In order for a timer to work, your program must process messages. In a GUI program, that part is automatic; the TApplication
class provides that for you. But you say you have a "no form" program, so I suppose you're probably not calling Application.Run
in your DPR file.
To use a timer, you need to process messages. The typical starting point for a message pump is code like this:
while Integer(GetMessage(Msg, 0, 0, 0)) > 0 do begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
When a timer's period has elapsed, the OS effectively places a wm_Timer
message in your program's message queue. The GetMessage
call fetches messages from the queue, and DispatchMessage
calls the destination window's window procedure. TTimer
creates a hidden window for itself to serve as the target for those messages, and DispatchMessage
makes sure they get there.
Apart from the fact you created a MyTimer
and freed a MouseTimer
, I don't see anything wrong with your code (I do assume you use your code in a GUI application or at least are having a message loop)
This code sample works with Delphi 5. The Hello World
get's written to the eventlog every second.
unit Unit2;
interface
uses
extctrls;
type
TMyTimer = Class(TTimer)
public
procedure OnMyTimer(Sender: TObject);
end;
var
MyTimer: TMyTimer;
implementation
uses
windows, sysutils, classes;
procedure TMyTimer.OnMyTimer(Sender: TObject);
begin
OutputDebugString(PChar('Hello World'));
end;
initialization
MyTimer := TMyTimer.Create(nil);
with MyTimer do
begin
Interval := 1000;
Enabled := True;
OnTimer := OnMyTimer;
end;
finalization
FreeAndNil(MyTimer);
end.
Is your unit used by other units or not? If this unit isn't used by others it won't even get in the initialization section. Or maybe the unit is finalized sooner then you think.
Put a breakpoint at the MyTimer := TMyTimer.Create(nil); line and at the FreeAndNil(MyTimer) line and run your application. Make sure that the timer is created when you want it to and not destroyed too early.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With