【问题标题】:Delphi: OnTimer event of my own Timer never happensDelphi:我自己的 Timer 的 OnTimer 事件永远不会发生
【发布时间】:2010-04-14 06:09:00
【问题描述】:

我需要一个“无表单”Delphi 单元中的 Timer(仍然有一个带表单的主单元),所以我这样做:

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 程序永远不会运行。我真的很感激任何关于为什么的想法:-)

【问题讨论】:

    标签: delphi timer delphi-7


    【解决方案1】:

    为了让计时器工作,您的程序必须处理消息。在 GUI 程序中,该部分是自动的; TApplication 类为您提供。但是你说你有一个“无表单”程序,所以我想你可能没有在 DPR 文件中调用Application.Run

    要使用计时器,您需要处理消息。消息泵的典型起点是这样的代码:

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

    当计时器的时间过去后,操作系统会有效地将wm_Timer 消息放入程序的消息队列中。 GetMessage 调用从队列中获取消息,DispatchMessage 调用目标窗口的窗口过程。 TTimer 为自己创建一个隐藏窗口作为这些消息的目标,DispatchMessage 确保它们到达那里。

    【讨论】:

    • 经常创建消息循环只是为了使用计时器对我来说似乎有点过分了。您可以使用在线程和类似对象中更好地工作的其他机制。 WaitForSingle 对象例如等...
    • 当然。我本可以详细讨论 TTimer 的替代方案,但我决定将我的答案限制在手头的问题上。
    • 我没有不尊重的意思。我只是想,如果有人读到它,他们知道这一点。
    【解决方案2】:

    除了你创建了一个MyTimer 并释放了一个MouseTimer,我看不出你的代码有什么问题(我假设你在 GUI 应用程序中使用你的代码,或者至少有一个消息循环)

    此代码示例适用于 Delphi 5。Hello Worldget 每秒写入事件日志。

    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.
    

    【讨论】:

    • 我不知道为什么,但我通过重新排列 uses 部分中的单元(接口中的 ExtCtrls,实现中的 SysUtils 和 Windows)使其工作。去图:-)
    • Mikhail,我向您保证,单位的使用顺序对您的计划的成功没有影响。问题出在其他地方。
    【解决方案3】:

    您的单位是否被其他单位使用?如果这个单元不被其他人使用,它甚至不会进入初始化部分。或者,该单元可能比您想象的更快完成。

    在 MyTimer 处设置断点 := TMyTimer.Create(nil);行和 FreeAndNil(MyTimer) 行并运行您的应用程序。确保在您希望的时候创建计时器并且不要过早销毁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-08
      • 2018-02-20
      • 2016-09-07
      • 2011-11-19
      相关资源
      最近更新 更多