Page 1 of 1

Exception when creating and removing tools via code

Posted: Wed Jan 12, 2005 8:40 am
by 8441042
When creating tools (annotation tools) dynamicaly at runtime, an exception is generated when the tools are removed and then free'd.

Sample code below:

Code: Select all

procedure TViewAnalyzer.HideZoneOverlay;
var
  i : integer;
begin
  for i := 0 to 19 do //max of 20 zones and annotations
  begin
    if (FSessionZoneBands[i] <> nil) then
    begin
      DBChartSession.Tools.Remove(FSessionZoneBands[i]);   
      FSessionZoneBands[i].Free;

      FSessionZoneBands[i] := nil;
    end;
    if (FSessionZoneNames[i] <> nil) then
    begin
      DBChartSession.Tools.Remove(FSessionZoneNames[i]);   
      FSessionZoneNames[i].Free; //! causes an exception
      FSessionZoneNames[i] := nil;
    end;     
  end;
end;
If the statement to free the tool is removed, the exception does not occur BUT all the annotations are not drawn (which is correct) except for one annotation that remains on the chart...

Help needed!!!!!

See the following post to under stand the context - the same code worked before moving the code to the OnBeforeDraw event

Posted: Wed Jan 12, 2005 9:06 am
by Marjan
Hi.

Do you use any other tools ? If not, then the simplest solution to remove/free all annotations is simply to call dbChart1.Tools.Clear; instead of for loop. Or use the following code:

Code: Select all

var tool: TTeeCustomTool;
begin
  While Chart1.Tools.Count > 0 do
  begin
    tool := Chart1.Tools[0];
    Chart1.Tools.Delete(0);;
    tool.Free;
  end;
end;
I'd use the first approach (Tools.Clear) to clear/free all annotations from chart tools collection. I've placed the code in Chart OnBeforeDrawSeries event and it worked just fine (no AV errors).

Other tools used

Posted: Wed Jan 12, 2005 10:13 am
by 8441042
I do use other tools and more will be added dynamicaly as well and I cannot call a clear all.

See the test project for an example of the error

Posted: Thu Jan 13, 2005 11:24 am
by Marjan
Hi.
I do use other tools and more will be added dynamicaly as well and
In that case you'll have to use the Delete+Free approach I posted in my previous reply, but for individual tool in tools list. Also, don't forget that once you delete/free specific tool from tool list, Tools.Count is decreased by one (so a simple for loop might not do the trick). I guess the safest way would be to:
1) Try to find a match for FSessionZoneBands tool in Tools.Items
2) Use matched tool index and delete and free the specific tool from tool collection (see my code in previous post)
3) Finally, free FSessionZoneBands .