Home > Blockchain >  How to make a component that support both FMX and VCL
How to make a component that support both FMX and VCL

Time:09-23

The question have already been asked, but I still can't find a good way to do it. I just made a component who simply draw some stuff on a TForm. basically it's exactly the same code regarding FMX or VCL, but on fmx it's use FMX.form and on vcl it's use VCL.form.

  1. How to make my component compatible with both framework? Ideally I don't want to split the unit (one FMX.myunit.pas and one VCL.myUnit.pas for exemple)
  2. How to make my component appear in the tools palette only for VCL project or only for FMX project or for both projects ?
  3. How in my dpr/dproj can I say that my project use VCL or FMX framework? Can a project use both Framework, VCL and FMX?
  4. For fmx components, why I need to do RegisterComponents('myGroup', [TMyControl]); followed by RegisterFmxClasses([TMyControl]); (It's look like this in all sample I saw).

CodePudding user response:

I just made a component who simply draw some stuff on a TForm.

A UI control should not be drawing on the Form at all. It should be drawing on the Canvas that the VCL/FMX framework provides to it, such as in an overridden Paint() method.

How to make my component compatible with both framework? Ideally I don't want to split the unit (one FMX.myunit.pas and one VCL.myUnit.pas for exemple)

You don't need to use Unit Scopes in your own units, unless you are sharing units across packages and want to differentiate between them.

If you don't make separate units for each framework, then you will need to IFDEF the unit as needed when using framework-specific coding.

If you write purely framework-agnostic code, then a single package can be used for both frameworks. But if you need to write framework-specific code (ie, because of UI code, etc), then you will need to make separate packages for each framework.

As for the component itself, if you go the IFDEF route then try to derive your component from a base class that exists in both frameworks, if possible.

For non-visual components, derive from TComponent, it behaves the exact same in both frameworks.

For visual controls, derive from TControl or descendant as needed. Just note that there are differences in how each framework implements visual controls, so you will likely need to IFDEF your implementation code accordingly, or use separate units for each framework.

How to make my component appear in the tools palette only for VCL project or only for FMX project or for both projects ?

A package can have an affinity for a specific framework (see further below).

If it specifies a particular framework, then that is the only framework it will appear for. If it does not specify a framework, then it will be available for both frameworks.

When you register a UI control, you should call GroupDescendentsWith() to group your control to TControl's class group, eg:

RegisterComponents('My Control', [TMyControl]);
GroupDescendentsWith(TMyControl, TControl);

Don't fully qualify the Unit Scope for TControl, either in this call, or in your uses clause. Use just the Controls unit and let the compiler pick between FMX.Controls.TControl or Vcl.Controls.TControl depending on which version of TControl is available based on which framework your package is being compiled for.

How in my dpr/dproj can I say that my project use VCL or FMX framework?

In the .dproj, in the first <PropertyGroup>, there is a <FrameworkType> element available (add it if it is missing), which can be set to either VCL, FMX, or None.

Can a project use both Framework, VCL and FMX?

Not officially, no. But, there are unofficial ways (ie, 3rd party solutions) to do it. I would not recommend doing this inside a package, only inside an application.

For fmx components, why I need to do RegisterComponents('myGroup', [TMyControl]); followed by RegisterFmxClasses([TMyControl]); (It's look like this in all sample I saw).

All that is really doing is grouping TMyControl to the TFmxObject class group, which is only available when the FMX framework is active. It is just another grup used for filtering the display of components within the IDE. Grouping a UI control to the TControl class group accomplishes the same thing.

  • Related