Arnold
Arnold

Reputation: 4840

Conditionally compile units for FMX or VCL

I want to have a different list of units in the uses clause depending on compiling for FMX or VCL. In the code below I try to test FireMonkeyVersion which works in an FMX project (label1.Text is 'FMX'). When I move the $IF statement into the uses clause I get an error message ([dcc32 Error] fmx_text.pas(7): E2026 Constant expression expected). Is there any way to get the desired conditional compilation?

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.

Upvotes: 10

Views: 7512

Answers (2)

IceCold
IceCold

Reputation: 21124

According to the documentation:

The following conditionals are available as of RAD Studio 11.1:
FRAMEWORK_VCL   Defined if the project uses VCL framework.
FRAMEWORK_FMX   Defined if the project uses FMX framework.

I think they should have been defined since FMX 1.0. But hey! Better (very) late than never. Right?


If you don't have Delphi 11 (and up) you can manually define FRAMEWORK_VCL/FRAMEWORK_FMX in your Project Options or even in the IDE -> Tools -> Settings IF you do only one type of projects (VCL/FMX).

As a precaution, put this code into one of your packages to remind you (or whomever uses your code) to remove the manually defined symbols when you upgrade to Delphi 11:

// Delphi 11.1 = CompilerVersion 35.0
{$IF CompilerVersion >= 35.0} 
   {$WARNING 'Detected D11. Remove the compiler symbols from Project Options'}
{$ENDIF}

Update: This is Remy's answer changed to stay compatible with the new FRAMEWORK_FMX defined in D11:

{$IF DECLARED(FireMonkeyVersion)}
  {$DEFINE FRAMEWORK_FMX}
{$ELSE}
  {$DEFINE FRAMEWORK_VCL}
{$IFEND}

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 595305

FireMonkeyVersion is not a compiler-defined value. It is a named constant declared in the FMX.Types unit instead. Try using {$IF DECLARED(FireMonkeyVersion)}, eg:

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

But I don't see a reason to check its numeric value. You either have FireMonkey or you do not:

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

With that said, do keep in mind that it is possible (though not officially supported) to mix FireMonkey and VCL together in the same project. So you might need to re-think whatever you are trying to accomplish by differentiating the frameworks.

Upvotes: 12

Related Questions