If you're writing common code that's supposed to work on the FireMonkey and the VCL framework, occasionally, it might be useful to detect whether you're compiling for the FireMonkey or the VCL framework.

You can do so by using the $IF directive, together with the DECLARED function.

Using the DECLARED function, you can use any name (a type, a constant, a variable) that exists only within FireMonkey, and then decide you're on the FireMonkey framework. Alternatively, to detect the VCL framework, use a type/variable that exists only within the FireMonkey framework. Note that when detecting the frameworks, it is necessary to find a name that exists only within one framework, but not the other.

For example, any FireMonkey forms automatically uses the FMX.Types unit, and there's the FireMonkeyVersion constant there, that's not declared within the VCL framework, so we can use that to determine that the code is being compiled for FireMonkey.

{$IF DECLARED(FireMonkeyVersion)}
// We're compiling for FireMonkey...
{$ENDIF}

This code below detects if the code is being compiled for VCL.

{$IF DECLARED(TCustomFrame)}
// We're compiling for VCL
{$ENDIF}

In order for these to work, you need to place them anywhere else within your code after the uses clause.

Here's some names you can use within FireMonkey, and VCL, together with the unit name:

Framework Unit Type/Variable Name
FireMonkey Fmx.Types TFmxHandle
FireMonkey Fmx.Types FireMonkeyVersion
FireMonkey Fmx.Forms ActionUpdateDelayNever
FireMonkey Fmx.Graphics TGradientPoint
FireMonkey Fmx.Menus TStartMenuLoopMessage
FireMonkey FMX.ActnList IActionClient
VCL Vcl.Forms TControlScrollBar
VCL Vcl.Forms TCustomFrame
VCL Vcl.Graphics TCursorOrIcon
VCL Vcl.ActnList TActionList
VCL Vcl.Menus TMenuItem

What if the same name exists within VCL and FireMonkey? In that case, prefix the unit name then.

{$IF DECLARED(Vcl.ActnList.TActionList)}
  // This code is meant for VCL, when you have the Vcl.ActnList unit listed in your uses clause. 
  // Without the unit listed in your uses clause, this code will not be included.
{$ENDIF}
{$IF DECLARED(FMX.ActnList.TActionList)}
  // This code is meant for FMX, when you have the FMX.ActnList unit listed in your uses clause.  
  // Without the unit listed in your uses clause, this code will not be included.
{$ENDIF}

With the above information, now you can write code that can detect whether it's being compiled for FireMonkey or VCL, and act accordingly.