如何创建可与VCL和FMX配合使用的内部计时器?

时间:2015-09-15 09:14:14

标签: delphi timer firemonkey vcl delphi-10-seattle

我有一个需要计时器的课程。该课程必须同时使用VCL和FMX。不幸的是,FMX计时器在FMX.Types中声明,VCL计时器在Vcl.ExtCtrls中声明。

由于没有类似{$IFDEF FMX}xxx{$ENDIF}的条件定义,如何在跨平台类中使用计时器?

2 个答案:

答案 0 :(得分:4)

如果是我,我会编写一个独立于FMX和VCL框架的专用跨平台计时器类。从概念上讲,它将与Delphi RTL处于同一水平。

如果您不想这样做并想重新使用现有的计时器类,那么您就处于绑定状态。对于没有VCL的目标,你做什么?您无法知道FMX或VCL项目是否会使用您的代码。想一想。您可以将您的单位编译为.dcu并将其包含在任何项目中。在编译单元时,它无法知道最终会消耗它的项目类型。

那该怎么办?你可以在任何地方使用FMX计时器。但这迫使FMX进入VCL项目。我知道我不喜欢那样。您可以在Windows以外的任何地方使用FMX计时器,并在那里使用VCL计时器。但这迫使VCL进入Windows FMX项目。

所以你可以采用这种方法:

  1. 创建您自己的跨平台计时器类。
  2. 在Windows以外的平台上,在FMX计时器之上实现它。
  3. 在Windows上使用原始Windows API函数SetTimerKillTimer实现它。

答案 1 :(得分:1)

我们可以假设您的类是非可视的,而且它不是设计时组件。如果情况并非如此,则不会与FMX和VCL兼容。

在这种情况下,您无法在VCL应用程序中包含FMX.Types,并且没有理由不能创建FMX.Types.TTimer VCL应用程序 - 您无法在设计时执行此操作(即:在VCL表单上删除FMX TTimer)。如果您只需要内部定时器,那么答案很明确 - 只需使用FMX定时器,因为无论平台目标还是正在使用的框架,它都会编译。

unit FMXTimerInVCLApplication;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  FMX.Types;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FTimer : TTimer;   // FMX.Types.TTimer !
    procedure foo(Sender : TObject);
  end;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FTimer := TTimer.Create(nil);
  FTimer.Interval := 1000;
  FTimer.OnTimer := foo;
end;

procedure TForm1.foo(Sender : TObject);
begin
  ShowMessage('foo');
end;

end.

当然,这确实会为您的应用带来相当多的FMX行李。如果你关心那种事情,它对计时器来说会很臃肿。我把它作为另一个自然答案的替代品(写自己的答案)。