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

请教FreeAndNil这个如何使用?

尚未結案
jtp
初階會員


發表:39
回覆:81
積分:29
註冊:2003-04-20

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-12 09:30:44 IP:218.18.xxx.xxx 未訂閱
代码如下:但运行出错 procedure TForm_caseembryo1.Button1Click(Sender: TObject); var i:integer; begin for i:=0 to ScrollBox1.ComponentCount - 1 do begin if ScrollBox1.Components[i] is TImage then FreeAndNil(TImage(ScrollBox1.Components[i])); end; end; 出错提示为:[Error] caseembryo1.pas(1375): Constant object cannot be passed as var parameter请问该如何改正?
william
版主


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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-05-12 09:41:27 IP:147.8.xxx.xxx 未訂閱
Shoud not use FreeAndNil here, e.g.
procedure TForm_caseembryo1.Button1Click(Sender: TObject);
var
     i:integer;
begin
     for i:=0 to ScrollBox1.ComponentCount - 1 do
     begin
        if ScrollBox1.Components[i] is TImage then
             ScrollBox1.Components[i].Free;
     end;
end;
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-05-12 09:42:58 IP:218.16.xxx.xxx 未訂閱
FreeAndNil 是要直接指給一個變數的    若你主要是要 Free 所有 TImage, 你應用 :
for i:= ScrollBox1.ComponentCount - 1 downto 0 do // 要 Delete 東西一定要從尾做起
begin
  if ScrollBox1.Components[i] is TImage then
    TImage(ScrollBox1.Components[i]).Free;
end;
提醒一點,若你的 TImage 是動態產生的沒問題,若是在 Design 時已有的你 Free了原本 Form有的東西到 FormClose 時可能會出錯。
jtp
初階會員


發表:39
回覆:81
積分:29
註冊:2003-04-20

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-05-12 09:56:45 IP:218.18.xxx.xxx 未訂閱
我按照两位提出的方法去运行,但都会出错,我的image是动态产生的,请问还有其它什么好的建议吗?
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-05-12 10:27:53 IP:218.16.xxx.xxx 未訂閱
忘了一點 Components 是 Form 的 要在 ScrollBox 做是 Controls 罷 即 : for i:= ComponentCount - 1 downto 0 do // 要 Delete 東西一定要從尾做起 begin   if Components[i] is TImage then     Components[i].Free; end; for i:= ScrollBox1.ControlCount - 1 downto 0 do // 要 Delete 東西一定要從尾做起 begin if ScrollBox1.Controls[i] is TImage then ScrollBox1.Controls[i].Free; end; 不過 William 兄和小弟的 程式碼應不會出錯丫,只是Free不了罷了,請問是甚麼錯誤訊息呢 ? 發表人 - Justmade 於 2003/05/12 10:29:26
jtp
初階會員


發表:39
回覆:81
積分:29
註冊:2003-04-20

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-05-12 10:50:07 IP:218.18.xxx.xxx 未訂閱
运行还是出错,不管是用controls还是Component.出错就弹出CPU调试窗口
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-05-12 10:59:56 IP:218.16.xxx.xxx 未訂閱
我測試過沒問題.... 你是甚樣動態建立的 ?可否貼你建立 Timage 的 function 出來
jtp
初階會員


發表:39
回覆:81
積分:29
註冊:2003-04-20

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-05-12 11:16:32 IP:218.18.xxx.xxx 未訂閱
是这样被建立 的: procedure TForm_caseembryo1.ReArrangeImages; var i, ImageW, ImageH, OffSet, CurrentX, CurrentY : integer; begin ImageW := 440; ImageH := 175; OffSet := 5; CurrentX := 0; CurrentY := 0; for i := 0 to ScrollBox1.ComponentCount - 1 do begin if ScrollBox1.Components[i] is TImage then with TImage(ScrollBox1.Components[i]) do begin Parent := ScrollBox1; Width := ImageW; Height := ImageH; Left := CurrentX OffSet; Top := CurrentY OffSet; proportional:=true; if ScrollBox1.Width<(CurrentX 2 * OffSet ImageW ) then begin CurrentX := 0; CurrentY := CurrentY 2 * OffSet ImageH; end else CurrentX := CurrentX 2 * OffSet ImageW; end; end; end;
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-05-12 11:26:07 IP:218.16.xxx.xxx 未訂閱
你這不是動態建立耶... 你這只是改變 TImage 的參數罷了 (那些 TImage 本身已存在) 你那些 TImage 是在設計時已放上了 Form 的嗎? 若是的話我之前都說了會出問題 還是在 別處 TImagel.Create(self) 的呢 ?
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-05-12 11:27:01 IP:61.155.xxx.xxx 未訂閱
你这样定义就不会出错的! procedure TForm1.Button1Click(Sender: TObject); var i:integer; tmpimage:timage; begin for i:=0 to ScrollBox1.ComponentCount - 1 do if ScrollBox1.Components[i] is TImage then begin tmpimage:=TImage(ScrollBox1.Components[i]); FreeAndNil(tmpimage); end; end; 风花雪月 e梦情缘
------
风花雪月 e梦情缘
jtp
初階會員


發表:39
回覆:81
積分:29
註冊:2003-04-20

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-05-12 11:34:07 IP:218.18.xxx.xxx 未訂閱
1.我的image是动态建立的,我并没有添加image控件 2.wnhoo: 我运行你的提示程序,出错如下:list index out of bounds(60),请问该如何解决?
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-05-12 12:18:00 IP:218.16.xxx.xxx 未訂閱
你能否貼出動態建立的程式碼 ?? 你上次貼的只是修改 Timage 程式碼並沒有建立的碼。
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-05-12 13:17:35 IP:61.155.xxx.xxx 未訂閱
1.我的image是动态建立的,我并没有添加image控件 2.wnhoo: 我运行你的提示程序,出错如下:list index out of bounds(60),请问该如何解决? --------------------------------------------------- //下面的代码,测试OK unit Unit1;    interface    uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls, jpeg, ExtCtrls;    type   TForm1 = class(TForm)     ScrollBox1: TScrollBox;     Button1: TButton;     Button3: TButton;     procedure Button1Click(Sender: TObject);     procedure Button3Click(Sender: TObject);   private     { Private declarations }   public     { Public declarations }   end;    var   Form1: TForm1;   totalrun:integer=5; implementation    {$R *.dfm}    procedure TForm1.Button1Click(Sender: TObject); var i:integer; tmpimage:timage; begin tmpimage:=timage.Create(nil); //修改一下 for i:=ScrollBox1.ComponentCount - 1 downto 0 do if ScrollBox1.Components[i] is TImage then begin tmpimage:=TImage(ScrollBox1.Components[i]); FreeAndNil(tmpimage); end; tmpimage.Free ; end; //动态创建 procedure TForm1.Button3Click(Sender: TObject); var image:timage; begin image:=timage.Create(ScrollBox1); image.Top:=20 totalrun; image.Left:=20 totalrun; image.Width:=75; image.Height:=75; image.Picture.LoadFromFile('c:\spy.jpg'); image.Align :=alNone; image.Visible:=true; image.Parent :=ScrollBox1; totalrun:=totalrun 5; end; end. 供参考!!!! 风花雪月 e梦情缘
發表人 - wnhoo 於 2003/05/12 13:21:34
------
风花雪月 e梦情缘
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-05-12 13:39:13 IP:218.16.xxx.xxx 未訂閱
引言: procedure TForm1.Button1Click(Sender: TObject); var i:integer; tmpimage:timage; begin tmpimage:=timage.Create(nil); //修改一下 for i:=ScrollBox1.ComponentCount - 1 downto 0 do if ScrollBox1.Components[i] is TImage then begin tmpimage:=TImage(ScrollBox1.Components[i]); FreeAndNil(tmpimage); end; tmpimage.Free ; end;
FreeAndNil 的程式碼 : procedure FreeAndNil(var Obj); var Temp: TObject; begin Temp := TObject(Obj); Pointer(Obj) := nil; Temp.Free; end; 特意做個TmpImage 然後來 FreeAndNil,除了執行比較慢(因多做沒用的動作)之外,跟本上就和直接 ScrollBox1.Components[i].Free 沒兩樣。 始終估計是出在 Create 身上但不一定。若你用 Wnhoo 兄提供的 Create 方法,我一開始的程式碼便應沒問題,但若你創建方法不同,請post出來大家幫你改善。
danny
版主


發表:100
回覆:522
積分:595
註冊:2002-03-11

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-05-12 14:15:01 IP:211.76.xxx.xxx 未訂閱
[quote] 1.我的image是动态建立的,我并没有添加image控件 2.wnhoo: 我运行你的提示程序,出错如下:list index out of bounds(60),请问该如何解决?
procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
  tmpimage:timage;
begin
  tmpimage:=timage.Create(ScrollBox1);
  for i:=ScrollBox1.ComponentCount - 1  downto 0 do
  ] if ScrollBox1.Components[i] is TImage then
    begin
      tmpimage:=TImage(ScrollBox1.Components[i]);
      FreeAndNil(tmpimage);
    end;      tmpimage.Free ;
end;
紅色部份很奇怪! 如果tmpimage 是物件參考變數, 是無需 Create 的(這樣會有 Memory leak 問題) 如果tmpimage 本來就需要 Create 的話, 他的 Owner 卻不是 ScrollBox1 真奇怪!
------
將問題盡快結案也是一種禮貌!
jtp
初階會員


發表:39
回覆:81
積分:29
註冊:2003-04-20

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-05-13 15:03:48 IP:218.18.xxx.xxx 未訂閱
我的timage是这样创建的 procedure TForm_caseembryo1.SpeedButton1Click(Sender: TObject); begin if qry1.Active=false then exit; Qry1.First; while not Qry1.Eof do begin with timage.Create(ScrollBox1) do Picture.LoadFromFile(Qry1.FieldByname('picpath').asstring); Qry1.Next; end; ReArrangeImages; end;
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-05-13 15:59:14 IP:61.155.xxx.xxx 未訂閱
//动态创建修改如下: procedure TForm_caseembryo1.SpeedButton1Click(Sender: TObject); var image:timage; I:INTEGER; begin I:=0; if qry1.Active=false then exit; Qry1.First; while not Qry1.Eof do BEGIN image:=timage.Create(ScrollBox1); image.Top:=20+I; image.Left:=20+I; image.Width:=75; image.Height:=75; IMAGE.Picture.LoadFromFile(Qry1.FieldByname('picpath').asstring); image.Align :=alNone; image.Visible:=true; image.Parent :=ScrollBox1; Qry1.Next; I:=I+5; END; END;    释放参见,我上面的发表的代码    1.我的image是动态建立的,我并没有添加image控件 2.wnhoo: 我运行你的提示程序,出错如下:list index out of bounds(60),请问该如何解决? --------------------------------------------------- //下面的代码,测试OK unit Unit1;    interface    uses    .......................    风花雪月 e梦情缘
------
风花雪月 e梦情缘
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-05-13 16:30:13 IP:218.16.xxx.xxx 未訂閱
以下是我測試的程式,除了因為我沒你的數據庫而改成load十次同一張圖外,其他創建及 ReArrangeImage程式碼完全似照你的碼,並加上小弟最初 Post 的移除程式碼 (參考了 william 兄的不用 Typecast 成 TImage 來 Free 使其更頪要)。    測試過完全沒問題,我敢說你若開一新專案並將 load image 處改回你 query 的 load 法亦不會有問題。    我亦試過在 ScrollBox1 加上其他元件亦沒有問題。所以應是你的程式其他部份出錯。你最後每步看看到底是執行到甚麼時出錯的。    
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  ComCtrls, DateUtils, StdCtrls, ExtCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ScrollBox1: TScrollBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    procedure ReArrangeImages;
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.ReArrangeImages;
var
i, ImageW, ImageH, OffSet, CurrentX, CurrentY : integer;
begin
  ImageW := 440; ImageH := 175; OffSet := 5;
  CurrentX := 0;
  CurrentY := 0;
  for i := 0 to ScrollBox1.ComponentCount - 1 do
  begin
    if ScrollBox1.Components[i] is TImage then
      with TImage(ScrollBox1.Components[i]) do
      begin
        Parent := ScrollBox1;
        Width := ImageW;
        Height := ImageH;
        Left := CurrentX   OffSet;
        Top := CurrentY   OffSet;
        proportional:=true;
    if ScrollBox1.Width<(CurrentX   2 * OffSet   ImageW ) then
    begin
      CurrentX := 0;
      CurrentY := CurrentY   2 * OffSet   ImageH;
    end else
      CurrentX := CurrentX   2 * OffSet   ImageW;
    end;
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
  For i := 1 to 10 do
  with timage.Create(ScrollBox1) do
    Picture.LoadFromFile('D:\Temp\Temp.bmp');
  ReArrangeImages;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
var i : integer;
begin
  for i:= ScrollBox1.ComponentCount - 1 downto 0 do // 要 Delete 東西一定要從尾做起
  begin
    if ScrollBox1.Components[i] is TImage then
      ScrollBox1.Components[i].Free;
  end;
end;    end.
系統時間:2024-06-02 20:19:31
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!