【问题标题】:How to make a component that support both FMX and VCL如何制作同时支持 FMX 和 VCL 的组件
【发布时间】:2021-11-15 17:56:42
【问题描述】:

这个问题已经被问过了,但我仍然找不到一个好的方法。我刚刚制作了一个组件,它只是在 TForm 上绘制了一些东西。基本上它与 FMX 或 VCL 的代码完全相同,但在 fmx 上使用 FMX.form 而在 vcl 上使用 VCL.form。

  1. 如何使我的组件与这两个框架兼容?理想情况下,我不想拆分单元(例如一个 FMX.myunit.pas 和一个 VCL.myUnit.pas)
  2. 如何使我的组件仅针对VCL project 显示在工具面板中或仅针对FMX project 或针对both projects?
  3. 如何在我的 dpr/dproj 中说我的项目使用 VCL 或 FMX 框架?一个项目能否同时使用 Framework、VCL 和 FMX?
  4. 对于 fmx 组件,为什么我需要先做 RegisterComponents('myGroup', [TMyControl]); 后跟 RegisterFmxClasses([TMyControl]);(在我看到的所有示例中都是这样的)。

【问题讨论】:

  • 不是您基本问题的答案,但是... 组件不会直接在表单上绘制。组件在自己的窗口中绘制,该窗口是 TForm 或其他容器的子窗口。
  • 使用条件编译并包含文件。例如,查看ICS source code 以了解它是如何完成的。
  • @AndreasRejbrand 你真的认为我不知道吗?
  • @fpiette:我想你已经知道了,但是你的第一条评论不是很准确,所以为了其他人阅读这个 Q 的利益,我添加了一些细节。
  • "在 TForm 上画一些东西。基本上是完全相同的代码.."。也许您可以在此处发布该代码,以便有人为您制定解决方案?

标签: delphi firemonkey vcl


【解决方案1】:

我刚刚制作了一个组件,它只是在 TForm 上绘制一些东西。

UI 控件根本不应该在表单上绘制。它应该利用 VCL/FMX 框架提供给它的Canvas,例如在覆盖的Paint() 方法中。

如何使我的组件与这两个框架兼容?理想情况下,我不想拆分单元(例如一个 FMX.myunit.pas 和一个 VCL.myUnit.pas)

您不需要在自己的单元中使用单元范围,除非您在包之间共享单元并且想要区分它们。

如果您不为每个框架制作单独的单元,那么在使用框架特定编码时,您需要根据需要IFDEF 单元。

如果您编写纯粹与框架无关的代码,那么两个框架都可以使用一个包。但是如果你需要编写特定于框架的代码(即,因为 UI 代码等),那么你将需要为每个框架制作单独的包。

至于组件本身,如果您走 IFDEF 路线,那么如果可能,请尝试从两个框架中都存在的基类派生您的组件。

对于非可视组件,派生自 TComponent,它在两个框架中的行为完全相同。

对于视觉控件,根据需要从TControl 或后代派生。请注意,每个框架实现可视化控件的方式存在差异,因此您可能需要相应地IFDEF您的实现代码,或者为每个框架使用单独的单元。

如何让我的组件仅针对 VCL 项目或仅针对 FMX 项目或两个项目出现在工具面板中?

一个包可以与一个特定的框架有关联(见下文)。

如果它指定了一个特定的框架,那么它就是唯一会出现的框架。如果它没有指定框架,那么它对两个框架都可用。

当你注册一个UI控件时,你应该调用GroupDescendentsWith()将你的控件分组到TControl的类组中,例如:

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

不要在此调用或您的 uses 子句中完全限定 TControl 的单元范围。仅使用 Controls 单元,让编译器在 FMX.Controls.TControl 或 Vcl.Controls.TControl 之间进行选择,具体取决于哪个版本的 TControl 可用,具体取决于您的包正在编译的框架。

如何在我的 dpr/dproj 中说我的项目使用 VCL 或 FMX 框架?

在.dproj 中,在第一个<PropertyGroup> 中,有一个<FrameworkType> 元素可用(如果缺少则添加它),可以设置为VCL、FMX 或@987654342 @。

一个项目能否同时使用 Framework、VCL 和 FMX?

不是正式,不是。但是,有 非官方 方法(即,第 3 方解决方案)可以做到这一点。我不建议在包中执行此操作,仅在应用程序中执行此操作。

对于 fmx 组件,为什么我需要先做 RegisterComponents('myGroup', [TMyControl]); 后跟 RegisterFmxClasses([TMyControl]);(在我看到的所有示例中都是这样的)。

真正要做的就是将TMyControl 分组到TFmxObject 类组,这仅在FMX 框架处于活动状态时可用。它只是另一个用于过滤 IDE 中组件显示的 grup。将 UI 控件分组到 TControl 类组可以完成同样的事情。

【讨论】:

    猜你喜欢
    • 2016-11-28
    • 2021-11-08
    • 2012-12-16
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 2015-02-06
    • 2014-10-14
    • 2011-09-18
    相关资源
    最近更新 更多