質問失礼します。
Createを用いて、ボタン1を押すとPanel1が動的に生成されるプログラムなんですが、このPanel1をボタン2を押したときに削除されるようにしたいのですが、Panel1が生成されていないときにボタン2を押すとエラーが出てしまうので、ifの条件を
if 「TForm上にPanel1が存在するならば」 then
Panel1.Destroy;
にしたいのですがご指導のほうお願い頂けないでしょうか?
初心者で伝わりに難い部分もございますが、どうか宜しくお願いします。
if Assigned(Panel1) then FreeAndNil(Panel1);
かと
ありがとうございます。試してみます!!!!
>うんとさん
FreeAndNil(Panel1) は、
Panel1 <> nil のときのみ、Panel1.Free;を呼び、Panel1 = nil;
してくれます。
(マルチスレッド考慮のため、実際の処理は、ちょっと違いますが、認識的には、これでOKです。
詳しくは、Pro版のソースを読んでいただければ、と)
つまり、
if Assigned(Panel1)
は必要なく、
FreeAndNil(Panel1);
だけで、よいはずです。
ちなみに、私は、GExpertsの、CodeProofreaderに登録して、
一発で入力できるようにしています。
表題が「ifの条件について」について、ですから。
これにたいして FreeAndNil(Panel1) だけでよい、と回答するの焦点がずれてると思います。
うんとは
質問の本文を理解できていないようですな
横ヤリ質問
TOBYさん
> FreeAndNil(Panel1) は、
>
> Panel1 <> nil のときのみ、Panel1.Free;を呼び、Panel1 = nil;
> してくれます。
D5,D7では以下のように記述されていますが、BDS2006とかでは変わったの?
> procedure FreeAndNil(var Obj);
> var
> P: TObject;
> begin
> P := TObject(Obj);
> TObject(Obj) := nil;
> P.Free;
> end;
見る限り、無条件Freeなんですが、魔法がかかった目に見えない処理が隠されているんですか?
TObject.Free に魔法がかかっているんですよ
procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;
でもあえて言うならば・・・・
var
Form1: TForm1;
Button3 : TButton;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Button2 : TButton;
begin
if Assigned(Button3) = True then FreeAndNil(Button3);
end;
Button3 のときはエラーになりませんが Button2 のときはエラーになります
ボタンやパネルをローカル変数でCreateする事は少ないと思いますが、Bitmap や StringList 等ならあるでしょう
Assigned FreeAndNil を過信してはいけません
>Button3 のときはエラーになりませんが Button2 のときはエラーになります
それは、グローバル変数はデフォルトで nil、ローカル変数はそうでない、って
ことですよね。
>Assigned FreeAndNil を過信してはいけません
この場合、それではどんなコードを書けばよい、とお考えですか?
> TObject.Free に魔法がかかっているんですよ
なるほど、アセンブラで魔法書いてあったんですね。
ありがとうございました。
>この場合、それではどんなコードを書けばよい、とお考えですか?
if true then
begin
Panel := TPanel.Create(Self);
end
else
begin
Panel := nil;
end;
FreeAndNil (Panel);
初期化すれば良いだけの事
>なるほど、アセンブラで魔法書いてあったんですね。
>ありがとうございました。
え?
>初期化すれば良いだけの事
うーむ、上のコードの意味がわかりません。
初期化に気をつけよう、というのと、ローカル変数がどうの、というのと
どんな関連があるのですか?
> >なるほど、アセンブラで魔法書いてあったんですね。
> >ありがとうございました。
>
> え?
あれ・・・?
と思って調べたら・・・
D5(まで?)
> procedure TObject.Free;
> asm
> (略)
> end;
D6,D7(D6以降?)
> procedure TObject.Free;
> begin
> if Self <> nil then
> Destroy;
> end;
失礼しました
var
Form1: TForm1;
Panel1 : TPanel;
procedure TForm1.Button1Click(Sender: TObject);
var
Panel2,Panel3 : TPanel;
begin
Panel3 := nil;
Memo1.Lines.Add ('Panel1 : ' + IntToStr(Integer(Panel1))); // 0
Memo1.Lines.Add ('Panel2 : ' + IntToStr(Integer(Panel2))); // 0 以外
Memo1.Lines.Add ('Panel3 : ' + IntToStr(Integer(Panel3))); // 初期化したので 0
end;
ローカル変数の Panel2,Panel3 は初期化されていませんので
Panel3 := nil のように初期化しないと駄目と言う事です
ツイート | ![]() |