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

動態產生的按鍵無法 Free

尚未結案
hungyulin
一般會員


發表:36
回覆:33
積分:13
註冊:2003-10-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-10-28 11:51:35 IP:61.219.xxx.xxx 未訂閱
我在動態產生了一個 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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-10-28 13:21:43 IP:220.135.xxx.xxx 未訂閱
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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-10-28 13:44:15 IP:61.218.xxx.xxx 未訂閱
引言: procedure TfmSAL0001M.BtnTDeleteClick(Sender: TObject); var pn:TfcShapeBtn; begin if not Assigned(con) then exit; inherited; //有沒有可能因為這裡,在祖先物件裡就已經被free掉了,在FreeAndNil之前,再用Assigned檢查一次看看 FreeAndNil(Tcontrol(con)); // 執行這一行時會出錯 end;
hungyulin
一般會員


發表:36
回覆:33
積分:13
註冊:2003-10-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-10-28 13:46:04 IP:61.219.xxx.xxx 未訂閱
錯誤訊息 Access violation at address 0427B60D. write of address 084F4D34
Miles
尊榮會員


發表:27
回覆:662
積分:622
註冊:2002-07-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-10-28 21:57:18 IP:220.135.xxx.xxx 未訂閱
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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-11-02 17:57:04 IP:61.64.xxx.xxx 未訂閱
基本上,你的問題應該是程式設計時思考方式不是很好而產生的 在程式碼的安排上,事情發生的先後順序混淆不清 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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-11-02 19:30:25 IP:218.18.xxx.xxx 未訂閱
排开前面的朋友讲的写代码的方式不论,单就你这段代码来看:    
我在動態產生了一個 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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-11-03 18:03:27 IP:61.64.xxx.xxx 未訂閱
引言: 排开前面的朋友讲的写代码的方式不论,单就你这段代码来看:
我在動態產生了一個 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;    
改為那樣還是會錯 因為 若是 con 不是 TContolr 就會錯,因為,若是 con 只是一個亂數值,會是已經釋放但是未設成 nil,此時 assinged 將會傳回 true ,而 FreeAndNil 就有可能會錯,因為物件不存在 所以這種錯誤在提示程式設計者,一件事,就是設計思考有問題,不然不會code 出這樣奇怪的東西 而這種錯誤常常出現在急於寫出成品,少於學習精進程式能力的初學者,小的案子也許沒問題,不會出錯,但是要是大案子,萬把行程式碼,相依度又不小時,除錯除到死,都無法解決 另外,那個 inherited 如無特殊需求或是設計,如前所說,應該是不需要的
系統時間:2024-07-02 12:49:53
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!