窗体里有tchart控件,动态生了一些checkbox,勾选checkbox作图,在关闭窗体时报错,代码如下:
//这是释放控件过程,在窗体close事件里有调用.
procedure TFrmHB.FreeFormCtrl();
var i,igroup:integer;
begin
try
  for igroup:=self.PageControl1.PageCount-1 downto 0  do begin
     for i:=self.PageControl1.Pages[igroup].ControlCount-1 downto 0 do begin
         self.PageControl1.Pages[igroup].Controls[i].Free;
     end;
  end;
  for i:=self.GroupBox1.ControlCount-1 downto 0 do begin
    self.GroupBox1.Controls[i].Free;
  end;
  for i:=self.Chart1.SeriesCount-1 downto 0 do begin
     self.Chart1.Series[i].Free;
  end;except
    on e:erangeerror do
    begin
      messagedlg(e.Message,mterror,[mbok],0);
    end;
end;
//这是生成控件的过程   在点击作图按留时调用
procedure TFrmHB.setItemView();
var
  pColorBox: TColorBox;
  pCheckBox: TCheckBox;
  intTop,intLeft,intCell,colorid:integer;
  ssql,itemcode,itemName:string;
begin
intCell:=1;inttop:=20;intleft:=10;
  ssql:='SELECT * FROM V_UserView where userid=' + self.userid + ' and fitemcode<>''sstate'' order by forder';
  customerdata.GetAdoQuery(ssql);
  if customerdata.ADOQuery1.IsEmpty then exit;
try
  while not customerdata.ADOQuery1.Eof do begin
     if not customerdata.ADOQuery1.FieldByName('FitemName').IsNull then begin
        itemName:= customerdata.ADOQuery1.FieldValues['FitemName'];
        if not customerdata.ADOQuery1.FieldByName('fitemcode').IsNull then begin
           itemcode:=customerdata.ADOQuery1.FieldValues['fitemcode'];
        end;
        if not customerdata.ADOQuery1.FieldByName('colorindex').IsNull then begin
           colorid:=strtoint(customerdata.ADOQuery1.FieldValues['colorindex']);
        end else begin
          colorid:=0;
        end;
        pCheckBox:=TCheckBox.Create(self);
        pcheckbox.Parent:=self.GroupBox1 ;
        pCheckBox.Caption:= itemName;        pcheckbox.Name:='pcheckbox'+  itemcode;
        pcheckbox.Hint:=inttostr(intCell);
        if intcell<=2 then pcheckbox.Checked:=true;
        pcheckbox.Width:=70;
        pcheckbox.Top:=inttop;
        pcheckbox.Left:= intLeft;
        pcheckbox.OnClick:=myCheckBoxClick;        pColorBox:=TColorBox.Create(self);
        pColorBox.Parent:=self.GroupBox1 ;
        pColorBox.Name:='pColorBox' + itemcode;
        pColorBox.Hint:=inttostr(intCell);
        pColorBox.ItemIndex:=colorid;
        pColorBox.Width:=40;
        pColorBox.Top:= pcheckbox.top;
        pColorBox.Left:=pcheckbox.Left+pcheckbox.Width;
        pColorBox.OnChange:=myColorBoxChange;
        intCell:=intCell+1;
        if self.GroupBox1.ControlCount =10 then begin
           inttop:=inttop+20;
           intleft:=10;
        end else begin
           intleft:=intleft+pcolorbox.Width+pcheckbox.Width;
        end;
     end;
     customerdata.ADOQuery1.Next;
  end;
finally
   customerdata.ADOQuery1.Close;
   customerdata.pubCnn.Close;
end;end;
//这是作图的过程  在myColorBoxChange   myCheckBoxClick都有调用
procedure TFrmHB.DrawWhole();
var
  pSeries:tFastLineSeries;
  i,ii,intSeries,intCell:integer;
  tmpHorizAxis:TchartAxis;
  pColorBox: TColorBox;
  pCheckBox: TCheckBox;
  colorboxname:string;
begin
if pUnitp=nil then exit ;
try
  self.Chart1.CustomAxes.Clear;
  self.Chart1.SeriesList.Clear;  for i:=0 to self.GroupBox1.ControlCount-1 do begin
    if self.GroupBox1.Controls[i].ClassName='TCheckBox' then begin
       pCheckBox:= TCheckBox(self.GroupBox1.Controls[i]);
       if pCheckBox.Checked then begin
          colorboxname:=stringreplace(pCheckBox.Name,'pcheckbox','pColorBox',[rfReplaceAll]);
          pColorBox:=TColorBox(self.GroupBox1.FindChildControl(colorboxname));
          pSeries:=TFastLineSeries.Create(self);
          self.Chart1.AddSeries(pSeries);
          pSeries.SeriesColor:= pColorBox.Selected;
          pSeries.xValues.Order:=lonone;
          pSeries.xValues.Sort;
          pSeries.YValues.Order:=loascending;
          pSeries.YValues.Sort;
          pSeries.Title:=pCheckBox.Caption; {//}
          intCell:=strtoint(pCheckBox.Hint);
          for ii:=0 to high(pUnitp.arr_Sd_Jiao_P_T) do begin
           pSeries.AddXY(strtofloat(self.StringGrid1.Cells[intCell,ii+1]),strtofloat(self.StringGrid1.Cells[0,ii+1]));
          end;
          if self.chbsame.Checked=false then begin
            self.Chart1.CustomAxes.Add;
            intSeries:= self.Chart1.CustomAxes.Count-1;
            tmpHorizAxis:=self.Chart1.CustomAxes[intSeries];
            tmpHorizAxis.Horizontal:=true;
            tmpHorizAxis.Axis.Color:=pColorBox.Selected;
            tmpHorizAxis.PositionPercent:=100+self.Chart1.CustomAxes.Count*3;
            tmpHorizAxis.LabelsSize:=5;
            tmpHorizAxis.LabelsFont.Size:=7;
            self.Chart1.AxisBehind:=false;
            pSeries.CustomHorizAxis:=tmpHorizAxis;
          end;
       end
    end;
  end;
except
  on e:erangeerror do
     messagedlg(e.Message,mterror,[mbok],0);
end;
end;

解决方案 »

  1.   

    注意释放的顺序你先释放GroupBox里面的控件,再释放GroupBox,再释放Page
      

  2.   

    pColorBox:=TColorBox.Create(self); 
    使用self创建的控件,无须手工释放。系统会自动递归释放
    pColorBox:=TColorBox.Create(nil); 
    需要手工释放的。解决方法:去掉对FreeFormCtrl过程的调用即可。
      

  3.   

    要是写成 TCheckBox.Create(self) 没有必要在窗体关闭的时候自己释放。TCheckBox.Create(nil) 的时候才需要自己释放释放时应该先释放容器内部的控件,在释放外层的.如果在绘图的过程中有访问到这些个控件,在释放时应该停止执行绘图的过程。
    否则在Close 事件中可能控件让释放了,但绘制过程还是会访问的。
      

  4.   

    create参数为application何self都无需手工释放,参数为nil时才需要手工释放
      

  5.   

    找到错误了,谢谢各位提醒。  是这一句的错误 ,
       self.Chart1.SeriesList.Clear; 
    这个问题,让我改了两天了。