MainForm creates some secondary Frame objects at runtime to display various option panels.
Here's a typical constructor for one of those frame classes (they each extend 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;
This code worked fine in Delphi (whether or not it was the right way to do things), but the same code in Lazarus keeps throwing an EInvalidOperation exception, because the control (TEdit) has no parent "window" assigned yet (rsControlHasNoParentWindow), which actually kind of makes sense when I examine the code because the parent doesn't appear to be getting assigned until after the constructor is called.
Here is the code in MainForm the initializes the secondary frame:
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;
So can anyone explain whether there's any important differences between Delphi and Lazarus as far as form initialization sequence?
And what the most standard way to resolve this type of initialization order problem would be? Comparing to other languages I'm more familiar with, there might be different strategies to resolve such errors. I could add another parameter to the constructor, or if there's a method that gets called post constructor pre-drawing it on the screen that I could override I could relocate that code, or just make a helper method and call it after setParent gets called. Any particular best practice here?
Edit]: It appears this may be specific to TEdit in some way. It looks like the lines initializing the state for checkboxes are not having the same issue. Could this just be a bug in Lazarus?