Conditional compilatation to detect VCL or FireMonkey in a Delphi Form

This shows how to detect if your application is using FireMonkey (FMX) or VCL when using conditional compilation within a Delphi form unit.

UPDATE – a better solution has been provided by a Rudy Velthuis.  I recommend to use that instead of my original post.  Ive provided examples based on his feedback.  Thanks Rudy

   -- Rudy Velthuis' updated solution
{$IF not declared(FireMonkeyVersion)}
     ShowMessage('VCL');
{$ELSE}
     ShowMessage('FMX');
{$IFEND}
-- Making it even simpler, this is the same code
-- with the "not" removed so the logic is flipped

{$IF declared(FireMonkeyVersion)}
  ShowMessage('FMX');
{$ELSE}
  ShowMessage('VCL');
{$IFEND}

 -- a handy function that can be used in regular code
 -- rather than conditional compilation
function IsFMX : boolean;
begin
 {$IF declared(FireMonkeyVersion)}
   result := TRUE;
 {$ELSE}
   result := FALSE;
 {$IFEND}
end;

The following is my original post

{$IF FMX.Types.FireMonkeyVersion >= 0} // if FireMonkey
     DoSomethingFMX;
{$ELSE}                  // its not FMX, so it must be VCL
     DoSomethingVCL;
{$ENDIF}

Can I Reverse the logic ?

No, reversing the logic does not work.  The reason for this is we are relying on the behaviour of Delphi conditional compile to return FALSE if the variable in the {$IF} does not exist.

To clarify … this  works correctly

{$IF FMX.Types.FireMonkeyVersion >= 0} // if FireMonkey
     ShowMessage ('FMX 1');
{$ELSE} // its not FMX, so it must be VCL
     ShowMessage ('VCL 1');
{$ENDIF}

But this does NOT work

     // DO NOT USE THIS - IT DOES NOT WORK
{$IF FMX.Types.FireMonkeyVersion < 0} // if VCL
     ShowMessage ('VCL 2');
{$ELSE}            // its not VCL, so it must be FMX
     ShowMessage ('FMX 2');
{$ENDIF}

What if I mix and match VCL and FMX ?

Although not officially supported, it is possible for a Delphi application to use both FireMonkey and VCL units.

It is possible to embed a FireMonkey form in a VCL application and vice versa using unsupported techniques.  However, I haven’t tested those scenarios with my conditional compilation code.  Maybe it will work, maybe not.  Ill leave it to you to look into it if you are interested.  Please post a comment here if you find anything interested.

Supported Versions of Delphi

The code has been tested on XE2 to XE10.1

+1 this post

I am trying to get this blog listed on DelphiFeeds.com
If you like this post, please +1 for me here on Delphi Feeds

and here on BeginEnd

Thank You !

About The Author

scott_circle
The Usual Suspect
– Scott Hollows –

  • Oracle and Delphi software developer.
  • Australian Delphi User Group – Western Australia Chief Cat Herder
  • Australian Delphi User Group – President
blogemaillinkedinlogo

Published by

6 responses to “Conditional compilatation to detect VCL or FireMonkey in a Delphi Form”

  1. Hi, how to do this in C++ Builder?

  2. There is a similar trick mentioned in Embarcadero’s own documentation:

    http://docwiki.embarcadero.com/RADStudio/en/IF_directive_(Delphi)

    “If the identifiers referenced in the conditional expression do not exist, the conditional expression will be evaluated as False:

    {$IF NoSuchVariable > 5}
    Writeln(‘This line doesn”t compile’);
    {$IFEND}

    You can use the FireMonkeyVersion constant (defined in FMX.Types.pas and equal to 16.1 at the XE2 Update 2 release) in an IF directive. To identify and separate FireMonkey code that is for any version higher than 16.0, surround the code with the following conditional directive:

    {$IF Declared(FireMonkeyVersion) and (FireMonkeyVersion > 16.0)}

    {$IFEND}

  3. Thanks!

    I found a way:

    #ifdef FMX.Types.FireMonkey Version> = 0
    #include
    #else
    #include
    #endif

  4. What about:

    {$IF not declared(FireMonkeyVersion)}
    DoSomethingVCL;
    {$ELSE}
    DoSomethingFMX;
    {$IFEND}

  5. Thanks – that works for me in VCL and FMX

    I think this is the best solution so far as it is more concise and does not have the issue of “reversing the logic does not work.” that I mentioned

    Im throwing in a Hello World so we have a copy / pasteable demo

    {$IF not declared(FireMonkeyVersion)}
    ShowMessage(‘VCL’);
    {$ELSE}
    ShowMessage(‘FMX’);
    {$IFEND}

  6. If you declare FMX.Types the Unit will be compiled as FMX otherwhise as VCL….
    Someone at this German-Forum suggested this instead
    https://www.delphipraxis.net/1376489-post6.html
    I’m trying to give you the translation: Create a file with the filename UserTools.proj in the %APPDATA% directory (For Tokyo thats %APPDATA%\Embarcadero\BDS\19.0 ) containing the XML-code below. This will enable you to detect the Framework used by the current project via
    {$IFDEF FrameWork_VCL}
    or
    {$IFDEF FrameWork_FMX}

    The XML code

    FrameWork_$(FrameworkType);$(DCC_Define)

    Should the file allread exist, you might have to sensible amend it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: