有条件地编译FMX或VCL的单位

Arn*_*old 7 delphi compiler-construction vcl delphi-xe2 firemonkey

我希望在uses子句中有不同的单元列表,具体取决于FMX或VCL的编译.在下面的代码中,我尝试测试FireMonkeyVersion哪个在FMX项目中工作(label1.Text是'FMX').当我将$ IF语句移动到uses子句中时,我收到一条错误消息([dcc32 Error] fmx_text.pas(7): E2026 Constant expression expected).有没有办法获得所需的条件编译?

unit fmx_text;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Types;
{$IF FireMonkeyVersion >= 16}
   {$DEFINE HAS_FMX}
{$ELSE}
   {$DEFINE HAS_VCL}
{$IFEND}

type

  TForm2 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.fmx}

procedure TForm2.FormCreate(Sender: TObject);
begin
   label1.Text := 'Undefined';
{$IFDEF HAS_FMX}
   label1.Text := 'FMX';
{$ENDIF}
{$IFDEF HAS_VCL}
   label1.Text := 'VCL';
{$ENDIF}
end;

end.
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 9

FireMonkeyVersion不是编译器定义的值.它是在FMX.Types单元中声明的命名常量.尝试使用{$IF DECLARED(FireMonkeyVersion)},例如:

{$DEFINE HAS_VCL}
{$IF DECLARED(FireMonkeyVersion) AND (FireMonkeyVersion >= 16)}
  {$UNDEF HAS_VCL}
  {$DEFINE HAS_FMX}
{$IFEND}
Run Code Online (Sandbox Code Playgroud)

但我没有理由检查其数值.你要么有FireMonkey,要么你没有:

{$IF DECLARED(FireMonkeyVersion)}
  {$DEFINE HAS_FMX}
{$ELSE}
  {$DEFINE HAS_VCL}
{$IFEND}
Run Code Online (Sandbox Code Playgroud)

说到这一点,请记住,在同一个项目中将FireMonkey和VCL混合在一起是可能的(尽管不是官方支持的).所以你可能需要通过区分框架来重新思考你想要完​​成的任何事情.

  • @maf-soft 我建议在每个项目的选项中定义一个自定义条件,然后在其上定义`{$IFDEF}`。 (2认同)