Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Unterstützung merherer adobe reader Versionen, geht das? (https://www.delphipraxis.net/60465-unterstuetzung-merherer-adobe-reader-versionen-geht-das.html)

alwin 7. Jan 2006 09:53


Unterstützung merherer adobe reader Versionen, geht das?
 
Hallo Ihr Lieben,

ich habe ein großes Problem und hoffe auf eure Hilfe. Ich muss in einer Anwendung eine PDF-Datei anzeigen und benutze dazu das entsprechende OCX des adobe readers.

Dursch die Schnittstellenänderung Vers. 6.0 / 7.0 bekomme ich nun natürlich ein Problem. Eigentlich möchte ich nicht auf Fremdprodukte ausweischen und würde deshalb am liebsten beide OCX-Versionen unterstützen. Ist sowas überhaupt möglich, und wenn ja wie???

Bin für jede Antwort dankbar!!!

Gruss

Alwin

marabu 7. Jan 2006 11:52

Re: Unterstützung merherer adobe reader Versionen, geht das?
 
Herzlich Willkommen in der Delphi-PRAXiS, alwin.

Du könntest die Registrierdatenbank untersuchen.

Code:
HKEY_LOCAL_MACHINE\
   SOFTWARE\
      Adobe\
         Acrobat Reader\
            6.0
               InstallPath\
            7.0
               InstallPath\
Du könntest dann den Reader mit der höchsten Versionsnummer verwenden. Da die Parallelinstallation mehrerer Versionen offensichtlich möglich ist - bei mir 5.0 und 7.0 - könntest du alle relevanten Versionen auf deiner Entwicklungsmaschine installieren und die Typbibliotheken importieren. Oder du verwendest die bereits vorhanden Logik der WebBrowser Komponente, die für dich die jeweils zuletzt auf der Zielmaschine installierte Version des Readers aktivieren wird - das wäre mein Ansatz.

Freundliche Grüße vom marabu

Bernhard Geyer 7. Jan 2006 17:23

Re: Unterstützung merherer adobe reader Versionen, geht das?
 
Zitat:

Zitat von alwin
Dursch die Schnittstellenänderung Vers. 6.0 / 7.0 bekomme ich nun natürlich ein Problem. Eigentlich möchte ich nicht auf Fremdprodukte ausweischen und würde deshalb am liebsten beide OCX-Versionen unterstützen. Ist sowas überhaupt möglich, und wenn ja wie??

Lade es doch über den IE. damit ist es dir wurscht ob 6 oder 7 installiert ist da der IE diese unterscheidung für dich durchführen muss (bzw. der Reader sich korrekt im IE installiert haben muss).

Zitat:

Zitat von marabu
Da die Parallelinstallation mehrerer Versionen offensichtlich möglich ist - bei mir 5.0 und 7.0 -

Das geht? Also meine Erfahrungen (ok. immer im zusammenhang mit Adobe-Vollversion) ist das bei parallelinstallation meißtens gar nichts mehr geht. Normalerweise sollte doch der Installer die alte Version eliminieren.

H4ndy 9. Jan 2006 11:01

Re: Unterstützung merherer adobe reader Versionen, geht das?
 
Zitat:

Zitat von Bernhard Geyer
Normalerweise sollte doch der Installer die alte Version eliminieren.

Eigentlich nicht. Der Installer des Acrobat 7 fragt am Ende nach,
welcher Reader als Standard benutzt werden soll...

Ich habe übrigends gerade das selbe Problem.
Ich versuche gerade folgenden Weg:

Ich habe beide OCX-Beschreibungen als .pas-Datei erzeugen lassen.
Nun muss ich noch einen Weg finden beim Programmstart über die
bei jedem Reader einzigartigen GUIDs zu prüfen welcher Reader installiert ist.
(6 oder 7) und dann je nach Ergebnis eben ein TPDF (6er) oder ein TAcroPDF (7er)
auf dem Form erzeugen.

Wenn ich rausgefunden hab wie ich die Prüfung durchführe, meld ich mich nochmal =)
(egal ob es gefunzt hat oder nicht)

H4ndy 11. Jan 2006 16:22

Re: Unterstützung merherer adobe reader Versionen, geht das?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Habs hinbekommen ^^

Folgender Hintergrund:
Von Version 6 zu 7 wurde das Interface der ActiveX Komponente geändert.
Der Installer terminiert aber das 6er gleich mit, sodass entweder das 6er Control,
oder das 7er Control zur Verfügung steht.

Nach dem CreatePDFViewer (siehe unten) aufgerufen wurden,
kann man über FIsAcrobat6/7installed feststellen, ob ihr PDF6 oder PDF7 nutzen müsst.
(Sicherer ist es jedoch, Assigned(PDFx) zu benutzen!)

Das 6er Interface steht in der Acrobat-Versionen 4,5 und 6 zur Verfügung.
(Getestet - Version 3 und älter konnte ich nicht testen)

Zur einfacherer Benutzung, empfehle ich, häufig genutze Funktionen der PDF-Objekte
in eine Funktion zu kapseln, welche entscheidet welcher Reader da ist (spart Code und Zeit).
Eine solche Funktion hab ich unten als Beispiel mit dabei.

Tipp:
OLEExceptions können über try..except abgefangen werden.
Dadurch scheint manchmal die Fehlermeldung genauer zu werden.

Delphi-Quellcode:
try
...
except
  on E: Exception do begin
    ShowMessage(E.Message); //kann man mit MessageDlg schöner machen
  end;
end;
---

(Alle Code-Kommentare sind auf english, da ich einfach Copy&Paste aus meinem Firmen-Projekt gemacht habe [mit kleinen Änderungen])

Vorbereitung:
Acrobat 6 und 7 OCX ActiveX Komponente als .pas exportieren
(alle Versionen deinstallieren -> v6 installieren -> OCX exportieren
-> v7 installieren -> OCX exportieren)
Falls ihr zu faul dazu seid, nehmt die im Anhang (erstellt mit Delphi 5)

Jetzt im Projekt beide .pas-Dateien aufnehmen und usen.

Folgender Code funktioniert bei mir bisher ohne Probleme:

Delphi-Quellcode:
var
  PDF7: TAcroPDF; //v7
  PDF6: TPDF; // v4-6 (getestet)
  FIsAcrobat7installed, FIsAcrobat6Installed: boolean;

...

// Folgender Code prüft welche Version installiert ist,
// und erzeugt dann das entspr. Objekt
procedure CreatePDFViewer;
var Reg: TRegistry;
    AcroBasekey, Acro7TypeLibID, Acro6TypeLibID: string;
    tmpStr: string;
begin
  // If the "AcroBasekey" under HKEY_CLASSES_ROOT\CLSID\ exists,
  // Acrobat 4,5,6 or 7 is theoretical installed.
  // The Value of the "TypeLib" Key dertermines the exact ActiveX version
  // installed (= different for version 4-6 and 7).

  AcroBasekey := '{CA8A9780-280D-11CF-A24D-444553540000}';
  Acro6TypeLibID := '{CA8A9783-280D-11CF-A24D-444553540000}'; // v4 - v6
  Acro7TypeLibID := '{05BFD3F1-6319-4F30-B752-C7A22889BCC4}'; // v7

  // Check for installed acrobat reader
  Reg := TRegistry.Create(KEY_READ); // We only need read-only access
  try
    Reg.RootKey := HKEY_CLASSES_ROOT;
    if Reg.OpenKeyReadOnly('CLSID\'+AcroBasekey+'\TypeLib\') then begin
      // Get "standard" value of key
      tmpStr := Reg.ReadString('');

      // Equal TypeLib GUIDs
      FIsAcrobat6Installed := tmpStr = Acro6TypeLibID; // Ver. 7 is installed
      FIsAcrobat7Installed := tmpStr = Acro7TypeLibID; // Ver. 6 is installed

      // Acrobat 6/7 not found...
      if (not FIsAcrobat7Installed) and (not FIsAcrobat6Installed) then begin
        // < HIER FEHLERMELDUNG ZEIGEN, DASS KEIN KOMPATIBLER ACROBAT DA IST > (v4-7 getestet)
      end;

      Reg.CloseKey;

    end else begin
      // decent acrobat not installed...
      // < HIER FEHLERMELDUNG ZEIGEN, DASS *KEIN* ACROBAT DA IST > (v4-7 getestet)
    end;
  finally
    Reg.Free;
  end;

  // Create Acrobat Reader 7 PDF-Viewer component
  if FIsAcrobat7Installed then begin
    PDF7 := TAcroPDF.Create(Self);
    PDF7.Parent := Self;
    PDF7.Align := alClient;

    // Hide Acrobat Toolbar (can be undone with button in the left-bottom corner)
    PDF7.setShowToolbar(false);
  end;

  // Create Acrobat Reader 6 PDF-Viewer component
  if FIsAcrobat6Installed then begin
    PDF6 := TPDF.Create(Self);
    PDF6.Parent := Self;
    PDF6.Align := alClient;

    // Hide Toolbar-function available, but doesn't work in v6 or lower
    // PDF6.setShowToolbar(false);
  end;
end;
Vergesst nicht, die Objekte im Form.Destroy freizugeben:

Delphi-Quellcode:
  // free PDF-Viewer components
  if Assigned(PDF6) then
    DeleteClass(PDF6);

  if Assigned(PDF7) then
    DeleteClass(PDF7);

Hier noch eine gebräuchliche Funktion, welche gleich selber entscheidet, welcher Reader verfügbar ist.

Delphi-Quellcode:
function PDF_LoadFile(const fileName: WideString): boolean;
begin
  result := true;
  if Assigned(PDF7) then begin
    try
      // TAcroPDF (Reader v7) returns 0 if successfully loaded... (and an exception if not)
      Result := not PDF7.LoadFile(FileName);
    except
      on E: Exception do begin
        MessageDlg(Format('Error while loading file: %s',
                   [E.Message]),mtError,[mbOK],0);
      end;
    end;
  end else if Assigned(PDF6) then begin
    try
      Result := PDF6.LoadFile(FileName);
    except
      on E: Exception do begin
        MessageDlg(Format('Error while loading file: %s',
                   [E.Message]),mtError,[mbOK],0);
      end;
    end;
  end else begin
    MessageDlg('No pdf viewer initialized',mtError,[mbOK],0);
    Result := false;
  end;
end;
Danke für's lesen!
Jetzt viel Spaß damit ^^

(Über etwagige Verbesserungen würde ich mich sehr freuen)

H4ndy 11. Dez 2006 15:43

Re: Unterstützung merherer adobe reader Versionen, geht das?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mal alles in ein kleines Projekt gepackt, um die Anwendung meines Codes zu verdeutlichen.
Das Projekt dürfte ab Delphi5 funktionieren. Zusätzlich ist noch folgender Kniff enthalten:
Delphi-Quellcode:
procedure TfrmMain.FormResize(Sender: TObject);
begin
  if Assigned(PDF7) then begin
    // Because of the strange behavior of the new Acrobat 7 ActiveX control,
    // it has to loose and gain focus again to repaint itself to the new size.
    // You have to give the focus to an control on the form, not the form itself.

    pnlBottom.SetFocus; // Using the form here doesn't work
    PDF7.SetFocus;
  end;
end;

shmia 11. Dez 2006 18:22

Re: Unterstützung merherer adobe reader Versionen, geht das?
 
Zitat:

Zitat von H4ndy
Tipp:
OLEExceptions können über try..except abgefangen werden.
Dadurch scheint manchmal die Fehlermeldung genauer zu werden.

Aber nur, wenn man folgenden Code benützt: :mrgreen:
OLE Exceptions verarbeiten und anzeigen


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz