首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在运行时创建和运行TTimer

在运行时创建和运行TTimer
EN

Stack Overflow用户
提问于 2018-04-03 18:45:46
回答 2查看 3.4K关注 0票数 3

我正试图在Delphi中实现类似于Javascript的setTimeout()过程的行为:在延迟几秒钟后运行。为此,我在运行时创建一个TTimer,运行它,然后释放它。

这是我的代码:

代码语言:javascript
复制
procedure createAndRunTimer();
  procedure goTimer(Sender: TObject);
  begin
    (sender as ttimer).enabled := false;
    // do stuff here
    sender.free;
  end;
var
  t : TTimer;
begin
  t := TTimer.Create(frmprinc);
  t.Interval := 5000;
  t.OnTimer := goTimer(t);
end;

但是我的代码无法编译,编译器将返回以下错误:

DCC错误单元1.PAS(2153):E2010不兼容类型:“TNotifyEvent”和“过程、非类型化指针或非类型化参数”

有什么暗示吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-03 19:18:05

TNotifyEvent声明为:

代码语言:javascript
复制
TNotifyEvent = procedure(Sender: TObject) of object;

of object使其成为一个闭包,它是一种特殊类型的方法指针,包含两个指针--一个指向对象的指针,以及一个指向在对象上调用的非静态类方法的指针。因此,不能直接将独立函数(当然不是嵌套函数)分配给TNotifyEvent。这正是编译器所抱怨的。

因此,您需要声明一个类来包装OnTimer事件处理程序,例如:

代码语言:javascript
复制
type
  TTimerEvents = class
  public
    procedure goTimer(Sender: TObject);
  end;

procedure TTimerEvents.goTimer(Sender: TObject);
begin
  (Sender as TTimer).Enabled := false;

  // do stuff here

  // NOTE: you cannot destroy the Sender object from here, you must delay
  // the destruction until after this handler exits!  You can post a
  // custom window message via PostMessage() and have the message handler
  // call Sender.Free().  Or, you can use a worker thread to call
  // Sender.Free() via TThread.Synchronize() (or TThread.Queue() in Delphi
  // 8 and later).  Or, in Delphi 10.2 Tokyo and later, you can call
  // Sender.Free() via TThread.ForceQueue().  Or, use whatever other
  // mechanism you want to use to call Sender.Free(), as long as it works
  // asynchronously and calls Sender.Free() in the same thread that
  // constructed the TTimer object ...
end;

var
  events: TTimerEvents;

procedure createAndRunTimer();
var
  t : TTimer;
begin
  t := TTimer.Create(frmprinc);
  t.Interval := 5000;
  t.OnTimer := events.goTimer;
  t.Enabled := True;
end;

initialization
  events := TTimerEvents.Create;
finalization
  events.Free;

或者,您可以使用class方法,这样就不需要包装类的实际实例:

代码语言:javascript
复制
type
  TTimerEvents = class
  public
    class procedure goTimer(Sender: TObject);
  end;

class procedure TTimerEvents.goTimer(Sender: TObject);
begin
  (Sender as TTimer).Enabled := false;

  // do stuff here

  // delay-destroy the Sender as needed ...
end;

procedure createAndRunTimer();
var
  t : TTimer;
begin
  t := TTimer.Create(frmprinc);
  t.Interval := 5000;
  t.OnTimer := TTimerEvents.goTimer;
  t.Enabled := True;
end;

或者,在Delphi 2006及更高版本中,您可以使用类帮助者

代码语言:javascript
复制
type
  TTimerHelper = class helper for TTimer
  public
    procedure goTimer(Sender: TObject);
  end;

procedure TTimerHelper.goTimer(Sender: TObject);
begin
  (Sender as TTimer).Enabled := false;

  // do stuff here

  // delay-destroy the Sender as needed ...
end;

procedure createAndRunTimer();
var
  t : TTimer;
begin
  t := TTimer.Create(frmprinc);
  t.Interval := 5000;
  t.OnTimer := t.goTimer;
  t.Enabled := True;
end;

尽管如此,还是有一种方法可以使用独立函数,而无需使用任何类包装器:

代码语言:javascript
复制
procedure goTimer(Self: Pointer; Sender: TObject);
begin
  (Sender as TTimer).Enabled := false;

  // do stuff here

  // delay-destroy the Sender as needed ...
end;

procedure createAndRunTimer();
var
  t : TTimer;
  event : TNotifyEvent;
begin
  t := TTimer.Create(frmprinc);
  t.Interval := 5000;

  TMethod(event).Data := nil; // or whatever you want to pass to the Self parameter...
  TMethod(event).Code := @goTimer;
  t.OnTimer := event;

  t.Enabled := True;
end;
票数 8
EN

Stack Overflow用户

发布于 2018-04-03 19:24:03

我使用Torry的这个过程作为延迟,它不会在执行时锁定线程:

代码语言:javascript
复制
procedure Delay(dwMilliseconds: Longint);
var
  iStart, iStop: DWORD;
begin
  iStart := GetTickCount;
  repeat
    iStop := GetTickCount;
    Application.ProcessMessages;
    Sleep(1);
  until (iStop - iStart) >= dwMilliseconds;
end;
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49637129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档