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.
- 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)
- How to make my component appear in the tools palette only for
VCL project
or only forFMX project
or forboth projects
? - 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?
- For fmx components, why I need to do
RegisterComponents('myGroup', [TMyControl]);
followed byRegisterFmxClasses([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 byRegisterFmxClasses([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.