Delphi XE2: Is there a predefined conditional to identify VCL and FireMonkey?

时光毁灭记忆、已成空白 提交于 2019-11-30 08:48:07

As others says, there is not a conditional directive to determine if your application is VCL or FireMonkey. I think the most reliable way to determine if your app is FireMonkey or VCL is using a function instead of a conditional directive.

Something like

Uses
 Rtti;

function IsVCLApp:Boolean;
begin
 Result:= CompareText(TRttiContext.Create.GetType(TApplication.ClassInfo).QualifiedName,'Vcl.Forms.TApplication')=0;
end;

function IsFireMonkeyApp:Boolean;
begin
 Result:= CompareText(TRttiContext.Create.GetType(TApplication.ClassInfo).QualifiedName,'FMX.Forms.TApplication')=0;
end;
Robert Love

Although not documented you can have VCL and Firemonkey in the same application.

There is no compiler define.

If you're building something that needs to be both VCL and Firemonkey I would recommend separation of the units.

A possible way:

  • MyLibrary.X.pas - Common Code that both VCL, and Firemonkey would uses.
  • MyLibrary.Vcl.X.Pas - Vcl Specific Code
  • MyLibrary.Fmx.X.Pas - Fmx Specific Code

Mixing UI code from two different frameworks in the same unit is not a good idea. It will link in the other library when it's not needed.

There is no compiler directive because technically there is no such thing as a firemonkey application or a vcl application. Only applications which make use of these technologies. An application can use fxm or vcl or both or neither (eg. a console app). This is a bit like asking if it is an SQL application. You can of course programatically check the ancestry of individual forms to see which framework they inherit from. Again, inside a unit that has no associated form, this has no meaning.

There does not seem to be a compiler define specifically for VCL/FireMonkey. You would need to create your own.

A list of predefined conditionals can be found in the documentation.

Abbrevia supports both the VCL and CLX using this kind of split:

QAbUnit1.pas:

{$DEFINE UsingCLX}
unit QAbUnit1;
{$I AbUnit1.pas}

AbUnit1.pas:

{$IFNDEF UsingCLX}
{$DEFINE UsingVCL}
unit AbUnit1;
{$ENDIF}

type
  ...
  TMyWidget = class({$IFDEF UsingVCL}TWinControl{$ENDIF}
                    {$IFDEF UsingCLX}TWidgetControl{$ENDIF})
  ...
  end;

end.

To add FireMonkey support, I'd add a file like this:

FmxAbUnit1.pas:

{$DEFINE UsingFMX}
unit FmxAbUnit1;
{$I AbUnit1.pas}
{$ENDIF}

and then make whatever conditional changes I need to AbUnit1.pas.

It's not a nice clean split like Robert's suggestion, but the advantage is that all of your editing occurs in a single file, and the conditional define is handled automatically, so it doesn't need to appear in the project options. Who ever uses your library just includes the appropriate unit to decide which one they want to use. You could probably take advantage of unit scoping too, by naming the files Fmx.AbUnit1.pas and Vcl.AbUnit1.pas, but I think Embarcadero discourages that.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!