如何制作同时支持 FMX 和 VCL 的组件
How to make a component that support both FMX and VCL
这个问题已经有人问过了,但我仍然找不到好的方法。我刚刚制作了一个组件,它只是在 TForm 上绘制一些东西。基本上它是关于 FMX 或 VCL 的完全相同的代码,但在 fmx 上它使用 FMX.form 而在 vcl 上它使用 VCL.form.
- 如何让我的组件兼容这两个框架?理想情况下,我不想拆分单元(例如一个 FMX.myunit.pas 和一个 VCL.myUnit.pas)
- 如何让我的组件仅在
VCL project
or FMX project
or[=25= 的工具面板中显示] 对于 both projects
?
- 如何在我的 dpr/dproj 中说我的项目使用 VCL 或 FMX 框架?一个项目可以同时使用Framework、VCL和FMX吗?
- 对于 fmx 组件,为什么我需要做
RegisterComponents('myGroup', [TMyControl]);
后跟 RegisterFmxClasses([TMyControl]);
(我看到的所有示例都是这样)。
I just made a component who simply draw some stuff on a TForm.
UI 控件根本不应在窗体上绘制。它应该利用 VCL/FMX 框架提供给它的 Canvas
,例如在重写的 Paint()
方法中。
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)
您不需要在自己的单元中使用单元范围,除非您跨包共享单元并希望区分它们。
如果您不为每个框架创建单独的单元,那么在使用特定于框架的编码时,您将需要IFDEF
根据需要创建单元。
如果您编写完全与框架无关的代码,那么一个包可用于两个框架。但是,如果您需要编写特定于框架的代码(即,由于 UI 代码等),则需要为每个框架制作单独的包。
至于组件本身,如果你走 IFDEF 路线,那么如果可能的话,尝试从两个框架中都存在的基础 class 派生你的组件。
对于非可视组件,派生自 TComponent
,它在两个框架中的行为完全相同。
对于视觉控件,根据需要派生自 TControl
或后代。请注意,每个框架实现视觉控件的方式有所不同,因此您可能需要 IFDEF
相应地编写您的实现代码,或者为每个框架使用单独的单元。
How to make my component appear in the tools palette only for VCL project or only for FMX project or for both projects ?
一个包可以对特定框架有亲和力(见下文)。
如果它指定了一个特定的框架,那么这是它会出现的唯一框架。如果它没有指定一个框架,那么它将对两个框架都可用。
当你注册一个UI控件时,你应该调用GroupDescendentsWith()
将你的控件分组到TControl
的class组,例如:
RegisterComponents('My Control', [TMyControl]);
GroupDescendentsWith(TMyControl, TControl);
不要在此调用或您的 uses
子句中完全限定 TControl
的单元范围。仅使用 Controls
单元,让编译器在 FMX.Controls.TControl
或 Vcl.Controls.TControl
之间进行选择,具体取决于哪个版本的 TControl
可用,具体取决于您的包正在为哪个框架编译。
How in my dpr/dproj can I say that my project use VCL or FMX framework?
在.dproj
中,在第一个<PropertyGroup>
中,有一个<FrameworkType>
元素可用(如果缺少则添加),可以设置为[=28] =]、FMX
或 None
.
Can a project use both Framework, VCL and FMX?
不是官方,不是。但是,有 非官方 方法(即第 3 方解决方案)可以做到这一点。我不建议在包内这样做,只能在应用程序内这样做。
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).
真正要做的就是将 TMyControl
分组到 TFmxObject
class 组,这仅在 FMX 框架处于活动状态时可用。它只是用于过滤 IDE 中组件显示的另一个组。将 UI 控件分组到 TControl
class 组可以完成同样的事情。
这个问题已经有人问过了,但我仍然找不到好的方法。我刚刚制作了一个组件,它只是在 TForm 上绘制一些东西。基本上它是关于 FMX 或 VCL 的完全相同的代码,但在 fmx 上它使用 FMX.form 而在 vcl 上它使用 VCL.form.
- 如何让我的组件兼容这两个框架?理想情况下,我不想拆分单元(例如一个 FMX.myunit.pas 和一个 VCL.myUnit.pas)
- 如何让我的组件仅在
VCL project
orFMX project
or[=25= 的工具面板中显示] 对于both projects
? - 如何在我的 dpr/dproj 中说我的项目使用 VCL 或 FMX 框架?一个项目可以同时使用Framework、VCL和FMX吗?
- 对于 fmx 组件,为什么我需要做
RegisterComponents('myGroup', [TMyControl]);
后跟RegisterFmxClasses([TMyControl]);
(我看到的所有示例都是这样)。
I just made a component who simply draw some stuff on a TForm.
UI 控件根本不应在窗体上绘制。它应该利用 VCL/FMX 框架提供给它的 Canvas
,例如在重写的 Paint()
方法中。
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)
您不需要在自己的单元中使用单元范围,除非您跨包共享单元并希望区分它们。
如果您不为每个框架创建单独的单元,那么在使用特定于框架的编码时,您将需要IFDEF
根据需要创建单元。
如果您编写完全与框架无关的代码,那么一个包可用于两个框架。但是,如果您需要编写特定于框架的代码(即,由于 UI 代码等),则需要为每个框架制作单独的包。
至于组件本身,如果你走 IFDEF 路线,那么如果可能的话,尝试从两个框架中都存在的基础 class 派生你的组件。
对于非可视组件,派生自 TComponent
,它在两个框架中的行为完全相同。
对于视觉控件,根据需要派生自 TControl
或后代。请注意,每个框架实现视觉控件的方式有所不同,因此您可能需要 IFDEF
相应地编写您的实现代码,或者为每个框架使用单独的单元。
How to make my component appear in the tools palette only for VCL project or only for FMX project or for both projects ?
一个包可以对特定框架有亲和力(见下文)。
如果它指定了一个特定的框架,那么这是它会出现的唯一框架。如果它没有指定一个框架,那么它将对两个框架都可用。
当你注册一个UI控件时,你应该调用GroupDescendentsWith()
将你的控件分组到TControl
的class组,例如:
RegisterComponents('My Control', [TMyControl]);
GroupDescendentsWith(TMyControl, TControl);
不要在此调用或您的 uses
子句中完全限定 TControl
的单元范围。仅使用 Controls
单元,让编译器在 FMX.Controls.TControl
或 Vcl.Controls.TControl
之间进行选择,具体取决于哪个版本的 TControl
可用,具体取决于您的包正在为哪个框架编译。
How in my dpr/dproj can I say that my project use VCL or FMX framework?
在.dproj
中,在第一个<PropertyGroup>
中,有一个<FrameworkType>
元素可用(如果缺少则添加),可以设置为[=28] =]、FMX
或 None
.
Can a project use both Framework, VCL and FMX?
不是官方,不是。但是,有 非官方 方法(即第 3 方解决方案)可以做到这一点。我不建议在包内这样做,只能在应用程序内这样做。
For fmx components, why I need to do
RegisterComponents('myGroup', [TMyControl]);
followed byRegisterFmxClasses([TMyControl]);
(It's look like this in all sample I saw).
真正要做的就是将 TMyControl
分组到 TFmxObject
class 组,这仅在 FMX 框架处于活动状态时可用。它只是用于过滤 IDE 中组件显示的另一个组。将 UI 控件分组到 TControl
class 组可以完成同样的事情。