delphi 如何制作同时支持FMX和VCL的组件

carvr3hs  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(315)

这个问题已经问过了,但我还是找不到一个好的办法。
我做了一个组件,它只是在TForm上绘制一些东西。基本上,它的代码与FMX或VCL完全相同,但在FMX上它使用FMX.Forms,而在VCL上它使用Vcl.Forms
1.如何使我的组件与两个框架兼容?理想情况下,我不想拆分单元(例如,一个FMX.myunit.pas和一个VCL.myUnit.pas)。
1.如何使我的组件仅出现在VCL project的“工具选项板”上,或仅出现在FMX project的“工具选项板”上,或出现在both projects的“工具选项板”上?
1.在我的.dpr/.dproj中,我如何才能说我的项目使用了VCL或FMX框架?一个项目可以同时使用VCL和FMX框架吗?
1.对于FMX组件,为什么我需要调用RegisterComponents('myGroup', [TMyControl]);,然后调用RegisterFmxClasses([TMyControl]);(在我看到的所有示例中都是这样的)。

lawou6xi

lawou6xi1#

我只是创建了一个组件,它只是在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.TControlVcl.Controls.TControl之间进行选择,这取决于TControl的版本(基于编译包的框架)。
在我的dpr/dproj中,我如何才能说我的项目使用了VCL或FMX框架?
.dproj中,在第一个<PropertyGroup>中,有一个<FrameworkType>元素可用(如果缺少,则添加它),该元素可以设置为VCLFMXNone
一个项目可以同时使用Framework、VCL和FMX吗?
不是 * 正式 *,不是。但是,有 * 非正式 * 的方式(即,第三方解决方案)来做到这一点。我不建议这样做的一个包内,只有在一个应用程序。
对于fmx组件,为什么我需要先执行RegisterComponents('myGroup', [TMyControl]);,然后执行RegisterFmxClasses([TMyControl]);(在我看到的所有示例中都是这样的)。
实际上所做的只是将TMyControl分组到TFmxObject类组中,该类组仅在FMX框架处于活动状态时可用。它只是用于在IDE中过滤组件显示的另一个组。将UI控件分组到TControl类组中也可以完成同样的任务。

相关问题