+ -
当前位置:首页 → 问答吧 → 动态创建的TImage,在关闭窗体时候报错,请问如何解决

动态创建的TImage,在关闭窗体时候报错,请问如何解决

时间:2011-09-23

来源:互联网

动态创建的TImage,在关闭窗体时候报错,请问如何解决?加了释放代码 还是不行

创建代码:
  //新建立的图块基础属性设置
  img_tile := TImage.Create(GroupBox2);
  img_tile.Picture.Assign(loadImages[tmpImgID].imgByteData);
  img_tile.Transparent := true ;
  //新建立的图块编辑器属性设置
  img_tile.Parent := GroupBox2 ;
  img_tile.AutoSize := true ;
  img_tile.Visible := true ;



释放代码:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  i : Integer ;
  tmpImg : TImage;

begin
  for i:= 0 to GroupBox2.ControlCount-1 do
  begin
  //获取控件名Components[i].Name
  if GroupBox2.Controls[0] is TImage then
  begin
  tmpImg := TImage(GroupBox2.Controls[0]); //跟踪过了 全部释放
  FreeAndNil(tmpImg);
  end ;
  end;
end;




追踪了下确定是由于动态TImage问题引起的。 如果没创建TImage一切正常,一旦创建了TImage就算将其Free依然在关闭窗体时候报错?请问如何解决

作者: huruihappy   发布时间: 2011-09-23

if GroupBox2.Controls[0] is TImage then
  begin
  tmpImg := TImage(GroupBox2.Controls[0]); //跟踪过了 全部释放
  FreeAndNil(tmpImg);
  end ;
 应该是controls[i]

作者: funxu   发布时间: 2011-09-23

GroupBox2.Controls[0],你一直用的是索引 0,那你还遍历有啥用,第一次被释放了,第二次肯定就不存在了,你还操作它肯定出错

作者: bdmh   发布时间: 2011-09-23

使用类似的
img_tile := TImage.Create(GroupBox2);代码,无需手动释放

如果使用
img_tile := TImage.Create(nil);
方式,就需要手动释放了。看看delphi源码就知道了。

作者: SmallHand   发布时间: 2011-09-23

for i:= GroupBox2.ControlCount-1 downto 0 do
begin
  if GroupBox2.Controls[i] is TImage then
  begin
  TImage(GroupBox2.Controls[i]).free; 
  end ;
end;

作者: mdejtod   发布时间: 2011-09-23

另外释放时也不要从0开始循环会出错的,应该逆序释放

作者: funxu   发布时间: 2011-09-23

哇塞2,3,4L好几位大神啊,喝口水的功夫就被抢答了..........

作者: funxu   发布时间: 2011-09-23

试了一下,没有你说的情况
估计是其他地方的问题

作者: m617105   发布时间: 2011-09-23

引用 2 楼 bdmh 的回复:
GroupBox2.Controls[0],你一直用的是索引 0,那你还遍历有啥用,第一次被释放了,第二次肯定就不存在了,你还操作它肯定出错


基础问题,动态创建的控件删除是0还是i 照着代码试1遍不就知道了,不做多解释。

作者: huruihappy   发布时间: 2011-09-23

引用 3 楼 smallhand 的回复:
使用类似的
img_tile := TImage.Create(GroupBox2);代码,无需手动释放

如果使用
img_tile := TImage.Create(nil);
方式,就需要手动释放了。看看delphi源码就知道了。


2种创建和释放的都试过 完全没效果

作者: huruihappy   发布时间: 2011-09-23

引用 7 楼 m617105 的回复:
试了一下,没有你说的情况
估计是其他地方的问题


谢谢 我自己解决了确实不是这个问题引起的。

创建代码后面有一段给Record的代码赋值,是由于Record定义的变量位置引起的,
按道理来说不应该有此问题,由此我怀疑的Delphi的编译BUG。

原Record结构:
  // 图块数据
  TImgTileData = record
  id: Integer ;
  imgName : ShortString ; //图片名
  x: Integer; //X 坐标
  y: Integer; //Y 坐标
  w: Integer; //宽
  h: Integer; //高
  imgPath : ShortString ; //路径
  level : Integer ; //所处图层
  logicSt : byte ; //逻辑状态
  isCanMov : Boolean ; //是否可以移动
  isEnabled : Boolean ; //是否可用
  end ;


改动后:
  // 图块数据
  TImgTileData = record
  isCanMov : Boolean ; //是否可以移动
  isEnabled : Boolean ; //是否可用
  id: Integer ;
  imgName : ShortString ; //图片名
  x: Integer; //X 坐标
  y: Integer; //Y 坐标
  w: Integer; //宽
  h: Integer; //高
  imgPath : ShortString ; //路径
  level : Integer ; //所处图层
  logicSt : byte ; //逻辑状态

  end ;


我定义完全没变,只是改变了结构体的数据的排列方式,就OK了。

作者: huruihappy   发布时间: 2011-09-23

1楼的回答过了。删除要从最后一个向前删除。
象你这种总是删除第一个不能用 for 循环,要用 while循环,其实用 while循环也不合适,因为得能保证
GroupBox2里只有 Timage类型才行。

作者: ZyxIp   发布时间: 2011-09-23

引用 11 楼 zyxip 的回复:
1楼的回答过了。删除要从最后一个向前删除。
象你这种总是删除第一个不能用 for 循环,要用 while循环,其实用 while循环也不合适,因为得能保证
GroupBox2里只有 Timage类型才行。

谢谢您的建议。 但是我觉得2种办法可能差不多

作者: huruihappy   发布时间: 2011-09-23