针对FMX或VCL有条件地编译单元

9

我希望在编译FMX或VCL时,在uses子句中使用不同的单位列表。在下面的代码中,我试图测试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.

只是一个小提示:VCL.TLabel有一个Caption属性,而不是Text。 - Tuncay Göncüoğlu
1个回答

12

FireMonkeyVersion 不是编译器定义的值,而是在 FMX.Types 模块中声明的一个命名常量。请尝试使用 {$IF DECLARED(FireMonkeyVersion)}

{$DEFINE HAS_VCL}
{$IF DECLARED(FireMonkeyVersion) AND (FireMonkeyVersion >= 16)}
  {$UNDEF HAS_VCL}
  {$DEFINE HAS_FMX}
{$IFEND}

但我不认为有必要检查它的数字值。你要么拥有FireMonkey,要么没有:

{$IF DECLARED(FireMonkeyVersion)}
  {$DEFINE HAS_FMX}
{$ELSE}
  {$DEFINE HAS_VCL}
{$IFEND}

话虽如此,要记住,在同一个项目中混合使用FireMonkey和VCL是可能的(尽管没有官方支持)。因此,您可能需要重新考虑通过区分框架来完成的任何任务。


这个可行!非常感谢你的帮助。第二种形式已经足够了。至于为什么我需要它:我有几个非视觉库。在为FMX更新它们时,我注意到TBitmap在FMX.Types和VCL.Graphics中都有声明。因此,我正在尝试使这些库跨平台。该示例完全依赖于平台,但我需要进行视觉测试。我可以接受更好的方法。我有很多要转换的内容,并且将不得不使用FMX和VCL两者都使用的库一段时间。 - Arnold
1
我不理解这个。当我包含FMX.Types时,常量被声明,否则不会。那么这如何帮助确定我的单元是否被FMX或VCL项目使用?假设我的单元使用Vcl.Graphics,但在运行FMX时不应该使用它... - maf-soft
2
@maf-soft 我建议在每个项目的选项中定义一个自定义条件,然后对其进行 {$IFDEF} - Remy Lebeau
@LarsFosdal 不,它并不会。无论您是否使用.0都没有关系,比较1616.0$IF方面是相同的,并且一直如此。您可以使用小数来检查更新,但是您不需要.0来检查基本RTM版本。 - Remy Lebeau
看起来我错过了错误的实际根本原因,但是我确实遇到了你提供的示例中的错误:{$DEFINE HAS_VCL} {$IF DECLARED(FireMonkeyVersion)} {$IF FireMonkeyVersion >= 16} <-- "[dcc32 Error]: E2026 Constant expression expected" {$UNDEF HAS_VCL} {$DEFINE HAS_FMX} {$IFEND} {$ENDIF}而这个可以正常工作:{$DEFINE HAS_VCL} {$IFDEF CONDITIONALEXPRESSIONS} {$IF DECLARED(FireMonkeyVersion) and (FireMonkeyVersion >= 16)} {$UNDEF HAS_VCL} {$DEFINE HAS_FMX} {$IFEND} {$ENDIF} - Lars Fosdal
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接