Access violation when closing Preview Form
My specific application is much to complicated to give a good example. When
a preview of a report is closed, I get an access violation. This does not
happen every time, but it seems to vary between different computers that I
run the report on. I am currently using Delphi 5.0 (Build 2195 Service Pack
1), with Report Builder 6.03 standard edition.
If I run the following code on a test project, to rapidly create, print and
destroy reports, I also get an access violation.
This problem started since I started to use V6.03 instead of V5.xxx, because
5.xxx seemed to have a problem with "ShiftRelativeTo" properties when sub
reports with multiple columns were used.
Did anybody else experience any similar problems?
Regards
Ludek
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
ppReport;
procedure TForm1.Button1Click(Sender: TObject);
var rpt: TppReport;
i: integer;
begin
for i := 1 to 100000 do
begin
rpt := TppReport.Create(self);
try
rpt.ModalPreview := False;
rpt.Print;
finally
FreeAndNil(rpt);
end;
end;
end;
end.
a preview of a report is closed, I get an access violation. This does not
happen every time, but it seems to vary between different computers that I
run the report on. I am currently using Delphi 5.0 (Build 2195 Service Pack
1), with Report Builder 6.03 standard edition.
If I run the following code on a test project, to rapidly create, print and
destroy reports, I also get an access violation.
This problem started since I started to use V6.03 instead of V5.xxx, because
5.xxx seemed to have a problem with "ShiftRelativeTo" properties when sub
reports with multiple columns were used.
Did anybody else experience any similar problems?
Regards
Ludek
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
ppReport;
procedure TForm1.Button1Click(Sender: TObject);
var rpt: TppReport;
i: integer;
begin
for i := 1 to 100000 do
begin
rpt := TppReport.Create(self);
try
rpt.ModalPreview := False;
rpt.Print;
finally
FreeAndNil(rpt);
end;
end;
end;
end.
This discussion has been closed.
Comments
In my testing with your code with Delphi 5 and ReportBuilder 7.03, I was not
able to recreate an AV. This could have been an issue that has been fixed
for the latest release. Please try downloading a trial copy of
ReportBuilder 7.03 and testing with that.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
TppCustomReport.Notify was under certain conditions called AFTER the
destructor TppCustomReport.Destroy, leaving FTemplate with the pointer to
the destroyed FTemplate. The reference to FTemplate in
TppCustomReport.Notify then cause access violations.
So I "Modified" rbRCL55.dpk = > rbRCL55.bpl unit ppClass.Pas to get rid of
access violation when closing report preview
By setting FTemplate = nil just after it is freed, and checking for
FTemplate = nil before accessing FTemplate as an object in
TppCustomReport.Notify, the problem seemed to be resolved for the cases
where I could duplicate it.
TppCustomReport = class(TppProducer)
private
......
FTemplate: TppReportTemplate;
....
1. destructor TppCustomReport.Destroy;
begin
.........
.........
{free TPersistent objects}
FTemplate.Free;
{ LDK!!! } FTemplate := nil; // I added this line ...
.........
end;
.............
2. { TppCustomReport.Notify }
procedure TppCustomReport.Notify(aCommunicator: TppCommunicator; aOperation:
TppOperationType);
begin
inherited Notify(aCommunicator, aOperation);
......
else
if assigned(FTemplate) and { LDK !!!! } // I added this line too..
(FTemplate.DatabaseSettings.DataPipeline = aCommunicator) then
FTemplate.DatabaseSettings.DataPipeline := nil;
end; {procedure, Notify}