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;