开发者

Delphi: OnTimer event of my own Timer never happens

开发者 https://www.devze.com 2022-12-26 14:17 出处:网络
I need a Timer in a \'no form\' Delphi unit (there\'s still a main unit with a form), so I do this: unit ...

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开发者_C百科 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 Worldget'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.

0

精彩评论

暂无评论...
验证码 换一张
取 消