Delphi: событие OnTimer моего собственного таймера никогда не происходит - PullRequest
7 голосов
/ 14 апреля 2010

Мне нужен Таймер в блоке Delphi «без формы» (есть еще основной блок с формой), поэтому я делаю это:

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);

Проблема в том, что процедура OnMyTimer никогда не запускается. Я буду очень признателен за любые идеи о том, почему: -)

Ответы [ 3 ]

9 голосов
/ 14 апреля 2010

Чтобы таймер работал, ваша программа должна обрабатывать сообщения . В программе с графическим интерфейсом эта часть является автоматической; класс TApplication обеспечивает это для вас. Но вы говорите, что у вас есть программа «без формы», поэтому я полагаю, что вы, вероятно, не вызываете Application.Run в своем файле DPR.

Чтобы использовать таймер, вам нужно обрабатывать сообщения. Типичной отправной точкой для рассылки сообщений является код, подобный следующему:

while Integer(GetMessage(Msg, 0, 0, 0)) > 0 do begin
  TranslateMessage(Msg);
  DispatchMessage(Msg);
end;

По истечении периода таймера ОС фактически помещает сообщение wm_Timer в очередь сообщений вашей программы. Вызов GetMessage извлекает сообщения из очереди, а DispatchMessage вызывает оконную процедуру окна назначения. TTimer создает для себя скрытое окно, которое будет служить целью для этих сообщений, а DispatchMessage обеспечивает их получение.

6 голосов
/ 14 апреля 2010

Кроме того, что вы создали MyTimer и освободили MouseTimer, я не вижу ничего плохого в вашем коде (я предполагаю, что вы используете свой код в приложении с графическим интерфейсом или, по крайней мере, имеете цикл сообщений)

Этот пример кода работает с Delphi 5. Hello World get записывается в журнал событий каждую секунду.

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.
1 голос
/ 14 апреля 2010

Ваш юнит используется другими юнитами или нет? Если этот блок не используется другими, он даже не попадет в раздел инициализации. Или, возможно, устройство будет завершено раньше, чем вы думаете.

Поместите точку останова в MyTimer: = TMyTimer.Create (nil); и на линии FreeAndNil (MyTimer) и запустите ваше приложение. Убедитесь, что таймер создан, когда вы этого хотите, и не уничтожен слишком рано.

...