Difference between revisions of "Delphi Converter in Lazarus/zh CN"

From Free Pascal wiki
Jump to navigationJump to search
Line 151: Line 151:
  
 
[[Category:Lazarus]]
 
[[Category:Lazarus]]
[[Category:Delphi_Converter_in_Lazarus]]
+
[[Category:Delphi Converter in Lazarus]]

Revision as of 17:39, 3 May 2024

English (en) 中文(中国大陆)‎ (zh_CN)
Delphi 项目、Delphi 包和单个单元文件可以转换为 Lazarus。 这些条目可以在 Lazarus 的工具菜单中找到:

  • 将 Delphi 单元转换为 Lazarus 单元...
  • 将 Delphi 项目转换为 Lazarus 项目...
  • 将 Delphi 包转换为 Lazarus 包...

此外还有:

  • 将二进制 DFM 文件转换为文本 LFM 并检查语法...

这通常是不必要的,因为在转换单元时,DFM 表单文件总是会被转换。

转换

这里简要列出了不同的转换。具体细节请参见下面的部分。

单元文件

  • 所有单元源文件都会添加一个 {$mode delphi} 指令。这使得编译器支持的语言语法与 Delphi 完全一致。这是有意义的,因为我们毕竟是在转换 Delphi 程序。如果用户以后想要利用 {$mode objfpc} 的特性,可以手动进行必要的更改。
  • 如果表单文件被重命名和转换,{$R *.DFM} 会被替换为 {$R *.lfm}。如果目标是 Lazarus 和 Delphi,则会使用条件编译。
  • Uses 部分中的单元名称和包含的文件名会被修正以匹配文件系统中实际的大小写敏感名称。这对于大小写敏感的文件系统是必要的。
  • Uses 部分中的一些单元名称要么被替换,要么被移除。
  • 一些 Delphi 类型会被替换为 "回退" LCL 类型(与表单文件中的处理方式相同)。
  • 代码中调用的一些函数名称会被替换。

表单文件

  • 旧的 Delphi 版本使用二进制格式用于 .dfm 表单文件。它们总是被转换为 ASCII 文本格式。
  • .dfm 表单文件被重命名或复制到 .lfm 并根据需要进行转换。还有一个选项可以直接使用相同的 Delphi 表单文件。请参见下面的 目标 部分。
  • 未知的属性会被移除。
  • 一些 Delphi 类型会被替换为 "回退" LCL 类型(与单元文件中的处理方式相同)。
  • 可视容器内控件的 Top 和 Left 坐标偏移量调整。

设置对话框

从工具菜单中选择一个条目后,然后选择要转换的单元/项目/包,用户将看到一个设置对话框。 所有设置都保存在本地 Lazarus 配置目录中的 delphiconverter.xml 文件中。 对话框允许配置转换的许多细节:

  • 项目路径 显示所选路径。
  • 更改的文件制作备份 将原始文件保存到所选目录下的 ConverterBackup 目录中。
  • 在编辑器中保持转换后的文件打开。如果选中,转换后的单元文件在转换后保持打开状态。

对话框的其余设置将在下面介绍。

Delphi 转换器的设置对话框图片

目标

转换目标在设置对话框中定义。它可以是:

  • 跨平台 -- 用跨平台等效项替换 Windows 特定单元。
  • 支持 Delphi -- 尝试使单元与 Delphi 和 Lazarus 兼容,通过在 Uses 部分使用 {$IFDEF...}。Delphi 表单文件 .dfm 被复制到 Lazarus 表单文件 .lfm 并进行转换。
  • 使用相同的 DFM 表单文件 -- Delphi 表单文件 .dfm 也与 Lazarus 一起使用。除非需要,否则不对其进行修改,除非需要将二进制格式转换为 ASCII 文本格式。

然而,后来同时在 Delphi 和 Lazarus 中维护该文件是有问题的,因为组件具有略微不同的属性。

单元名称替换和移除

当 Uses 部分中列出的单元找不到时,它可以被替换或移除。 替换是可配置的,请参阅设置对话框中的 "单元替换"。空 "新名称" 表示移除。 例如,默认情况下,"Windows" 被替换为 "LCLIntf, LCLType, LMessages"。

替换支持正则表达式语法。例如:

  • ^Q(.+) --> $1

意味着匹配以 'Q' 开头、后跟任何内容的字符串,并保存 'Q' 后面的部分, 然后用保存的部分替换。本质上,这是在开头移除了 'Q'。

替换可以是交互式的或自动的。在交互式模式下,用户可以在应用替换之前编辑它们。

如果在替换后仍然缺少单元,用户将被询问它们。 然后,他可以选择将它们注释掉或搜索它们的单元路径。

Delphi 转换器的“未找到单元”对话框图片

未知属性移除

并非所有 Delphi 组件属性都在 LCL 组件中实现。这些属性可以被移除。LCL 中有一个系统,其中不存在的属性被注册,表单加载器会忽略它们。转换器也会自动或交互式地移除它们。 目前的交互式移除发生在用于组件类型替换的同一个对话框中(见下文)。属性也可以被替换,但通常不需要这样做。

类型替换

一些 Delphi 组件在 LCL 中不存在。许多第三方组件也仅存在于 Delphi 中。 这些类型可以用回退 LCL 类型替换。例如:

  • TCoolBar --> TToolBar。

这也是可配置的,请参阅设置对话框中的 "类型替换"。

这里支持与单元名称替换中使用的相同的正则表达式语法。

这些类型在 Pascal 源文件和表单文件 (.lfm) 中都会被替换。 替换也适用于嵌套的组件结构,其中被替换类型的组件具有也必须被替换的子组件。

原始组件和替换组件之间的不同属性可能会在转换后引起问题。 对于这个问题没有简单的解决方案。

最好的解决方案是制作更多与 Delphi 兼容的组件,并将所有第三方组件移植到 Lazarus。 由于这些潜在问题,类型转换总是交互式的。

Delphi 转换器的“修复 LFM”对话框图片

函数调用替换

源代码中的一些仅限 Windows 的函数调用可以被替换为功能上相似的 RTL / LCL 库函数调用。 这是可配置的,请参阅设置对话框中的 "函数替换"。

每个函数都定义了一个类别。可以通过类别启用或禁用替换。 例如,有一个 "UTF8Names" 类别用于与文件操作相关的函数。

替换的语法是:

  • FileExists --> FileExistsUTF8($1)

其中 ($1) 表示原始函数调用中的第一个参数用于替换函数。 还有更高级的语法可用。例如:

  • ShellExecute --> if $3 match ":/" then OpenURL($3); OpenDocument($3)

ShellExecute 可以映射到两个不同的 LCL 函数。关键字 "match" 后面的字符串再次是一个正则表达式。 如果匹配,则使用其后的替换项,否则使用下一个替换项。

坐标偏移

在 Delphi 和 Lazarus 中,当组件位于可视容器内时,Top 和 Left 坐标具有不同的含义。 在 Delphi 中,坐标是相对于容器的 Top 和 Left。 在 Lazarus 中,它们是相对于容器的客户端区域,不包括边框。 这对于 TGroupBox 来说是最明显的问题,因为它在边框上有标题文本。

从坐标中减去偏移量可以使表单布局看起来与在 Delphi 中相同。 偏移量在设置对话框的 "坐标偏移" 中定义。

问题

当 Delphi 程序包含未在 RTL/LCL 中移植的 Windows API 调用时,没有自动转换它的方法。 其他 Windows 特定技术,如 OLE,也会引起同样的问题。

数据库连接通常需要进行更改。要么 DB,要么连接组件不兼容。

另一个问题是某些库与 Delphi 库不兼容。例如,XML 的使用方式略有不同。也许转换器将来可以在这个领域进行改进。

如前所述,在 Lazarus/LCL 中不存在的 Delphi 组件即使被替换为回退组件类型也会引起问题,因为它们具有不同的属性。

然而,如果程序仅使用 VCL 类和函数,转换成功的几率很大。