| File: | QRPrntr.pas |
| Procedure: | Multiple Fixes |
| Line #: | Not Applicable |
| Description: | Free of the TQRPrinter class. |
| Type: | Multiple Memory Leaks |
Workaround
This leak is fixed by implementing a reference counting schema.
File QRPrntr.pas - implement a reference counting schema for TQRPrinter
line : 807
TQRPrinter = class(TPersistent)
private
//Added next member and Reference counting functions
FRefCount: Integer;
public
function AddRef : Integer;
function Release : Integer;
property RefCount : Integer read FRefCount;
//END Added
private
aPrinter : TPrinter;
......
Line : 4835
//Added following two procedures :
function TQRPrinter.AddRef : Integer;
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TQRPrinter.Release : Integer;
begin
if Self <> nil then
begin
Dec(FRefCount);
if FRefCount = 0 then
begin
Destroy;
Result := 0;
Exit;
end;
Result := FRefCount;
end else
Result := 0;
end;
line : 4869
constructor TQRPrinter.Create;
begin
...
FPrinterOK := Printer.Printers.Count > 0;
//Next line Added
AddRef;
....
end;
File QuickRpt.pas
line : 3112
procedure TQRCreateReportThread.Execute;
begin
FQuickRep.CreateReport(false);
//next line commented out
// FQRPrinter.Free;
end;
line : 3186
destructor TQuickRep.Destroy;
begin
.....
FBands.Free;
//Added next 2 lines
FQRPrinter.Release;
FQRPrinter := nil;
inherited Destroy;
end;
line : 3612
function TQuickRep.PrepareQRPrinter : boolean;
var aReceiver : TWinControl;
begin
Result := Available;
if Result then
begin
if assigned(FQRPrinter) then
AReceiver := QRPrinter.MessageReceiver
else
AReceiver := nil;
//Added next line
QRPrinter.Release;
FQRPrinter := TQRPrinter.Create;
....
end;
end;
line : 3580
procedure TQuickRep.Print;
var AProgress : TQRProgressForm;
begin
AProgress := nil;
try
.......
finally
//commented out following two lines
//QRPrinter.Free;
//QRPrinter := nil;
AProgress.Free;
end;
end;
line : 3633
procedure TQuickRep.PrintBackground;
begin
if PrepareQRPrinter and QRPrinter.PrinterOK then
begin
QRPrinter.Destination := qrdPrinter;
{$ifdef win32}
BGThread := TQRCreateReportThread.Create(Self);
{$else}
CreateReport(false);
//commented out following two lines
//QRPrinter.Free;
//QRPrinter := nil;
{$endif}
end;
end;
line : 3660
procedure TQuickRep.Preview;
var aQRPrinter : TQRPrinter;
begin
AQRPrinter := nil;
....
finally
//commented out following two lines
//AQRPrinter.Free;
//QRPrinter := nil;
end;
end;
line : 4546
procedure TQRCompositeReport.CreateComposite;
var I : integer;
LastCurrentY : integer;
LastPageCount : integer;
LastColumn : integer;
aReport : TQuickRep;
begin
....
for I := 0 to Reports.Count - 1 do
begin
aReport := TQuickRep(Reports[I]);
//Added next line
aReport.QRPrinter.Release;
aReport.QRPrinter := FQRPrinter;
//Added next line
aReport.QRPrinter.AddRef;
aReport.CurrentY := LastCurrentY;
....
end;
line : 4535
destructor TQRCompositeReport.Destroy;
begin
FReports.Free;
FPrinterSettings.Free;
//next line added
FQRPrinter.Release;
inherited Destroy;
end;
line : 4598
procedure TQRCompositeReport.Print;
begin
//next line added
FQRPrinter.Release;
FQRPrinter := TQRPrinter.Create;
FQRPrinter.Destination := qrdPrinter;
CreateComposite;
end;
line : 4610
procedure TQRCompositeReport.Preview;
begin
//next line added
FQRPrinter.Release;
FQRPrinter := TQRPrinter.Create;
FQRPrinter.Preview;
CreateComposite;
end;
line : 4622
procedure TQRCompositeReport.Prepare;
begin
//next line added
FQRPrinter.Release;
FQRPrinter := TQRPrinter.Create;
CreateComposite;
end;
File QRPrev.pas
line : 69
TQRStandardPreview = class(TForm)
....
public
constructor CreatePreview(AOwner : TComponent; aQRPrinter : TQRPrinter);virtual;
//added next line
destructor Destroy;override;
......
Line : 80
constructor TQRStandardPreview.CreatePreview(AOwner : TComponent; aQRPrinter : TQRPrinter);
begin
inherited Create(AOwner);
QRPrinter := aQRPrinter;
//Added next line
QRPrinter.Addref;
....
end;
line 110
//added destructor
destructor TQRStandardPreview.Destroy;
begin
QRPrinter.Release;
QRPrinter := nil;
inherited Destroy;
end;