如何开发同时支持FMX和VCL双框架的通用组件及相关问题咨询
问题1:如何实现该组件同时兼容两个框架?理想情况不想拆分单元,例如分别提供
FMX.myunit.pas和VCL.myUnit.pas两个独立单元 用Delphi内置的条件编译指令即可实现同一单元兼容双框架:
- 首先在单元顶部的uses段用条件编译区分框架单元引用:
uses System.SysUtils, System.Classes, {$IFDEF FMX} FMX.Forms, FMX.Graphics; {$ELSE} Vcl.Forms, Vcl.Graphics; {$ENDIF}
- 对于两个框架中命名相同、功能一致的基类,可以用条件编译定义统一别名,后续核心逻辑直接使用别名即可,无需重复编码:
{$IFDEF FMX} type TBaseForm = FMX.Forms.TForm; TBaseCanvas = FMX.Graphics.TCanvas; {$ELSE} type TBaseForm = Vcl.Forms.TForm; TBaseCanvas = Vcl.Graphics.TCanvas; {$ENDIF}
- 极少数框架差异逻辑(比如绘制参数、坐标体系不同)也可以用条件编译包裹隔离,核心逻辑完全复用。编译组件包时分别对应VCL和FMX项目配置对应条件编译符号即可,无需拆分单元。
问题2:如何设置让组件在工具面板(Tools Palette)中仅对
VCL project可见、仅对FMX project可见,或是对两类项目都可见 给组件类附加ComponentPlatformsAttribute特性即可实现可见性控制:
- 仅对VCL项目可见:给组件类加
[ComponentPlatforms(pidVCL)] - 仅对FMX项目可见:给组件类加
[ComponentPlatforms(pidFMX)] - 对两类项目都可见:给组件类加
[ComponentPlatforms(pidVCL or pidFMX)]
IDE会自动读取这个特性,匹配当前打开的项目类型,决定是否在工具面板展示该组件。
问题3:在
.dpr/.dproj文件中如何指定项目使用VCL还是FMX框架?单个项目是否可以同时使用VCL和FMX两个框架 - 配置指定逻辑:
.dpr文件:uses段引用Vcl.Forms即为VCL项目,引用FMX.Forms即为FMX项目.dproj项目配置文件:通过<FrameworkType>节点指定,值为VCL或FMX
- 单个项目理论上可以同时引用两个框架,但官方不推荐这种用法:两个框架存在大量同名类(比如都有TForm、TButton),容易出现命名冲突,且两者的消息循环、资源管理逻辑不兼容,非常容易出现难以排查的运行时错误,仅做跨框架桥接工具时可以尝试,普通业务项目不要这么用。
问题4:开发FMX组件时,为什么所有示例代码都是先调用
RegisterComponents('myGroup', [TMyControl]);,之后还要调用RegisterFmxClasses([TMyControl]); 两个函数的作用完全不同:
RegisterComponents是Delphi IDE的通用组件注册接口,作用是把组件注册到工具面板,让开发者可以直接拖拽到窗体设计器上使用,VCL和FMX组件都需要调用这个函数。RegisterFmxClasses是FMX框架独有的序列化注册接口:FMX的窗体存储格式.fmx和VCL的.dfm序列化逻辑完全独立,自定义FMX组件如果不调用这个接口注册,IDE保存窗体、运行时加载窗体时都会识别不到该自定义类,抛出类未找到的错误,所以FMX组件必须额外调用这个注册函数。
内容的提问来源于stack exchange,提问作者zeus
相关产品推荐
相关产品推荐

