Page 1 of 1

AV with Chart and Grid

Posted: Fri Jun 16, 2006 5:01 am
by 9337351
Application with a TPanel, TChart and a TChartGrid (with Chart set to Chart1) on a Form that cause AV whenever the mouseMove event is triggered from the TPanel.

To reproduce:

New Application
Drop on a Tpanel, TChart and TChartGrid and set the Chart property of the Chart Grid to the Chart.

Move the mouse around in the panel. The AV will occur after mouse movement - sometimes immediately and sometimes after several movements

Code:

procedure TForm1.ChangeValues;
var
i: Integer;
begin
chart1.SeriesList.ClearValues;
for i := 0 to chart1.SeriesCount - 1 do
chart1.Free;
chart1.AddSeries(tbarseries.Create(self));
chart1.Title.Caption := 'test';
for i := 0 to 9 do
begin
chart1.Series[0].Add(round(random(99)));
application.ProcessMessages;
end;
end;

procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y:
Integer);
begin
changevalues;
end;


AV:

exception number : 1
exception class : EAccessViolation
exception message : Access violation at address 004B3DC2 in module 'Project2.exe'. Read of address 009C2424.

main thread ($57c):
004b3dc2 +006 Project2.exe TeEngine TChartSeries.Count
004e311f +06b Project2.exe TeeChartGrid MaxNumPoints
004e3482 +0b6 Project2.exe TeeChartGrid TCustomChartGrid.RecalcDimensions
004e3608 +038 Project2.exe TeeChartGrid TCustomChartGrid.TeeEvent
004c7b8b +047 Project2.exe TeeProcs TCustomTeePanel.BroadcastTeeEvent
004b7d84 +044 Project2.exe TeEngine TCustomAxisPanel.BroadcastSeriesEvent
004b7ac8 +020 Project2.exe TeEngine TCustomAxisPanel.RemoveSeries
004b7a9f +017 Project2.exe TeEngine TCustomAxisPanel.RemoveSeries
004b1dbb +013 Project2.exe TeEngine TChartSeries.SetParentChart
004d4a59 +005 Project2.exe Series TCustomBarSeries.SetParentChart
004b1491 +021 Project2.exe TeEngine TCustomChartElement.Destroy
004b1bc4 +0bc Project2.exe TeEngine TChartSeries.Destroy
004d480c +028 Project2.exe Series TCustomBarSeries.Destroy
00403cc4 +008 Project2.exe System TObject.Free
004e3b93 +03b Project2.exe Unit1 35 +3 TForm1.ChangeValues
004e3c3f +003 Project2.exe Unit1 48 +1 TForm1.Panel1MouseMove
00483550 +024 Project2.exe Controls TControl.MouseMove
004835ca +06e Project2.exe Controls TControl.WMMouseMove
004830b4 +188 Project2.exe Controls TControl.WndProc
00485fff +157 Project2.exe Controls TWinControl.WndProc
00485c7c +02c Project2.exe Controls TWinControl.MainWndProc
0046b3d0 +014 Project2.exe Classes StdWndProc
77d496c2 +00a user32.dll DispatchMessageA
004a119f +083 Project2.exe Forms TApplication.ProcessMessage
004a11d6 +00a Project2.exe Forms TApplication.HandleMessage
004a1406 +096 Project2.exe Forms TApplication.Run

Posted: Fri Jun 16, 2006 11:40 am
by narcis
Hi NREL,

We could reproduce the issue you report here. You should avoid OnMouseMove reentrancy by doing something like this:

Code: Select all

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, TeeChartGrid, TeeProcs, TeEngine, Chart, ExtCtrls, Series,
  ComCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Chart1: TChart;
    procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { Private declarations }
    InMouseMove : Boolean;

    procedure ChangeValues;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ChangeValues;
var i: Integer;
begin

  chart1.SeriesList.ClearValues;

  for i := 0 to chart1.SeriesCount - 1 do
    chart1[i].Free;

  chart1.AddSeries(tbarseries.Create(self));

  chart1.Title.Caption := 'test';
   chart1.Series[0].Clear;

  for i := 0 to 9 do
  begin
    chart1.Series[0].Add(round(random(99)));
    application.ProcessMessages;
  end;

end;


procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if not InMouseMove then
  begin
    InMouseMove:=True;
    try
      ChangeValues;
    finally
      InMouseMove:=False;
    end;
  end;
end;

end.