動態產生的按鍵無法 Free |
尚未結案
|
hungyulin
一般會員 發表:36 回覆:33 積分:13 註冊:2003-10-15 發送簡訊給我 |
我在動態產生了一個 Button (Btn35),但是要 Free 卻出現 Access violation 的訊息,
我的動作是先按一下 Btn35,再去按 BtnTDelete 。
priv
Con:TControl;
.
.
. procedure TfmSAL0001M.Btn35MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
TfcShapeBtn(Sender).Color:=clRed;
Con := TControl(Sender);
setcapturecontrol(TControl(Sender));
zX := X;
zY := Y;
RenewDragSpots;
end; procedure TfmSAL0001M.BtnTDeleteClick(Sender: TObject);
var
pn:TfcShapeBtn;
begin
if not Assigned(con) then exit;
inherited;
FreeAndNil(Tcontrol(con)); // 執行這一行時會出錯
end;
|
Miles
尊榮會員 發表:27 回覆:662 積分:622 註冊:2002-07-12 發送簡訊給我 |
Hi hungyulin 你好:
請問錯誤訊息是什麼??
我做了一個簡單的測試沒發生錯誤
procedure TForm1.Button1Click(Sender: TObject); begin Con := TControl(Sender); end; procedure TForm1.Button2Click(Sender: TObject); begin if not Assigned(con) then exit; FreeAndNil(Tcontrol(con)); end;我不是高手, 高手是正在銀幕前微笑的人.
------
我不是高手, 高手是正在銀幕前微笑的人. |
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
|
hungyulin
一般會員 發表:36 回覆:33 積分:13 註冊:2003-10-15 發送簡訊給我 |
|
Miles
尊榮會員 發表:27 回覆:662 積分:622 註冊:2002-07-12 發送簡訊給我 |
Hi hungyulin :
先將一些程式碼Mark起來跑看看是否有錯
procedure TfmSAL0001M.Btn35MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); begin TfcShapeBtn(Sender).Color:=clRed; Con := TControl(Sender); //setcapturecontrol(TControl(Sender)); //zX := X; //zY := Y; //RenewDragSpots; end; procedure TfmSAL0001M.BtnTDeleteClick(Sender: TObject); var pn:TfcShapeBtn; begin if not Assigned(con) then exit; inherited; FreeAndNil(Tcontrol(con)); // 執行這一行時會出錯 end;我不是高手, 高手是正在銀幕前微笑的人.
------
我不是高手, 高手是正在銀幕前微笑的人. |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
基本上,你的問題應該是程式設計時思考方式不是很好而產生的
在程式碼的安排上,事情發生的先後順序混淆不清 procedure TForm1.Button2Click(Sender: TObject);
begin
if not Assigned(con) then exit;
inherited;
FreeAndNil(Tcontrol(con));
end; 為何要將 assigned(con) 與 FreeAndNil(~) 分開?整個程式在安排上就是一個瑕疵,這樣的瑕疵越多,Bug 就越多,同時也更不容易除錯,因為你根本就認為該程式碼是對的,而不會去注意,只能知道錯的位置,而不知道為什麼
何不改成 procedure TForm1.Button2Click(Sender: TObject);
begin inherited;// 兩個 inherited 選一個用 (A)
if Assigned(con) then FreeAndNil(Tcontrol(con));
inherited; // 或是用這個 (B)
end; 如果 Button2Click 不屬於你要釋放的那個 BTN 的方法,則 inherited 的位置就沒有關係~選那個都行,如果是,則最好用 (A) 同常沒有很巢狀的相依性下,inherited 的位置(或是根本不用)就不是很重要,但在考慮良好安全的程式碼下,通常應該先將 inherited 使用,讓該做的是做完,在做你的事,除非你有特殊需求才來調整 inherited 之位置,同時注意若像是 destory 這種方法中,inherited 要放在最後,不然你就會有錯誤產生
最後因為我們使用 FreeAndNil 所以程式碼可以改成更安全的: procedure TForm1.Button2Click(Sender: TObject);
begin inherited;
if con is TControl then FreeAndNil(Tcontrol(con));
end;
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
排开前面的朋友讲的写代码的方式不论,单就你这段代码来看:
我在動態產生了一個 Button (Btn35),但是要 Free 卻出現 Access violation 的訊息, 我的動作是先按一下 Btn35,再去按 BtnTDelete 。 priv Con:TControl; . . . procedure TfmSAL0001M.Btn35MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin TfcShapeBtn(Sender).Color:=clRed; Con := TControl(Sender); //《----显然,这个 Con 就是 Btn35. 因为看不到 Btn35 是在哪里Create的,Create的方式如何,所以就没办法知道它在哪里会被 Free 掉。 setcapturecontrol(TControl(Sender)); zX := X; zY := Y; RenewDragSpots; end; procedure TfmSAL0001M.BtnTDeleteClick(Sender: TObject); var pn:TfcShapeBtn; begin if not Assigned(con) then exit; inherited; FreeAndNil(Tcontrol(con)); // 執行這一行時會出錯 //〈---当然,这里应该改为:if Assigned(con) then FreeAndNil(Con); 但是,还是应该分析那个 inherited干了什么。为什么它先把Con给Free掉了。 end; |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
引言: 排开前面的朋友讲的写代码的方式不论,单就你这段代码来看:改為那樣還是會錯 因為 若是 con 不是 TContolr 就會錯,因為,若是 con 只是一個亂數值,會是已經釋放但是未設成 nil,此時 assinged 將會傳回 true ,而 FreeAndNil 就有可能會錯,因為物件不存在 所以這種錯誤在提示程式設計者,一件事,就是設計思考有問題,不然不會code 出這樣奇怪的東西 而這種錯誤常常出現在急於寫出成品,少於學習精進程式能力的初學者,小的案子也許沒問題,不會出錯,但是要是大案子,萬把行程式碼,相依度又不小時,除錯除到死,都無法解決 另外,那個 inherited 如無特殊需求或是設計,如前所說,應該是不需要的我在動態產生了一個 Button (Btn35),但是要 Free 卻出現 Access violation 的訊息, 我的動作是先按一下 Btn35,再去按 BtnTDelete 。 priv Con:TControl; . . . procedure TfmSAL0001M.Btn35MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin TfcShapeBtn(Sender).Color:=clRed; Con := TControl(Sender); //《----显然,这个 Con 就是 Btn35. 因为看不到 Btn35 是在哪里Create的,Create的方式如何,所以就没办法知道它在哪里会被 Free 掉。 setcapturecontrol(TControl(Sender)); zX := X; zY := Y; RenewDragSpots; end; procedure TfmSAL0001M.BtnTDeleteClick(Sender: TObject); var pn:TfcShapeBtn; begin if not Assigned(con) then exit; inherited; FreeAndNil(Tcontrol(con)); // 執行這一行時會出錯 //〈---当然,这里应该改为:if Assigned(con) then FreeAndNil(Con); 但是,还是应该分析那个 inherited干了什么。为什么它先把Con给Free掉了。 end; |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |