德尔福DFM文件中的奇怪[数字] - 起源和必要性?

时间:2012-06-06 14:29:28

标签: delphi rename dfm

我需要将一个包中定义的大量Delphi组件更改为另一个包中的类似组件。 可以通过替换DFM文件中的文本(组件类型和属性)来完成大部分繁琐的工作 - 当然是保存为文本。

我搜索过Stackoverflow和Google,现在我正在调整http://www.felix-colibri.com/papers/colibri_utilities/dfm_parser/dfm_parser.html

中的Felix Colibri DFM解析器

我遇到了解析器窒息的DFM文件中的“功能”:类型规范之后的[number] s:

inherited DialoogEditAgenda: TDialoogEditAgenda
  ActiveControl = PlanCalendar
  Caption = 'Agenda'
  [snip]
  inherited PanelButtons: TRzPanel
    Top = 537
    [snip]
    inherited ButtonCancel: TRzBitBtn [0]  <== *here*
      Left = 852
      [snip]
    end
    object CheckBoxBeschikbaarheid: TRzCheckBox [1]  <== *here*
      Left = 8
      [snip]
    end
    inherited ButtonOK: TRzBitBtn [2]  <== *here*
      Left = 900
      [snip]
    end
  end
  inherited PageControl: TRzPageControl
    Left = 444
    [snip]
  end
  object PanelBeschikbaarheid: TRzSizePanel [2]  <== *here*
    Left = 967
    [snip]
  end
  object PanelScheduler: TRzPanel [3]  <== *here*
    Left = 23
    Top = 22
    [...]

其中许多DFM都是大量继承的(我必须为此修改Colibri的代码),但是一个带继承的小型测试应用程序无法在DFM中生成[数字]。

我必须扩展解析器代码之前的问题:有没有人知道这些[数字]的来源,因此,我可以在解析DFM文件之前删除它们吗?

由于

2 个答案:

答案 0 :(得分:37)

这些数字并非完全没用。假设您有TATBTCTBTC来自TA。 DFM看起来像:

object A: TA
  object X: TX
  end
end

inherited B: TB
  object Y: TY
  end
end

inherited C: TC
  object Y: TY [0]
  end
  inherited X: TX [1]
  end
end

BC的不同之处在于,XY子组件的顺序相反。子组件顺序的确切含义取决于组件(见下文),但最值得注意的是,如果它们是TWinControl后代,或者它们都是TControl后代,而不是TWinControl ,这意味着它们在X上显示YY上显示X时会有所不同。

删除这些数字可能会改变表格,因此您不应盲目地这样做。但是,根据您的目标,您可以修改解析器(源代码似乎可用)以简单地跳过这些数字。

组件的相对顺序通常一般不重要,但也有一些例外。要更详细地解释一下:

对于普通控件,子组件以(1)TControl后代开头,后代不是从TWinControl派生,然后是(2)TWinControl后代,最后是(3)任何非{ {1}}组件。在每个组件中,组件的相对顺序是可调的:对于控件,“Bring to front”和“Send to back”尽可能地移动控件,其中非TControl永远不能放在TWinControl之后。对于非控件,(略微错误名称)“创建订单”选项允许您更改订单。所以,假设您有两个标签(A和B),两个编辑控件(C和D),以及一个数据集和数据源(E和F),您可以获得订单,例如,ABCDEF,BACDEF,ABDCFE ,但不是ACBDEF。

保存到DFM文件时保留该顺序:当不使用可视继承时,组件只是按顺序保存和重新加载。当您使用继承时,DFM文件将被处理为基于派生的,因此在上述情况下,创建TWinControl时,其TC成员始终创建<{1}} { {1}}成员。在组件顺序重要的情况下,需要XY来告诉Delphi RTL以后修复订单。

组件顺序实际上取决于组件类型。正如“Bring to front”/“Send to back”名称所示,控件使用组件顺序来指定Z顺序。对于其他组件类型,它意味着组件想要它的意思。例如,菜单可以使用组件顺序指定其菜单项的顺序(从上到下)。工具栏控件可以使用组件顺序指定工具栏按钮的顺序,即使这些工具栏按钮本身不是控件。数据集使用组件顺序来指定字段顺序,从而使用[0]中的默认列顺序。

答案 1 :(得分:0)

我最近写了一个DFM解析器,它支持这些类型的索引。它是用Go语言编写的,可以生成类似于Delphi的DFM文件。

https://github.com/gonutz/dfm

它已经针对RAD Studio源文件和我们自己的生产代码进行了测试,并且可以解析所有文件并逐字节生成文件。目的是提供一种简单的方法来更改DFM树并生成类似于RAD Studio创建的输出。