動態建立與刪除Form的問題… |
答題得分者是:jow
|
ychch0819
一般會員 發表:25 回覆:29 積分:15 註冊:2006-08-09 發送簡訊給我 |
有兩個問題想請教各位:
我想要在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 發送簡訊給我 |
(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 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. |
ychch0819
一般會員 發表:25 回覆:29 積分:15 註冊:2006-08-09 發送簡訊給我 |
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 發送簡訊給我 |
當然會出現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; 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,這是無法避免的嗎? 謝謝... |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |