delphipdfaxacropdf

how to get the selected text from acropdf component to an edit directly with Delphi 7


I study preparing a dictionary programme with delphi. So far I have solved my problems about Word documents but I've got some problem about PDF documents. I imported and installed the AcroPdf component with Delphi 7 and I want to get the word (or text) which was selected by dblclicking by user from pdf document which was viewed by the ACROPDF component in Delphi. If I can get it I'll send it the dictionary database directly. If you help me I'll be glad. Thank you... Remzi MAKAK


Solution

  • The following shows one way to get the selected text from a Pdf document which is open in Adobe Acrobat Professional (v.8, English version).

    Update The original version of this answer neglected to check the Boolean result of calling MenuItemExecute and specified the wrong argument to it. Both these points are fixed in the updated version of this answer. It turned out that the reason the call to MenuItemExecute was failing was that it is essential to call BringToFront on the Acrobat document before trying to copy the text selected in to to the clipboard.

    1. Create a new Delphi VCL project.

    2. In D7's IDE go to Projects | Import Type Library, and in the Import Type Library pop-up, scroll down until you see something like "Acrobat (Version 1.0) in the list of files, and "TAcroApp, TAcroAVDoc..." in the Class names box. That is the one you need to import. Click the Create unit button/

    3. In the project's main form file

      a. Make sure it USES the Acrobat_Tlb.Pas unit from step 2. You may need to add the path to wherever you saved Acrobat_Tlb.Pas to the SearchPath of your project.

      b. Drop a TButton on the form, name it btnGetSel. Drop a TEdit on the form and name it edSelection

    4. Edit the source code of your main form unit as shown below.

    5. Set a debugger breakpoint on Acrobat.MenuItemExecute('File->Copy'); Do not set a breakpoint within the GetSelection procedure as this is likely to defeat the call to BringToFront in it.

    6. Close any running instance of Adobe Acrobat. Check in Task Manager that there are no hidden instances of it running. The reason for these step is to make sure that when you run your app, it "talks" to the instance of Acrobat that it starts, not another one.

    7. Compile and run your app. Once the app and Acrobat are open, switch to Acrobat, select some text, switch back to your app and click the btnGetSel button.

    Code:

      uses ... Acrobat_Tlb, ClipBrd;
    
      TDefaultForm = class(TForm)
      [...]
      private
        FFileName: String;
        procedure GetSelection;
      public
        Acrobat : CAcroApp;
        PDDoc : CAcroPDDoc;
        AVDoc : CAcroAVDoc;
      end;
    
    [...]
    
    procedure TDefaultForm.FormCreate(Sender: TObject);
    begin
      //  Adjust the following path to suit your system.  My application is
      //  in a folder on drive D:
      FFileName := ExtractfilePath(Application.ExeName) + 'Printed.Pdf';
      Acrobat := CoAcroApp.Create;
      Acrobat.Show;
      AVDoc := CoAcroAVDoc.Create;
      AVDoc.Open(FileName, FileName); // := Acrobat.GetAVDoc(0) as CAcroAVDoc; //
    
      PDDoc := AVDoc.GetPDDoc as CAcroPDDoc;
    end;
    
    procedure TDefaultForm.btnGetSelClick(Sender: TObject);
    begin
      GetSelection;
    end;
    
    procedure TDefaultForm.GetSelection;
    begin
      // call this once some text is selected in Acrobat
      edSelection.Text := '';
    
      if AVDoc.BringToFront then  //  NB:  This call to BringToFront is essential for the call to MenuItemExecute('Copy') to succeed 
        Caption := 'BringToFront ok'
      else
        Caption := 'BringToFront failed';
      if Acrobat.MenuItemExecute('Copy') then
        Caption := 'Copy ok'
      else
        Caption := 'BringToFront failed';
    
      Sleep(100);  // Normally I would avoid ever calling Sleep in a Delphi     
      //  App's main thread.  In this case, it is to allow Acrobat time to transfer the selected
      //  text to the clipboard before we attempt to read it.
    
      try
        edSelection.Text := Clipboard.AsText;
      except
      end;
    
    end;