2012-09-26 11 views
6

MainFormは実行時にいくつかのセカンダリFrameオブジェクトを作成し、さまざまなオプションパネルを表示します。DelphiとLazarusのフォーム初期化の違いは?

ここでは、それらのフレームクラスの一つの典型的なコンストラクタは、(彼らはそれぞれの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でうまくいきましたが、コントロール(TEdit)にまだ割り当てられていない親ウィンドウ(rsControlHasNoParentWindow)がないため、Lazarusの同じコードがEInvalidOperation例外をスローし続けます。親が割り当てられていないように見えるので、コンストラクタが呼び出されるまで

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; 

だから、誰もが、フォームの初期化シーケンス限りデルファイとラザロとの間の重要な違いがあるのか​​どうか説明することができます:ここで

はMainFormを内のコードは、二次フレームを初期化しているのですか?

そして、このタイプの初期化順序問題を解決する最も標準的な方法はどれですか?私がもっと慣れ親しんでいる他の言語と比較すると、そのようなエラーを解決するさまざまな戦略があるかもしれません。コンストラクタに別のパラメータを追加することもできますし、ポストコンストラクタと呼ばれるメソッドをプレイングして画面上に描画してオーバーライドすることもできます。そのコードを再配置したり、ヘルパーメソッドを作成してsetParentを呼び出した後に呼び出すことができます。特にここでのベストプラクティスは?

編集]:これはTEditに固有のものであるようです。チェックボックスの状態を初期化する行に同じ問題がないようです。これはLazarusのバグでしょうか?

+0

問題が解決するかどうかわかりませんが、継承されたCreate(AOwner);作成プロシージャで – Ravaut123

+0

シンプルなコードを試してください* TEdit.Create(nil).Text:= '12345' *; このコードは、親なしの編集を作成し、それにキャプションを割り当てます。 これはVCLでは動作しますが、LCLでは動作しない場合、それはまさにそれらが親を持つwrtであることを意味します。また、LCLは一部のツールキットライブラリに対するラッパーに過ぎないことにも注意してください。 GTK +以上のLCL、Qt以上のLCL、他に何が分かっているか。おそらく、LCLバックエンドを別のライブラリに切り替えて修正することができます。またはそうでないかもしれません。 –

+0

私はそれを打ったが、私はこの問題を複製することはできない(lazarus 0.9.30.4)。 –

答えて

1

さらに実験を重ねた結果、TEditの親をフレームに設定する行を追加してフレームの親を設定するよりも、すぐにクラッシュするという問題のほとんどを解決できました。これと同じように:私はまだ、なぜよりよく理解してみたい

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

しかし、これは「時々」が必要です。

編集:これはTEditでテキストを設定できるようになっていますが、これはコンポーネントを繰り返し処理してチェックボックスになるサイズを変更する自動サイズコードを修正しません。どうやらそれが親のセットを持っていないフォームは、まだ「一種の」問題です。

edit2:コンストラクタに2番目のパラメータを追加し、コンストラクタ内のフォーム全体の親を設定すると、TEditのParentを完全に設定する必要がなくなりました。

+2

これは、(TEditのような)ビジュアルコントロールを作成するときには、ほとんどの場合必須です。ビジュアルコンテンツを持っているので、そのコンテンツをペイントする必要があります。これは 'Parent.Canvas'にあります。 DFMストリーミングメソッドはこれを自動的に行います(そして、構造ビューで子コントロールの '系譜'または '親の注文 'を見たり、DFMをテキストとして見てインデントレベルを観察することができます)。実行時にコード内にコントロールを作成するときは、自分で行う必要があります(発見したように)。 –

関連する問題