Как создать внутренний таймер, который будет работать с VCL и FMX?


У меня есть класс, который требует таймер. Класс должен работать как с VCL, так и с FMX. К сожалению, таймер FMX объявлен в FMX.Types, а таймер VCL-в Vcl.ExtCtrls.

Поскольку нет условного определения типа {$IFDEF FMX}xxx{$ENDIF}, как я могу использовать таймер в кроссплатформенном классе?

2 2

2 ответа:

Если бы это был я, я бы написал специальный кросс-платформенный класс таймера, который был бы независим от фреймворков FMX и VCL. Концептуально он будет находиться на том же уровне, что и Delphi RTL.

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

Так что же делать? Вы можете использовать таймер FMX везде. Но это заставляет FMX работать над проектами VCL. Я знаю, что мне бы это не понравилось. Вы можете использовать таймер FMX везде, кроме Windows, и использовать таймер VCL там. Но это вынуждает VCL на проекты Windows FMX.

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

  1. создайте свой собственный кросс-платформенный класс таймера.
  2. на платформах, отличных от Windows, реализуйте его поверх таймера FMX.
  3. в Windows реализуйте его с помощью функций raw Windows API SetTimer и KillTimer.

Мы можем предположить, что ваш класс не является визуальным и что, кроме того, он не является компонентом времени разработки. Если бы это было не так, то он не был бы в противном случае уже совместим как с FMX, так и с VCL.

В этом случае нет причины, по которой вы не можете включить FMX.Types в приложение VCL, и нет также причины, по которой вы не можете создать FMX.Types.TTimer в приложении VCL - вы просто не можете сделать это во время разработки (т. е.: поместите FMX TTimer на форму VCL). Если вам нужен только таймер внутренне, тогда ответ ясен - просто используйте таймер 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. Это слишком много для таймера, если вы заботитесь о таких вещах. Я представляю его как альтернативу другому естественному ответу (который заключается в написании вашего собственного).