線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2959
推到 Plurk!
推到 Facebook!

動態建立與刪除Form的問題…

答題得分者是:jow
ychch0819
一般會員


發表:25
回覆:29
積分:15
註冊:2006-08-09

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-11-07 09:54:43 IP:59.120.xxx.xxx 訂閱
有兩個問題想請教各位:
我想要在Form1(MDI Form)的某個Botton ClickEvent後,動態建立n個相同的MDI Child Form(Form2)
建立時沒有問題…而要做delete的動作時..只要加入ab_form[i]->Parent這一行就會有問題,拿掉就可以正常,不知道為什麼!?

第二個問題是我在Form2的closeEvent有加入Action=caFree;的動作,上述沒有問題的情況是在Form2還沒有被關起來的動作下可以正常
只要Form2已經先被關掉,在執行Button Click的動作後,刪除時一樣會出現access violation的情況(ab_form的指標不為NULL),所以想請
問一下若要避開上述問題,正確的寫法是什麼…謝謝

程式碼如下:(ab_form宣告於.h檔(TForm2 ab_form**;)

void __fastcall TForm1::Button1Click(TObject *Sender)
{
int cnt=2;
//先判斷是否為null,若不是則delete memory
if (ab_form!=NULL)
{
for (int i=0;i {
if (ab_form[i]!=NULL)
delete ab_form[i];
}
ab_form=NULL;
}
//create..
ab_form = new TForm2*[cnt];
for (int i=0;i {
ab_form[i] = new TForm2(Application);
//ab_form->Visible = true;
ab_form[i]->Parent = this;
}
}


而沒問題的寫法如下,不需要於.h檔先宣告,且也沒有做form delete的動作
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-11-07 11:05:44 IP:210.66.xxx.xxx 訂閱
(1)Child Form 的 Owner 指定為 Application
基本上, 這沒有什麼問題, 反正在程式結束時, 若是沒有明確的程式碼
去釋放所有產生的Child Form, 那麼最後就由Application這個Global 物件
負責釋放.

(2)以物件指標陣列(TForm2 ab_form**) Keep產生的 Child Form 參考(reference)
基本上, 這也沒有什麼問題, 反正只是用來引用所產生的Child Form, 只是以ab_form**
來作釋放Child Form的動作時, 必須特別記得在delete 該 Child Form之後, 要將相對的
物件指標設定成 NULL(在程式執行過程中, 可能誤判). 這一點與Owner去作釋放的狀況
不同, 被Owner管理的物件, 在free 時會通知 Owner, 然後Owner 則將它的reference從
Components[]中移除, 兩者之間有互動關係.

另外在MDI Application時, 以你的程式碼來說, 要先避開 ActiveMDIChild, 在For-Loop
執行完畢後,再將它釋放.

[code cpp]
if (ab_form!=NULL) {
for (int i=0;i if (ab_form[i]!=NULL&&ab_form[i]!=ActiveMDIChild){
delete ab_form[i];
ab_form[i] = NULL;
}
}
if(ActiveMDIChild!=NULL)
delete ActiveMDIChild
ab_form=NULL;
}
[/code]

(3)Child Form 在 OnClose的 Action 設定成 caFree, 在Child Form
關閉後再作delete動作會產生錯誤, 就是(2)中所提的物件釋放後, 指
向的物件參考沒有設成NULL.

編輯記錄
jow 重新編輯於 2007-11-07 11:10:29, 註解 無‧
jow 重新編輯於 2007-11-07 11:12:22, 註解 無‧
jow 重新編輯於 2007-11-07 11:15:59, 註解 無‧
jow 重新編輯於 2007-11-07 11:17:36, 註解 無‧
ychch0819
一般會員


發表:25
回覆:29
積分:15
註冊:2006-08-09

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-11-07 15:14:23 IP:59.120.xxx.xxx 訂閱
Dear jow:

我依照你所提供的delete方法測式,仍然會出現Access Voilation的問題…
而只要拿掉ab_form[i]->Parent=this這一行,即不會出現…

而第二個問題,依照你的說法,只要Form2事先已經先關掉了…
在去執行delete的動作就一定會出現access violation,這是無法避免的嗎?
謝謝...

===================引 用 jow 文 章===================
(1)Child Form 的 Owner 指定為 Application
基本上, 這沒有什麼問題, 反正在程式結束時, 若是沒有明確的程式碼
去釋放所有產生的Child Form, 那麼最後就由Application這個Global 物件
負責釋放.

(2)以物件指標陣列(TForm2 ab_form**) Keep產生的 Child Form 參考(reference)
基本上, 這也沒有什麼問題, 反正只是用來引用所產生的Child Form, 只是以ab_form**
來作釋放Child Form的動作時, 必須特別記得在delete 該 Child Form之後, 要將相對的
物件指標設定成 NULL(在程式執行過程中, 可能誤判). 這一點與Owner去作釋放的狀況
不同, 被Owner管理的物件, 在free 時會通知 Owner, 然後Owner 則將它的reference從
Components[]中移除, 兩者之間有互動關係.

另外在MDI Application時, 以你的程式碼來說, 要先避開 ActiveMDIChild, 在For-Loop
執行完畢後,再將它釋放.

[code cpp]
if (ab_form!=NULL) {
for (int i=0;i if (ab_form[i]!=NULL&&ab_form[i]!=ActiveMDIChild){
delete ab_form[i];
ab_form[i] = NULL;
}
}
if(ActiveMDIChild!=NULL)
delete ActiveMDIChild
ab_form=NULL;
}
[/code]

(3)Child Form 在 OnClose的 Action 設定成 caFree, 在Child Form
關閉後再作delete動作會產生錯誤, 就是(2)中所提的物件釋放後, 指
向的物件參考沒有設成NULL.

jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-11-07 15:56:20 IP:210.66.xxx.xxx 訂閱
當然會出現Access Voilation, 因為Child Form關閉時並沒有通知MDI Form
將ab_form[i] 設成 NULL.

以下幾項建議, 提供你參考
(1)Create Child Form時, Owner指定為 MDI Form.

ab_form[i] = new TForm2(this);

(2)Child Form's OnClose Event Handler

[code cpp]
//找到Child Form 自己在ab_form中的位置
TForm1 *f=(TForm1*)Owner;
int Index=-1;
for(int i=0; icnt;i ){
if(this==f->ab_form[i]){
Index=i;
break;
}
//將參考到自己的指標設成NULL
if(Index!=-1)f->ab_form[Index]=NULL;

Action=caFree;

[/code]

(3)或者在MDI Form設置一個User Define Message,
例如


WM_CHILD_FORM_CLOSE = WM_USER 1000;

然後, 在Child Form OnClose時, PostMessage() 給 MDI Form,
然後,MDI Form 收到這個訊息, 則將指向該Child Form在ab_form中的參考,設成NULL.

(4)
ab_form[i] = new TForm2(this);
//ab_form->Visible = true;
ab_form[i]->Parent = this;<<--這一行是不必要的

因為一個 MDI Application只能有一個 MDI Form, 並且所有的
MDI Child Form必定要在 MDI Form中顯示, 所以...就是這樣...


以上建議, 純屬個人見解, 僅供參考...........^_^

===================引 用 ychch0819 文 章===================
Dear jow:

我依照你所提供的delete方法測式,仍然會出現Access Voilation的問題…
而只要拿掉ab_form[i]->Parent=this這一行,即不會出現…

而第二個問題,依照你的說法,只要Form2事先已經先關掉了…
在去執行delete的動作就一定會出現access violation,這是無法避免的嗎?
謝謝...

系統時間:2024-11-26 1:27:33
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!