喫茶XRAYトップページ

[スレッド全体
]

[11143] Re:コンポーネントの登録先はForm … 何を今さら。返信 削除
2017/4/24 (月) 01:01:44 taka
▼ takiさん
> Button3は配列にnilを代入しています。
> それでも、生成したpanelをクリックすると色が変わります。


Button3変数
変数は ここにありますよという、封筒の宛先にすぎませんので
Button3 にnilをいれても 封筒の宛先を砂消しで消すことにしかなりませんので宛先の住所地はなくなりません。
Button3本体を消滅させるのは巡航ミサイルの Free 手続きです
ミサイルを飛ばした後は、だれが撃ったかわからないようにButton3変数を焼却します

変数(封筒)がなくても、建物にはなんら影響はありません
封筒がなくても住所地建物は存在します。廃墟の場合もあります。

子コントロールをFreeしたあとに 間違って呼び出すと 宛先不明・不在でエラーとして返送されますので
念のためnilを代入しておきます

> Delphiヘルプより引用
> アプリケーションでは RemoveControl メソッドを直接呼び出さないでください。
> 実行時には,子コントロールの Parent プロパティを使って Controls 配列から削除できます。


手動でコントロールの消滅を強制執行したい場合は
コントロール.Free;

if Not(csDestroyingHandle in ControlState) And Assigned(Button3) then
begin
  FreeAndNil(Button3);
end;

PanelArray[i]に登録したものを動的に破棄したい場合は、
if Not(csDestroyingHandle in ControlState) And Assigned(PanelArray[i]) then
begin
  // try exceptでくくったほうが安全
  FreeAndNil(PanelArray[i]);
 // 同じ配列内で親子関係のパネルがネストされている場合は注意
end;



[11144] Re2:コンポーネントの登録先はForm … 何を今さら。返信 削除
2017/4/24 (月) 08:39:42 Mr.XRAY
▼ takaさん
>
> if Not(csDestroyingHandle in ControlState) And Assigned(Button3) then


おおっ !

>procedure TForm1.Button3Click(Sender: TObject);

では配列要素を削除しているということですから,
その時に実体である,基本的には生成したコンポーネントも破棄ですね.

で,サンプルとしては掲載してはいますが,
このように複数の同じコンポーネントを生成して管理する場合,
配列よりもリストの方がいいと思います.
TComponentList, TList<T> の方が扱いやすいと思いますね.

記事の履歴は削除してしまいましたが,
この配列を使用するサンプルは後から追加した記憶があります.

検索エンジンで「コンポーネント 配列」というのがあり,
このページがヒットすれば,TComponentList のところも見てくれるのではないか,
という期待感から掲載したつもりです.

ただし,今回のような,
入れ物と中身である実体の動作を確認するには,配列はいい見本かも知れません.


[11145] Re2:コンポーネントの登録先はForm … 何を今さら。返信 削除
2017/4/24 (月) 12:43:03 taki
▼ takaさん

> Button3変数
> 変数は ここにありますよという、封筒の宛先にすぎませんので
> Button3 にnilをいれても 封筒の宛先を砂消しで消すことにしかなりませんので宛先の住所地はなくなりません。
> Button3本体を消滅させるのは巡航ミサイルの Free 手続きです
> ミサイルを飛ばした後は、だれが撃ったかわからないようにButton3変数を焼却します


 
> PanelArray[i]に登録したものを動的に破棄したい場合は、
> if Not(csDestroyingHandle in ControlState) And Assigned(PanelArray[i]) then
> begin
>   // try exceptでくくったほうが安全
>   FreeAndNil(PanelArray[i]);
>  // 同じ配列内で親子関係のパネルがネストされている場合は注意
> end;
>


配列にnilを代入していたコードを以下のように変更しました。
procedure TForm1.Button3Click(Sender: TObject);
var
  i:integer;
begin
  for i := 0 to High(FPanelArray1) do begin
    if Not(csDestroyingHandle in ControlState) And Assigned(FPanelArray1[i]) then begin
      FreeAndNil(FPanelArray1[i]);
    end;
  end;
end;

5枚のパネルは消えて、Self.ControlCountの値も9から4に戻りました。

基本は自分で生成したコンポーネントは自分で始末するべきなんでしょうね。
でも、もし忘れていてもForm(Owner)が知っているのでFormが始末してくれるんですね。

勉強になりました。ありがとうございます。


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82