ifの条件について


DO  2007-11-24 23:33:32  No: 28650  IP: 192.*.*.*

質問失礼します。

Createを用いて、ボタン1を押すとPanel1が動的に生成されるプログラムなんですが、このPanel1をボタン2を押したときに削除されるようにしたいのですが、Panel1が生成されていないときにボタン2を押すとエラーが出てしまうので、ifの条件を

if 「TForm上にPanel1が存在するならば」 then
Panel1.Destroy;

にしたいのですがご指導のほうお願い頂けないでしょうか?
初心者で伝わりに難い部分もございますが、どうか宜しくお願いします。

編集 削除
うんと  2007-11-25 00:11:11  No: 28651  IP: 192.*.*.*

if Assigned(Panel1) then FreeAndNil(Panel1);

かと

編集 削除
DO  2007-11-25 01:05:44  No: 28652  IP: 192.*.*.*

ありがとうございます。試してみます!!!!

編集 削除
TOBY  URL  2007-12-01 23:30:45  No: 28653  IP: 192.*.*.*

>うんとさん

FreeAndNil(Panel1) は、

Panel1 <> nil のときのみ、Panel1.Free;を呼び、Panel1 = nil;
してくれます。
(マルチスレッド考慮のため、実際の処理は、ちょっと違いますが、認識的には、これでOKです。
詳しくは、Pro版のソースを読んでいただければ、と)

つまり、
  if Assigned(Panel1)
は必要なく、
  FreeAndNil(Panel1);
だけで、よいはずです。


ちなみに、私は、GExpertsの、CodeProofreaderに登録して、
一発で入力できるようにしています。

編集 削除
うんと  2007-12-02 05:15:53  No: 28654  IP: 192.*.*.*

表題が「ifの条件について」について、ですから。
これにたいして FreeAndNil(Panel1) だけでよい、と回答するの焦点がずれてると思います。

編集 削除
どうみても  2007-12-02 13:18:54  No: 28655  IP: 192.*.*.*

うんとは

質問の本文を理解できていないようですな

編集 削除
ofZ  2007-12-03 08:43:55  No: 28656  IP: 192.*.*.*

横ヤリ質問

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なんですが、魔法がかかった目に見えない処理が隠されているんですか?

編集 削除
KHE00221  2007-12-03 09:18:22  No: 28657  IP: 192.*.*.*

TObject.Free に魔法がかかっているんですよ

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

編集 削除
KHE00221  2007-12-03 09:24:53  No: 28658  IP: 192.*.*.*

でもあえて言うならば・・・・

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 を過信してはいけません

編集 削除
うんと  2007-12-03 10:46:17  No: 28659  IP: 192.*.*.*

>Button3 のときはエラーになりませんが Button2 のときはエラーになります

それは、グローバル変数はデフォルトで nil、ローカル変数はそうでない、って
ことですよね。

>Assigned FreeAndNil を過信してはいけません

この場合、それではどんなコードを書けばよい、とお考えですか?

編集 削除
ofZ  2007-12-03 10:54:04  No: 28660  IP: 192.*.*.*

> TObject.Free に魔法がかかっているんですよ
なるほど、アセンブラで魔法書いてあったんですね。
ありがとうございました。

編集 削除
KHE00221  2007-12-03 10:54:13  No: 28661  IP: 192.*.*.*

>この場合、それではどんなコードを書けばよい、とお考えですか?

if true then 
begin
  Panel := TPanel.Create(Self);
end
else
begin
  Panel := nil;
end;

FreeAndNil (Panel);

初期化すれば良いだけの事

編集 削除
KHE00221  2007-12-03 10:55:11  No: 28662  IP: 192.*.*.*

>なるほど、アセンブラで魔法書いてあったんですね。
>ありがとうございました。

え?

編集 削除
うんと  2007-12-03 11:03:45  No: 28663  IP: 192.*.*.*

>初期化すれば良いだけの事

うーむ、上のコードの意味がわかりません。
初期化に気をつけよう、というのと、ローカル変数がどうの、というのと
どんな関連があるのですか?

編集 削除
ofZ  2007-12-03 11:29:33  No: 28664  IP: 192.*.*.*

> >なるほど、アセンブラで魔法書いてあったんですね。
> >ありがとうございました。

> え?
あれ・・・?
と思って調べたら・・・

D5(まで?)
> procedure TObject.Free;
> asm
>   (略)
> end;

D6,D7(D6以降?)
> procedure TObject.Free;
> begin
>   if Self <> nil then
>     Destroy;
> end;

失礼しました

編集 削除
KHE00221  2007-12-03 11:32:56  No: 28665  IP: 192.*.*.*

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 のように初期化しないと駄目と言う事です

編集 削除