MainForm は、実行時にいくつかのセカンダリ Frame オブジェクトを作成して、さまざまなオプション パネルを表示します。
これらのフレーム クラスの 1 つの典型的なコンストラクタを次に示します (それぞれ 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) に親の「ウィンドウ」がまだ割り当てられていない (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 の間に重要な違いがあるかどうかを説明できる人はいますか?
そして、この種の初期化順序の問題を解決する最も標準的な方法は何でしょうか? 私がよく知っている他の言語と比較すると、このようなエラーを解決するための戦略が異なる場合があります。コンストラクターに別のパラメーターを追加するか、コンストラクターを事前に画面に描画して呼び出されるメソッドがある場合は、そのコードを再配置するか、ヘルパー メソッドを作成して setParent が呼び出された後に呼び出すことができます。ここで特定のベストプラクティスはありますか?
Edit]: これは何らかの形で TEdit に固有のもののようです。チェックボックスの状態を初期化する行には同じ問題がないようです。これは単に Lazarus のバグでしょうか?