Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   ActiveX AcroPdf no funciona (https://www.clubdelphi.com/foros/showthread.php?t=85867)

radenf 17-05-2014 15:31:06

ActiveX AcroPdf no funciona
 
Hola amigos:

He desarrollado algunos programas en los que he utilizado el componente ActiveX AcroPdf, para visualizar archivos PDF.
La última actualización de Adobe Reader modifica la AcroPdf.dll a la versión 11.0.7.79, con lo cual el componente deja de funcionar al igual que los programas que lo utilizan, enviando un mensaje de AccessViolation.
Si restauro mi sistema a un punto anterior a esta actualización todo vuelve a la normalidad, pero lamentablemente Adobe Reader se actualiza automáticamente a pesar de que tenga desactivadas las actualizaciones en este programa.
Como he visto que muchas personas han hecho consultas aquí en el foro en relación al uso de este componente, me imagino que también podrían verse afectados sus programas.
En el foro de Adobe ya se han publicado varios casos que apuntan al mismo problema.
¿Alguien dispone de alguna información al respecto?

Saludos

dec 17-05-2014 17:10:02

Hola,

Lo que yo haría (y quizá no sirva para nada) es:

1º Intentar actualizar el componente en cuestión de manera que use la última versión de la DLL de marras, tal vez "importándola" para crear otro "ActiveX" o algo así...

2º Mostrar al usuario los PDF dentro de un "WebBrowser" preparado para tal efecto. De este modo el "WebBrowser" lidiaría con la última versión instalada en el equipo.

3º No mostrar, pero, "lanzar" los documentos PDF de manera que el usuario los visualize usando el programa que prefiera y tenga instalado: Acrobat Reader u otro.

Nota: el orden los puntos anteriores tal vez no sea el esperado, sino que podríamos empezar por el final y aquí paz y después gloria. ;)

radenf 17-05-2014 17:54:07

Muchas gracias por responder dec.
Lo que tú señalas ya lo intenté y como bien acotas no sirvió de nada.
Por lo que he leído en los foros de Adobe se trataría de un bug no considerado en la última actualización, que pretende corregir algún problema de seguridad.
Al parecer habrá que esperar que los gurus de Adobe corrijan el problema y ojalá lo tengan presente en futuras actualizaciones.
Saludos

dec 17-05-2014 20:00:31

Hola,

Hombre, si se puede esperar... ¿pero qué hay de la segunda o tercera soluciones propuestas?

camino 17-05-2014 21:10:16

PDF con Windows 7 64 bits
 
Despues de haber dejado el tema ( por cansancio) sin solucion, ayer decidi darle unas vueltas mas y, parece que descubri la solucion:

AcroPDFLib_TLB no basta con colocarlo en el uses de la form que hace el display del PDF.

Se me ocurrio colocarlo en todas las Unit que llama a la form del PDF.

Esto dio el resultado que yo esperaba.

Ojala sirva para los que aun no han encontrado una solucion. Yo se lo que es eso.

nlsgarcia 17-05-2014 21:17:04

radenf,

Cita:

Empezado por radenf
...La última actualización de Adobe Reader modifica la AcroPdf.dll a la versión 11.0.7.79, con lo cual el componente deja de funcionar al igual que los programas que lo utilizan...

Momentáneamente mientras Adobe resuelve el problema, puedes hacer un workaroud copiando la versión del DLL que funciona de un directorio de respaldo antes de hacer uso de cualquier función de este, donde y como copiar el DLL depende de como este implementado en tu aplicación.

Cita:

Empezado por dec
...No mostrar, pero, "lanzar" los documentos PDF de manera que el usuario los visualice usando el programa que prefiera y tenga instalado: Acrobat Reader u otro...

Esta opción también es válida (Temporalmente si es el caso por medio de un ShellExecute) y funciona independientemente del View PDF instalado.

Espero sea útil :)

Nelson.

radenf 17-05-2014 23:14:18

Muchas gracias por sus opiniones y aportes.
Creo que esperaré la solución que provea Adobe.
Esto me ha abierto los ojos a la vulnerabilidad de los programas que desarrollamos cuando se utilizan componentes de terceros o cuando a través de componentes nativos, como es el caso, se llama a programas de terceros(Adobe Reader).
Intentaré a futuro encontrar alguna alternativa que no utilice Adobe Reader, aunque sea de pago..
Un abrazo

apicito 19-05-2014 12:07:08

Mi casuística es la siguiente:
Funciona con windows Vista y 7 con Acrobat XI.
Falla con Windows XP SP2 en todos los casos y la única solución que he encontrado ha sido downgrade a Adobe 10.
Funciona con windows XP SP3 totalmente actualizado y falla (ocasionalmente) cuando falta alguna actualización.
Un saludo.

radenf 19-05-2014 14:12:41

Estimado apicito:

Gracias por tu respuesta.
El error se produce sólo con la versión 11.0.7.79 de AcroPdf.dll que corresponde a la última actualización de Adobe Reader XI.
Yo utilizo Windows 7 64 bits.
Saludos

nlsgarcia 21-05-2014 09:47:04

radenf,

Cita:

Empezado por radenf
...La última actualización de Adobe Reader modifica la AcroPdf.dll a la versión 11.0.7.79, con lo cual el componente deja de funcionar al igual que los programas que lo utilizan...

Cita:

Empezado por dec
...No mostrar, pero, "lanzar" los documentos PDF de manera que el usuario los visualice usando el programa que prefiera y tenga instalado: Acrobat Reader u otro...

Cita:

Empezado por radenf
...Esto me ha abierto los ojos a la vulnerabilidad de los programas que desarrollamos cuando se utilizan componentes de terceros...

Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Menus, ShellAPI, ExtCtrls, TlHelp32;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure ExecuteApp(AppName, CmdLine, WindowName : String);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  HWindow : THandle;

implementation

{$R *.dfm}

// Verifica si un Proceso esta Activo
function ProcessExists(ExeFileName: String): Boolean;
var
   ContinueLoop: BOOL;
   FSnapshotHandle: THandle;
   FProcessEntry32: TProcessEntry32;

begin

   FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
   ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);

   while Integer(ContinueLoop) <> 0 do
   begin
      if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
      or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
      begin
         Result := True;
         Exit;
      end;
      ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
   end;

   CloseHandle(FSnapshotHandle);

   Result := False;

end;

// Elimina un Proceso Activo
function KillTask(ExeFileName: String): Integer;
const
   PROCESS_TERMINATE = $0001;
var
   ContinueLoop: BOOL;
   FSnapshotHandle: THandle;
   FProcessEntry32: TProcessEntry32;

begin

   Result := 0;

   FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
   ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);

   while Integer(ContinueLoop) <> 0 do
   begin
      if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
      or  (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
         Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE,
                                                        BOOL(0),
                                                        FProcessEntry32.th32ProcessID),
                                            0));
      ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
   end;

   CloseHandle(FSnapshotHandle);

end;

// Visualiza un Archivo PDF en un TPanel (Ejecución)
procedure TForm1.ExecuteApp(AppName, CmdLine, WindowName : String);
var
   HndApp : THandle;
   i : Integer;
   Command : String;
   Parameters : String;

begin

   // Cierra cualquier instancia previa de Acrobat Reader que este activa
   if ProcessExists('AcroRd32.exe') then
      KillTask('AcroRd32.exe');

   // Abre una nueva instancia de Acrobat Reader con el Documento Seleccionado
   HndApp := ShellExecute(0, nil, PChar(AppName), PChar(CmdLine), nil, SW_SHOWMINIMIZED);

   // Busca la ventana de Acrobat Reader con el Documento Seleccionado y la asigna al TPanel
   if (HndApp > 32) then
   begin

      for i := 1 to 10 do
      begin
         HWindow := FindWindow(nil,PChar(WindowName));
         if HWindow > 0 then
            Break
         else
            Sleep(100);
      end;

      if HWindow > 0 then
      begin
         Windows.SetParent(HWindow, Panel1.Handle);
         Windows.MoveWindow(HWindow, 0, 0, ClientWidth, ClientHeight, True);
         Windows.ShowWindow(HWindow,SW_MAXIMIZE);
         Windows.SetFocus(HWindow);
      end;

   end;

end;

// Visualiza un Archivo PDF en un TPanel (LLamada)
procedure TForm1.Button1Click(Sender: TObject);
var
   AppName, CmdLine, WindowName : String;
   openDialog : TOpenDialog;
   Msg : String;

begin

   if (HWindow = 0) then
   begin

      openDialog := TOpenDialog.Create(self);
      openDialog.InitialDir := GetCurrentDir;
      openDialog.Options := [ofFileMustExist];
      openDialog.Filter := 'PDF files|*.pdf';
      openDialog.FilterIndex := 1;

      if openDialog.Execute then
      begin
         AppName := 'C:\Program Files\Adobe\Reader 11.0\Reader\AcroRd32.exe';
         CmdLine := openDialog.FileName;
         WindowName := ExtractFileName(openDialog.FileName) + ' - Adobe Reader';
         ExecuteApp(AppName, CmdLine, WindowName);
      end
      else
      begin
         Msg := 'No Se Selecciono Ningún Archivo PDF a Visualizar';
         MessageDlg(Msg, mtInformation, [mbOK],0);
      end;

   end;

end;

// Cierra la ventana de un Archivo PDF en un TPanel
procedure TForm1.Button2Click(Sender: TObject);
begin
   if HWindow > 0 then
   begin
      SendMessage(HWindow, WM_CLOSE, 0, 0);
      HWindow := 0;
   end;
end;

// Maximiza la ventana de un Archivo PDF en un TPanel
procedure TForm1.Button3Click(Sender: TObject);
begin
   if HWindow > 0 then
      ShowWindow(HWindow, SW_MAXIMIZE);
end;

// Minimiza la ventana de un Archivo PDF en un TPanel
procedure TForm1.Button4Click(Sender: TObject);
begin
   if HWindow > 0 then
      ShowWindow(HWindow, SW_MINIMIZE);
end;

// Inicializa el Handle de la Ventanna del TPanel
procedure TForm1.FormCreate(Sender: TObject);
begin
   HWindow := 0;
end;

// Cierra la ventana de un Archivo PDF en un TPanel al finalizar la Aplicación
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   if HWindow > 0 then
      SendMessage(HWindow, WM_CLOSE, 0, 0);
   Action := caFree;
end;

end.
El código anterior en Delphi 7 bajo Windows 7 Professional x32, permite abrir un documento PDF en un TPanel por medio de la función ShellExecute, como se muestra en la siguiente imagen:



Nota:

1- En esta versión es mandatorio finalizar cualquier instancia previa de Acrobat Reader para poder visualizar el documento seleccionado en el TPanel.

2- Esta versión no depende de ningún componente de terceros, solo de las APIs de Windows y de la versión instalada de Acrobat Reader.

Espero sea útil :)

Nelson.

radenf 21-05-2014 14:42:35

Muchas gracias Nelson.
Excelente alternativa.
Probaré tu código adaptándolo a mi programa.
Saludos

Noruca5 30-07-2014 12:40:08

ActiveX AcroPdf - imprimir varios pdf sin visualizar
 
Hola

Estoy intentando imprimir varios ficheros Pdf con el componente TAcroPDF, segun lo que he leido se puede enviar a la impresora sin visualizar los documentos.

Mi problema es que me descargo el fichero Pdf de un servidor y despues lanzo la impresión, solo me imprime el último fichero cargado en el componente.

ademas solo me permite imprimirlo si ejecuto primero un Show sobre el componente antes de ejecutar PrintAll, ya que Print no funciona tampoco.

¿Sabeis alguna solución? o ¿alguno otro componente que permita enviar a la impresora vairos documentos pdf?

Muchas gracias.

Casimiro Notevi 30-07-2014 13:55:17

Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo?, gracias por tu colaboración :)


La franja horaria es GMT +2. Ahora son las 01:06:30.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi