Delphi和Lazarus之间表单初始化的差异?

时间:2012-09-26 04:19:04

标签: delphi freepascal lazarus

MainForm在运行时创建一些辅助Frame对象以显示各种选项面板。

这里是其中一个框架类的典型构造函数(它们各自扩展了TFrame):

constructor Tframe2.Create(AOwner: TComponent);
begin
    inherited;
    edTime.Text := '12:00pm'; //edTime is a TEdit control. this line is where it throws the exception
    //etc.
end;

这段代码在Delphi中运行良好(无论是否是正确的方法),但是Lazarus中的相同代码不断抛出EInvalidOperation异常,因为控件(TEdit)没有父"窗口&# 34;已分配(rsControlHasNoParentWindow),当我检查代码时,这实际上是有意义的,因为在调用构造函数之后,父级似乎没有被分配。

以下是MainForm中初始化辅助帧的代码:

if Assigned(frame) then FreeAndNil(frame);
case Node.AbsoluteIndex of
    optInterval: frame := Tframe2.Create(Self); //here's where the constructor gets called.
    //etc
end;
frame := TframeOther.Create(Self); 
if Assigned(frame) then
begin
    frame.Parent := panOptions; //here's where Tframe2's parent gets set
    frame.Align := alClient;
end;  

所以有人可以解释,就形式初始化顺序而言,Delphi和Lazarus之间是否有任何重要的区别?

解决这种初始化顺序问题的最标准方法是什么?与我更熟悉的其他语言相比,可能有不同的策略来解决此类错误。我可以在构造函数中添加另一个参数,或者如果有一个方法被调用post构造函数在屏幕上预先绘制它我可以重写我可以重新定位该代码,或者只是创建一个帮助方法并在setParent之后调用它被叫。这里有什么特别的最佳做法吗?

编辑]:看起来这可能是某种特定的TEdit。看起来初始化复选框状态的行没有相同的问题。这可能只是拉撒路的一个错误吗?

1 个答案:

答案 0 :(得分:1)

经过进一步的实验,通过添加一行来将TEdit的父级设置为Frame(而不是设置Frame的父级),我已经能够解决大部分崩溃的直接问题。像这样:

edTime.Parent := Self;
edTime.Text := '12:00';

但是我仍然希望更好地理解为什么这是“有时”需要的。

编辑:虽然这修复了能够在TEdit上设置文本,但这并不能修复我所拥有的自动调整代码,它会遍历组件并调整任何恰好是复选框的大小。显然,没有它的父集的形式仍然是“有点”的问题。

edit2:在构造函数中添加第二个参数并在构造函数中设置整个表单的父级似乎无需完全为TEdit设置父级。