多個Form被執行關閉時, Close該如何寫 |
缺席
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
請問各位: 我有一個狀況 Form1 有 Button1 procedure TForm1Click(Sender: TObject); Form2.Show; end; 在Form2的onClose procedure TForm2.FormClose(Sender: TObject; 問題: 當button1執行4次時, 會建立4個Form2, 但Form2.name分別為 Form2_1, Form2_2, Form2_3, Form2_4(此部份是由Delphi自己命名的, 我並未指定), 而就目前的寫法 Form2:=nil一旦被執行(假設我是關閉 Form2_3), 然後我再去關閉 Form2_1, Form2_2都會引發錯誤, 我要如何在 Close上寫, 才可以做到關閉Form2_1, 實際是Form2_1:= nil, 關閉Form2_2, 實際是Form2_2:= nil的寫法, 謝謝! |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
我非delphi的當前使用者。但猜問題可能的情形。也許不對,但目前也還沒人回應,就插花一下吧!
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin Action:= caFree; self:= nil; end; ===================引 用 文 章=================== 問題: 當button1執行4次時, 會建立4個Form2, 但Form2.name分別為 Form2_1, Form2_2, Form2_3, Form2_4(此部份是由Delphi自己命名的, 我並未指定), 而就目前的寫法 Form2:=nil一旦被執行(假設我是關閉 Form2_3), 然後我再去關閉 Form2_1, Form2_2都會引發錯誤, 我要如何在 Close上寫, 才可以做到關閉Form2_1, 實際是Form2_1:= nil, 關閉Form2_2, 實際是Form2_2:= nil的寫法, 謝謝!
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
謝謝你的回應,也讓我學習到不能直接把 self 值設成NIL ! 不過終就我還是錯了! ,因為認真的看了你的程式才發現,你要的是把一個reference的變數設定成nil而已。我自己都頭昏的想把指向物件的指標變成null,真是神經了。想了想,有點奇怪的是,通常需要把reference變數設成nil是為了類似這樣的敘述 if not Assigned( ref ) then ref := TXxxx.Create(AOwner)以避開建二次… 我剛也查了我以前的舊書 delphi 2 發展手冊,也有看到類似你要 Action := caFree; 然後到OnDestory事件上加一句 ref := nil。說明有提到事實上caFree 時整個物件已經釋放,「變數」本身的值還是存在,於是為了在Assigned的判別中正常運作,需要把此變數設成nil 。 但你的例子是使用了 一個Global reference variable (Form2) ,以此來跨二個unit,且是唯一一個變數來接受你動態的傳reference 給 Form2。第一次產生時,Form2的值是指向第一個產生的實體,二個次Form2是指向第二個實體……,無論幾次create,都只用一個Form2的變數來接。當第一個instance close的時候,Form2指向nil,即不指向任何地方。第二個instance close的時候,Form2再度的被nil,此時沒義意了因為重複設定Form2為nil n 次是沒什麼意義的。 因為PD兄肯定是高手,我想應該會覺得我講一堆沒用很煩的話。我想表達的意思是這個程式本身的「目的」問題。因為: 不知是否還有其他的應用?? 廢話很多,請見諒唷! 謝謝回應 但這不是一個合法的寫法, self是反應一個TObject, 無法指定 nil的格式
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
感謝 aftcast 兄詳細的說明: 昨天我的問題已經解決, 首先 大多數人使用 if not Assign(..) then Form.Create(...) 來避免二次建窗, 但我的需求是要多窗開出, 所以不能加這樣的寫法, 至於在 onclose 會加這兩組參數的原因是 一般人在關窗, 都是在 button上寫 Form2.Close, 而在呼叫的Form2的Form1上寫 try Form2:= Tform2.Create(slef); finally Form2.Free; end; 事實上這個Form2並未真正自記憶體中被釋放, 只要執行數次, 系統資源立刻大幅減少, 因此指定Action:= caFree, 可以讓 Form2確實自記憶體配置被清除, 可是還有一個Form2的變數, 如果不指定 Form2:= nil 的話, 當你使用if not Assing(Form2) , 事實上 Form2的變數已不是 nil值, 因此必須指定 Form2:= nil才可以徹底將Form2變數給釋放, 可是當我使用多窗來Create時, 第2個Form2的變數名稱已經不是Form2了, 而是 Form2_1, 因為這是全域變數F不能有重覆, 這也就是我在Form2.OnClose寫 Form2:= nil, 當某一個Form2被釋放是沒有問題, 但如果有第二個Form2窗被開啟的話, 這個Form2被釋放時, Delphi仍以 Form2來釋放, 但Form2變數已經前一個Form2給放掉, 自然就會出現Access Error 的錯誤(其實應該是Form2_1:= nil), 後來我解決的方法是在 Form2.onDestroy 上寫 Form2:= nil; 這樣去編譯, 執行都很正常了, 當然我不是很清楚 onDestroy到底做了那些事, 只是把這個經驗提供給各位做參考! |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
不知道我看明白你的问题没有。按我对你的问题的理解,我认为你对 Form2 是个啥东西,理解有错误。
在 TFomr2 的单元里,Delphi 自动地帮你在 interface 部分声明了一个: var Form2: TForm2; 并且,delphi 自动地在工程那个单元里,自动地帮你写了:Application.CreateForm(Form2, TForm2); 要知道,这个类型为 TForm2 的变数 Form2 是一个其它单元也可以看到的一个 TForm2 的实例。 如果你有很多个 TForm2 的实例,也就是你要同时 Show 很多个 Form2 出来,就不应该用 Form2 这个变数!而应该为每个窗口,单独命名一个 TForm2 类型的变数。 否则,问题很严重。 ===================引 用 文 章=================== 感謝 aftcast 兄詳細的說明: 昨天我的問題已經解決, 首先 大多數人使用 if not Assign(..) then Form.Create(...) 來避免二次建窗, 但我的需求是要多窗開出, 所以不能加這樣的寫法, 至於在 onclose 會加這兩組參數的原因是 一般人在關窗, 都是在 button上寫 Form2.Close, 而在呼叫的Form2的Form1上寫 try Form2:= Tform2.Create(slef); finally Form2.Free; end; 事實上這個Form2並未真正自記憶體中被釋放, 只要執行數次, 系統資源立刻大幅減少, 因此指定Action:= caFree, 可以讓 Form2確實自記憶體配置被清除, 可是還有一個Form2的變數, 如果不指定 Form2:= nil 的話, 當你使用if not Assing(Form2) , 事實上 Form2的變數已不是 nil值, 因此必須指定 Form2:= nil才可以徹底將Form2變數給釋放, 可是當我使用多窗來Create時, 第2個Form2的變數名稱已經不是Form2了, 而是 Form2_1, 因為這是全域變數F不能有重覆, 這也就是我在Form2.OnClose寫 Form2:= nil, 當某一個Form2被釋放是沒有問題, 但如果有第二個Form2窗被開啟的話, 這個Form2被釋放時, Delphi仍以 Form2來釋放, 但Form2變數已經前一個Form2給放掉, 自然就會出現Access Error 的錯誤(其實應該是Form2_1:= nil), 後來我解決的方法是在 Form2.onDestroy 上寫 Form2:= nil; 這樣去編譯, 執行都很正常了, 當然我不是很清楚 onDestroy到底做了那些事, 只是把這個經驗提供給各位做參考! |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |