7
votes

My Delphi application has a form that uses the Acrobat Reader ActiveX control for viewing pdfs. When I use the control's functions (LoadFile, gotoNextPage, gotoPreviousPage, gotoFirstPage, gotoLastPage), then close the form, I get the following error: "Access violation at address 6AF5703C. Read of address 6AF5703C". When I run the app, but do not use the control's functions, and then close the form, the app will exit without error.

Anyone know of a fix or workaround for this issue?

My app is written using Delphi 5 (legacy app). I have Adobe Acrobat Reader DC v15.016.20045 installed.

2
It's years since I used the TPDF object (import of PDFLib_Tlb.Pas) and I can't get it to run under Win10, but have you tried setting the FIntf member of the TPDF instance to Nil before you close your form? That would be the first thing I'd try. Btw despite the "F" prefix, FIntf is a public member. - MartynA
similar with modern version of Delphi (DX10 including). i spent hours trying to find solution, but without success. rebuilding and modifying AdobeTlb file didn't help. i didn't try solution from @MartynA yet :) so far my code for release Adobe control in try except block - Zam
@Zam, I installed the current version of Reader DC and am getting the same problem, so far w/o solution. The Active X no longer has a public FIntf member, so don't bother with my suggestion. - MartynA

2 Answers

13
votes

As I said in a comment to Zam, with the current version downloaded today of Acrobat Reader DC , I get the exact same error as you.

Please try this code and let us know whether it avoids the error for you, because it certainly works for me and there is no AV, either in the FormClose or afterwards.

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  Ref : Integer;
begin
  Ref := AcroPdf1.ControlInterface._AddRef;
  AcroPdf1.Src := '';
  AcroPdf1.Free;
  AcroPdf1 := Nil;
end;

This is my FormCreate, which contains my only other code.

procedure TForm1.FormCreate(Sender: TObject);
begin
  AFileName := 'd:\aaad7\pdf\printed.pdf';
  AcroPdf1.src := AFileName;
  AcroPdf1.setZoom(200);  // <- this line is to exercise the
    // ControlInterface to provoke the AV on shutdown
end;

I have absolutely no idea why my FormClose avoids the AV problem, and before anybody else says so, yes, it looks mad to me, too! Hardly something that deserves the name "solution", but maybe it will suggest a proper solution to someone who knows more about COM and Ole controls than I do.

I originally included the Ref := AcroPdf1._AddRef just as an experiment. I noticed that after it, Ref's value was 9. After AcroPdf1.Src := '', calling AcroPdf1._Release in the debugger evaluator returned a value of 4. I was about to see if the AV was avoided by forcing the RefCount down by repeatedly calling _Release but then Presto!, there was no AV after my first trace into FormClose exited.

Update: I have not tested the following exhaustively, but this simplified FormClose also avoids the AV, on my system at any rate:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  Ref : Integer;
begin
  Ref := AcroPdf1.ControlInterface._AddRef;
end;

Obviously, omitting the assignment to Ref shouldn't make any difference.

I'm using Delphi 10 Seattle on 64-bit Win10, btw.

3
votes

The better solution is to edit the TPDF Object in "AcroPDFLib_Tlb.pas"

Just add the proper destructor to the Code to free the OLE Object:

Declaration

Type
  TAcroPDF = class(TOleControl)
  ...
  public
    destructor Destroy; override; // <- New Line
  ...
  end;

Implementation

destructor TAcroPDF.Destroy;
begin
 FIntf := NIL;
 inherited;
end;