ifの条件について


DO  2007-11-25 08:33:32  No: 28650

質問失礼します。

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

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

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


うんと  2007-11-25 09:11:11  No: 28651

if Assigned(Panel1) then FreeAndNil(Panel1);

かと


DO  2007-11-25 10:05:44  No: 28652

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


TOBY  URL  2007-12-02 08:30:45  No: 28653

>うんとさん

FreeAndNil(Panel1) は、

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

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

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


うんと  2007-12-02 14:15:53  No: 28654

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


どうみても  2007-12-02 22:18:54  No: 28655

うんとは

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


ofZ  2007-12-03 17:43:55  No: 28656

横ヤリ質問

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 18:18:22  No: 28657

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

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


KHE00221  2007-12-03 18:24:53  No: 28658

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

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 19:46:17  No: 28659

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

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

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

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


ofZ  2007-12-03 19:54:04  No: 28660

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


KHE00221  2007-12-03 19:54:13  No: 28661

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

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

FreeAndNil (Panel);

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


KHE00221  2007-12-03 19:55:11  No: 28662

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

え?


うんと  2007-12-03 20:03:45  No: 28663

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

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


ofZ  2007-12-03 20:29:33  No: 28664

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

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

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

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

失礼しました


KHE00221  2007-12-03 20:32:56  No: 28665

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


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加