About the author
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:
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.
Continued discussion of undocumented Delphi 8 Property Access Specifiers, and other ways of adding and removing delegates / events handlers, including clearing the list of all the delegates / event handlers.
This article discusses the new Delphi 8 property access specifiers.
A method pointer is now the same as a global procedure, ie, procedure of object = procedure.