全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3398
推到 Plurk!
推到 Facebook!

about 動態產生元件

答題得分者是:william
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-11-12 11:06:07 IP:61.222.xxx.xxx 未訂閱
各位前輩: 想請問一下,我有動態產生一個panel,其owner為我的主form,再產生的panel下還有產生一些其他的元件,我要將這些動態產生的元件釋放掉,要如何下釋放指令? 我目前的用法是:(Sender as TButton).parent.Free; 可是會有錯誤訊息出現"Access violation at address 0040307D in module..." 該如何解決?Thanks~~
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#2 引用回覆 回覆 發表時間:2002-11-12 11:10:25 IP:147.8.xxx.xxx 未訂閱
Where is the access violation actually? At the (Sender as TButton).parent.Free or other places? Maybe the 'Parent' is freed before? Can you give out the order of creation and destruction of your components (and better with some codes)?
Miles
尊榮會員


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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2002-11-12 11:21:47 IP:210.58.xxx.xxx 未訂閱
Hello fanny try this:

全部釋放
for i := 0 to Form1.ComponentCount - 1 do 
    Form1.Components[i].Free;
若只是要釋放動態產生的元件就用TList去紀錄

var MyList : TList;    procedure TForm1.FormCreate(Sender: TObject);
begin
   MyList := TList.Create;
end;    procedure TForm1.Button2Click(Sender: TObject);
var MyComponent : TEdit;
begin
   MyComponent := TEdit.Create(Form1);
   MyComponent.Left := 10;
   MyComponent.Top := 10;
   MyComponent.Parent := Form1;
   MyComponent.Text := IntToStr(MyList.Count);
   MyList.Add(MyComponent);
end;    procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
   for i := 0 to MyList.Count - 1 do begin
       TComponent(MyList.Items[i]).Free;
   end;
end;    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   MyList.Free;
end;
我不是高手, 高手是正在銀幕前微笑的人.
------


我不是高手, 高手是正在銀幕前微笑的人.
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2002-11-12 11:30:06 IP:61.222.xxx.xxx 未訂閱
procedure TRDQuotationForm.LoadBtnClick(Sender: TObject); var pan,: TPanel;dbg1: TDBGrid;bit1,bit2: TBitBtn; begin pan:=TPanel.Create(self); with pan do begin parent :=RDQuotationForm; Top := 2; Left := 2; Height := 460; Width := 712; color := clBlack; Visible:= True; dbg1:=TDBGrid.Create(self); with dbg1 do begin parent := pan; Align := alTop; Height := 367; Fixedcolor := clYellow; color := clSilver; DataSource := KKDM.BufferADS; ReadOnly := False; Visible := True; end; bit1:=TBitBtn.Create(self); with bit1 do begin parent := pan; Height := 28; top := parent.Height-60; Width := 120; left := parent.width-350; Visible := True; Caption := '確認轉入'; tag := 1; OnClick := ButtonClick; end; bit2:=TBitBtn.Create(self); with bit2 do begin parent := pan; Height := 28; top := parent.Height-60; Width := 120; left := parent.width-200; Visible := True; Caption := '取消返回'; tag := 2; OnClick := ButtonClick; end; end; end; procedure TRDQuotationForm.ButtonClick(Sender: TObject); begin case (Sender as TButton).Tag of 1: begin end; 2: begin (Sender as TButton).parent.Free; //bit2 end; end; end; //run 到此後就出現message 這是產生元件程式,bit2 on click 後就會產生message
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#5 引用回覆 回覆 發表時間:2002-11-12 11:43:16 IP:61.222.xxx.xxx 未訂閱
加進去了,可是還是會出現同樣的錯誤訊息
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2002-11-12 12:07:05 IP:147.8.xxx.xxx 未訂閱
引言:
procedure TRDQuotationForm.ButtonClick(Sender: TObject);
begin
   case (Sender as TButton).Tag of
     1: begin
        end;
     2: begin
           (Sender as TButton).parent.Free;   //bit2
        end;
   end;
end;   //run 到此後就出現message    這是產生元件程式,bit2 on click 後就會產生message
If I understand correctly, this event handler is executed by clicking bit2. You are freeing its parent (pan) and some windows messages will be dispatched to controls displayed inside it. Since freeing of parent control (not owner) does not necessary free the controls displayed on it I would suggest either free each controls manually or chagne their 'Owner' to pan. Here is the way I tested:
procedure TRDQuotationForm.ButtonClick(Sender: TObject);
var
    i: integer;
    pan: TWinControl;
    bit2: TButton;
begin
    case (Sender as TButton).Tag of
        1: begin
        end;
    2: begin
        bit2 := (Sender as TButton);
        pan := bit2.parent;
        bit2.Parent := nil;
        for i := pan.ControlCount-1 downto 0 do
            pan.Controls[i].Free;
        pan.Free;
        bit2.free;
    end;
end;
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#7 引用回覆 回覆 發表時間:2002-11-12 13:26:15 IP:61.222.xxx.xxx 未訂閱
[/quote] If I understand correctly, this event handler is executed by clicking bit2. You are freeing its parent (pan) and some windows messages will be dispatched to controls displayed inside it. Since freeing of parent control (not owner) does not necessary free the controls displayed on it I would suggest either free each controls manually or chagne their 'Owner' to pan. Here is the way I tested:
procedure TRDQuotationForm.ButtonClick(Sender: TObject);
var
    i: integer;
    pan: TWinControl;
    bit2: TButton;
begin
    case (Sender as TButton).Tag of
        1: begin
        end;
    2: begin
        bit2 := (Sender as TButton);
        pan := bit2.parent;
        bit2.Parent := nil;
        for i := pan.ControlCount-1 downto 0 do
            pan.Controls[i].Free;
        pan.Free;
        bit2.free;     
   end;
end;
把【bit2.free;】那一行攔掉就可以了, 不過再請問一下,那我bit2要如何free掉? Thanks~~ [/quote]
Miles
尊榮會員


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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2002-11-12 13:43:09 IP:210.58.xxx.xxx 未訂閱
Hello : 照william先進的這段程式Bit2已經Free掉了吧
procedure TRDQuotationForm.ButtonClick(Sender: TObject);
var i: integer;    
    pan: TWinControl;    
    bit2: TButton;
begin
    case (Sender as TButton).Tag of
        1: begin        end;
        2: begin
             bit2 := (Sender as TButton);
             pan := bit2.parent;
             bit2.Parent := nil;
             for i := pan.ControlCount-1 downto 0 do
                 pan.Controls[i].Free;
                 pan.Free;
           end;
end;
我不是高手, 高手是正在銀幕前微笑的人.
------


我不是高手, 高手是正在銀幕前微笑的人.
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#9 引用回覆 回覆 發表時間:2002-11-12 14:17:34 IP:147.8.xxx.xxx 未訂閱
引言: 把【bit2.free;】那一行攔掉就可以了, 不過再請問一下,那我bit2要如何free掉? Thanks~~
??? Did you encounter any problem in this line? I have tested the above code and it works fine on my copy of Delphi 7.
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#10 引用回覆 回覆 發表時間:2002-11-12 14:36:22 IP:61.222.xxx.xxx 未訂閱
引言:
引言: 把【bit2.free;】那一行攔掉就可以了, 不過再請問一下,那我bit2要如何free掉? Thanks~~
??? Did you encounter any problem in this line? I have tested the above code and it works fine on my copy of Delphi 7. It must cancel the code of "bit2.free" like Miles's supply code. And now I don't know how to free TBitBtn(bit2) or it's already been free?
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#11 引用回覆 回覆 發表時間:2002-11-12 14:50:22 IP:147.8.xxx.xxx 未訂閱
I have no idea, btw what error do you encounter? Can I have the code?. Since bit2 is created using the form as owner, it will be freed upon destruction of the form. By setting bit2.Parent to nil, bit2 should be invisible and it is not contained in the controls list of pan and hence it won't get any message when pan is being destroyed.
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#12 引用回覆 回覆 發表時間:2002-11-12 15:44:32 IP:61.222.xxx.xxx 未訂閱
引言: I have no idea, btw what error do you encounter? Can I have the code?. Since bit2 is created using the form as owner, it will be freed upon destruction of the form. By setting bit2.Parent to nil, bit2 should be invisible and it is not contained in the controls list of pan and hence it won't get any message when pan is being destroyed.
If I didn't delete the code of "bit2.free",it appeared the first time message.Now it worked successfully,but i don't know how to free the "bit2". Is "bit2" be free at the end of program If I never free it? Will it cost space If I run this procedure many times?
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#13 引用回覆 回覆 發表時間:2002-11-12 16:07:47 IP:147.8.xxx.xxx 未訂閱
引言: If I didn't delete the code of "bit2.free",it appeared the first time message.Now it worked successfully,but i don't know how to free the "bit2". Is "bit2" be free at the end of program If I never free it? Will it cost space If I run this procedure many times?
This sounds strange, I have no problem using Delphi 7 and I really cannot find any problem with the code... If you do not free bit2 manually, it would be destroyed upon its OWNER destruction (i.e. the form) and it does use up some resource/memory upon repeated iteration untill the form is destroyed.
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#14 引用回覆 回覆 發表時間:2002-11-13 09:04:28 IP:147.8.xxx.xxx 未訂閱
Just a thought, do not typecast using "as" in this case. i.e. (Sender as TButton) change to TButton(Sender). See if this helps.
chih
版主


發表:48
回覆:1186
積分:639
註冊:2002-04-02

發送簡訊給我
#15 引用回覆 回覆 發表時間:2002-11-13 13:24:07 IP:211.74.xxx.xxx 未訂閱
DataSource := KKDM.BufferADS; 這一句看不懂怎麼設定... 是不是有人解釋一下ㄋ?? thanks..
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#16 引用回覆 回覆 發表時間:2002-11-13 13:42:43 IP:61.222.xxx.xxx 未訂閱
引言: DataSource := KKDM.BufferADS; 這一句看不懂怎麼設定... 是不是有人解釋一下ㄋ?? thanks.. KKDM 是我DataModule的名稱 BufferACDS 是一個TClientDataSet BufferADS 是一個TDataSource
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#17 引用回覆 回覆 發表時間:2002-11-13 13:52:23 IP:61.222.xxx.xxx 未訂閱
引言: Just a thought, do not typecast using "as" in this case. i.e. (Sender as TButton) change to TButton(Sender). See if this helps. I change the code as below. procedure TRDQuotationForm.ButtonClick(Sender: TObject); var i: integer; pan: TWinControl; bit2: TButton; begin bit2 := (Sender as TButton); pan := bit2.parent; bit2.Parent := nil; for i := pan.ControlCount-1 downto 0 do pan.Controls[i].Free; pan.Free; bit2.free; RDQuotationForm.SetFocus; end; It also show the same message. How can I test bit2 existence?
chih
版主


發表:48
回覆:1186
積分:639
註冊:2002-04-02

發送簡訊給我
#18 引用回覆 回覆 發表時間:2002-11-13 13:52:30 IP:211.74.xxx.xxx 未訂閱
thanks...
引言: DataSource := KKDM.BufferADS; 這一句看不懂怎麼設定... 是不是有人解釋一下ㄋ?? thanks.. KKDM 是我DataModule的名稱 BufferACDS 是一個TClientDataSet BufferADS 是一個TDataSource
Miles
尊榮會員


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

發送簡訊給我
#19 引用回覆 回覆 發表時間:2002-11-13 16:19:34 IP:210.58.xxx.xxx 未訂閱
Hello fanny:
引言: Just a thought, do not typecast using "as" in this case. i.e. (Sender as TButton) change to TButton(Sender). See if this helps. I change the code as below. procedure TRDQuotationForm.ButtonClick(Sender: TObject); var i: integer; pan: TWinControl; bit2: TButton; begin bit2 := (Sender as TButton); pan := bit2.parent; bit2.Parent := nil; for i := pan.ControlCount-1 downto 0 do pan.Controls[i].Free; pan.Free; //bit2.free; bit2是pan的子項, 所以在pan.Controls[i].Free這個迴圈裡已經將他Free掉了若是後面在加bit2.Free這樣會錯 RDQuotationForm.SetFocus; end; It also show the same message. How can I test bit2 existence?
我不是高手, 高手是正在銀幕前微笑的人.
------


我不是高手, 高手是正在銀幕前微笑的人.
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#20 引用回覆 回覆 發表時間:2002-11-13 16:32:16 IP:61.222.xxx.xxx 未訂閱
引言: Hello fanny:
引言: Just a thought, do not typecast using "as" in this case. i.e. (Sender as TButton) change to TButton(Sender). See if this helps. I change the code as below. procedure TRDQuotationForm.ButtonClick(Sender: TObject); var i: integer; pan: TWinControl; bit2: TButton; begin bit2 := (Sender as TButton); pan := bit2.parent; bit2.Parent := nil; for i := pan.ControlCount-1 downto 0 do pan.Controls[i].Free; pan.Free; //bit2.free; bit2是pan的子項, 所以在pan.Controls[i].Free這個迴圈裡已經將他Free掉了若是後面在加bit2.Free這樣會錯 RDQuotationForm.SetFocus; end; It also show the same message. How can I test bit2 existence?
可是【bit2.Parent := nil;】這一行指令不是已經切斷了跟pan之間的關係了,若把pan釋放掉,bit2也會影響到?
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#21 引用回覆 回覆 發表時間:2002-11-13 16:44:12 IP:147.8.xxx.xxx 未訂閱
引言: Just a thought, do not typecast using "as" in this case. i.e. (Sender as TButton) change to TButton(Sender). See if this helps. I change the code as below.
procedure TRDQuotationForm.ButtonClick(Sender: TObject);
var i: integer;
    pan: TWinControl;
    bit2: TButton;
begin
//   bit2 := (Sender as TButton);
   bit2 := TButton(Sender);
   pan := bit2.parent;
   bit2.Parent := nil;
   for i := pan.ControlCount-1 downto 0 do
       pan.Controls[i].Free;
   pan.Free;
   bit2.free;
   RDQuotationForm.SetFocus;
end;
It also show the same message. How can I test bit2 existence?
Since I cannot reproduce the problem myself, would you mind testing it? 發表人 - william 於 2002/11/13 16:45:47
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#22 引用回覆 回覆 發表時間:2002-11-13 16:59:46 IP:61.222.xxx.xxx 未訂閱
引言:
引言: Just a thought, do not typecast using "as" in this case. i.e. (Sender as TButton) change to TButton(Sender). See if this helps. I change the code as below.
procedure TRDQuotationForm.ButtonClick(Sender: TObject);
var i: integer;
    pan: TWinControl;
    bit2: TButton;
begin
//   bit2 := (Sender as TButton);
   bit2 := TButton(Sender);
   pan := bit2.parent;
   bit2.Parent := nil;
   for i := pan.ControlCount-1 downto 0 do
       pan.Controls[i].Free;
   pan.Free;
   bit2.free;
   RDQuotationForm.SetFocus;
end;
It also show the same message. How can I test bit2 existence?
Since I cannot reproduce the problem myself, would you mind testing it? OK~~thanks~~ Can I ask you where the difference? 發表人 - william 於 2002/11/13 16:45:47
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#23 引用回覆 回覆 發表時間:2002-11-13 17:11:36 IP:147.8.xxx.xxx 未訂閱
引言: OK~~thanks~~ Can I ask you where the difference?
So it works for you? There are 2 ways to do type casting. The first one is directly using the type and the other is using as. I think one is using compile time information and the other is using RTTI (forget which one and whether it is correct or not). IMHO, using "as" only when you are type casting an interface and always use Txxx(xxx) kind of type cast for classes. In this case, I think that the "as" has make an interface and associate with the local variable bit2 (strange and wrong? my copy of Delphi 7 works fine...), so when the variable goes out of scope, it will need to be destroyed (codes generated by the compiler?). Since bit2 is freed already and trying to free it again will cause access violation (at the very end of the procedure since the codes are generated by the compiler).
fanny
一般會員


發表:10
回覆:26
積分:7
註冊:2002-07-19

發送簡訊給我
#24 引用回覆 回覆 發表時間:2002-11-13 17:57:21 IP:61.222.xxx.xxx 未訂閱
Yes, it can work fine.Maybe it is different from Delphi 5. Thanks for your detailed description.
Emulator
一般會員


發表:1
回覆:18
積分:8
註冊:2002-10-17

發送簡訊給我
#25 引用回覆 回覆 發表時間:2002-11-14 16:26:43 IP:163.13.xxx.xxx 未訂閱
引言:
引言: Hello fanny:
引言: Just a thought, do not typecast using "as" in this case. i.e. (Sender as TButton) change to TButton(Sender). See if this helps. I change the code as below. procedure TRDQuotationForm.ButtonClick(Sender: TObject); var i: integer; pan: TWinControl; bit2: TButton; begin bit2 := (Sender as TButton); pan := bit2.parent; bit2.Parent := nil; for i := pan.ControlCount-1 downto 0 do pan.Controls[i].Free; pan.Free; //bit2.free; bit2是pan的子項, 所以在pan.Controls[i].Free這個迴圈裡已經將他Free掉了若是後面在加bit2.Free這樣會錯 RDQuotationForm.SetFocus; end; It also show the same message. How can I test bit2 existence?
可是【bit2.Parent := nil;】這一行指令不是已經切斷了跟pan之間的關係了,若把pan釋放掉,bit2也會影響到?
Owner才是負責記憶體.. Parent只是負責重繪..=.= = Delphi - Emulator =
------
= Delphi - Emulator =
系統時間:2024-11-24 17:33:24
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!