何时调用在表单上创建组件的代码以及设置其属性的代码?

Mar*_*unu 5 delphi components creation

如果我将一个组件放在表单上,​​我看不到任何像MyComp:=TMyComponent.Create单元代码中的代码。我认为该组件是自动创建的,但是什么时候?将组件放在表单上后配置的属性也会发生同样的情况。当它们在运行时应用时?

Dav*_*nan 4

表单的属性以及其上存在的所有设计时组件均在表单构建期间由框架流入。该过程是由表单的构造函数触发的,在TCustomForm.Create. 那里的相关代码如下所示:

Include(FFormState, fsCreating);
try
  if not InitInheritedComponent(Self, TForm) then
    raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);
finally
  Exclude(FFormState, fsCreating);
end;
Run Code Online (Sandbox Code Playgroud)

关键是调用InitInheritedComponent. Classes这是在执行繁重任务的单元中定义的函数。概括地说,它执行以下操作:

  1. 查找表单类的名称并查找RT_RCDATA该名称的资源。该资源是 .dfm 文件。
  2. 一旦找到 .dfm 资源,就会对其进行解析。
  3. .dfm 解析处理您在设计时在对象检查器中设置的属性的分配。例如,解析可能会遇到这样的行:Caption = 'My main form'并将其转换为将字符串分配'My main form'给表单的 property Caption
  4. .dfm 文件是分层的。它包含在设计时定义的各种组件和控件的属性。
  5. 除了设置表单设计时组件的属性外,.dfm 流处理还实例化这些组件。

为了使所有这些工作正常进行,流框架依赖于 RTTI。它在编译时对类和组件一无所知。因此需要 RTTI。流媒体框架使用旧式 RTTI,事实上这就是旧式 RTTI 存在的原因。如果您想知道为什么旧式 RTTI 是这样的,请尝试从设计用于支持流媒体的角度来看待它。