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;