Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Problemas con TAcroPdf en Tiempo de ejecucuón (https://www.clubdelphi.com/foros/showthread.php?t=30769)

Pook 18-04-2006 12:33:34

Problemas con TAcroPdf en Tiempo de ejecucuón
 
Buenas, tengo un problemilla, me creo un componente del tipo TAcroPDF (Acrobat reader 7) e intento imprimirlo, la razón de hacerlo en tiempo de ejecución es que el usuario elige un documento de un servidor y directamente lo imprime sin abrirlo ni nada, pudiendo elegir entre archivos de tipo word, excel, pdf y powerpoint, este es el código que uso para la creación de PDF:

Código:

procedure TPrint.PdfPrint(Filename: string);
  var
    Nombre : OleVariant;
    PdfDoc : TAcroPdf;
  begin
    PdfDoc := TAcroPdf.Create(self);
    Nombre := Filename;
    PdfDoc.LoadFile(Nombre);
    PdfDoc.printWithDialog;
  end;

Uso print with dialog, porque en versiones anteriores de Acrobat (5-6) el comando PrintAll no imprimia nada, el problema es que con la versión 7 ahora ni siquiera me saca el dialogo de imprimir...

¿Hay alguna manera de poder imprimir el documento que se le pase sin abrir el Acrobat y haciendolo desde tiempo de ejecución?

Gracias de antemano.

ozsWizzard 13-07-2012 10:22:33

Hola compañeros de Delphi, tengo exactamente este mismo problema, no soy capaz de imprimir un pdf con el componente de acrobat (TAcroPdf).

He utilizado Print, PrintAll, ... todo, vaya, y ésto no imprime.

He comprobado que si meto el componente en un Form, el "Print" funciona correctamente. Iba a tirar por el camino, un tanto chapucero, siguiente:

Como quién se encarga de imprimir es un objeto instanciado(instado según el DRAE) de una clase declarada por mí, iba a ponerle una propiedad del tipo TAcroPdf, y asignarla antes de llamar al procedimiento que se encarga de imprimir.

Pues nada, no me imprime tampoco.

Tengo el "Rad Studio X2 Delphi" y el adobe acrobat 10.0.

El código sería más o menos esto:

Código Delphi [-]
//DECLARACIÓN DE LA CLASE
TMiClase = class
  private
     FPdf:       TAcroPdf;
     FNombreDoc: String;

     procedure Ejecutar(const Accion: String);
  public
     property NombreDoc: String read FNombreDoc;
     property Pdf: TAcroPdf read FPdf write FPdf;

     procedure visualizar;
     procedure Imprimir;

     constructor Create(Id: String);
end;

Código Delphi [-]
//IMPLEMENTACION DE LA CLASE
{ TMiClase }

constructor TMiClase.Create(Id: String);
begin
   inherited Create;

   //Proceso que calcula NombreDoc con el Id, pongamos que le calcula lo siguiente
   FNombreDoc :=  'Fichero.pdf';
end;

procedure TMiClase.Ejecutar(const Accion: String);
var
  ExecInfo : TShellExecuteInfo;
  Fichero: TFichero;
  ExitCode: DWord;
begin
   //La clase "TFichero" se usa para codificar y descodificar ficheros. la idea es que los ficheros se guardan codificados, al abrirlos, los 
   //descodifico en un fichero temporal, que es el que intenta imprimir.
   //Parámetros del Create de TFichero (ruta, documeto, nombre del fichero temporal
    Fichero := TFichero.Create(ExtractFilePath(Application.ExeName),
                               NombreDoc, 'documento.pdf');
    try
      Application.ProcessMessages;
      Fichero.Descodificar;

      if Accion = 'print' then
      begin
         Pdf.LoadFile(WideString(Fichero.Temporal));
         Pdf.Print;
      end
      else begin
         ExecInfo.cbSize := SizeOf(ExecInfo);
         ExecInfo.fMask  := SEE_MASK_NOCLOSEPROCESS;
         ExecInfo.Wnd    := Handle;
         ExecInfo.lpVerb := PWideChar(Accion);
         ExecInfo.lpFile := pChar(Fichero.Temporal);
         ExecInfo.lpParameters := nil;
         ExecInfo.lpDirectory  := nil;
         ExecInfo.nShow  := SW_SHOW;
         ShellExecuteEx(@ExecInfo);

         repeat
            Application.ProcessMessages;
            GetExitCodeProcess(ExecInfo.hProcess, ExitCode) ;
         until (ExitCode <> STILL_ACTIVE);
      end;
    finally
       Fichero.Free;
    end;
end;

procedure TMiClase.Imprimir;
begin
   Ejecutar('print');
end;

procedure TMiClase.visualizar;
begin
   Ejecutar('open');
end;

Código Delphi [-]
//LLAMADA (más o menos)
procedure TForm.actImprimirExecute(Sender: TObject);
var
   MiObjeto: TMiClase;
begin
   //Obtengo el ID, supongamos que es 5
   MiObjeto := TMiClase.Create('5');
   try
      MiObjeto.Pdf := AcroPdf1;
      MiObjeto.Imprimir;
   finally
      MiObjeto.Free;
   end;
end;

Evidentemente, he tenido que quitar código, política de empresa, pero a groso modo esto es lo que hago.

ozsWizzard 13-07-2012 10:26:49

También me vale la opción de que con el ShellExecuteEx pueda imprimir sin abrir el acrobat (que ya sé que no se puede) pero no me vale terminar el proceso yo mismo porque no puedo asegurarme de que lo haya imprimido.

Y me da exactamente igual usar el TAcroPdf en tiempo de diseño que en tiempo de ejecución, lo que me gustaría es mantener la funcionalidad dentro de "MiClase" y no tener que llevármela al Form.

ozsWizzard 13-07-2012 12:40:40

Acabo de descubrir con asombro que, hasta que no acaba el hilo del proceso entero, no carga el pdf.

Es decir, incluso en un formulario, si hago el LoadFile y el Print seguidos, no funciona. y da igual que lo meta en procedientos distintos, que ponga Sleeps de los segundos que quiera, Application.ProcessMessages, etc. Da excatamente igual, no imprime (porque realmente no ha cargado el pdf).

En caso contrario, si pongo en un evento onclick de un botón el "LoadFile" y en el evento onclick de otro botón el "Print", funciona correctamente.

Mi problema está en que lo que realmente quería hacer es una iteración donde se reccorre un dataset con el nombre de cada fichero y quiero imprimir los que tenga marcados (da igual el método).

Con esta premisa, es imposible hacer lo que quiero hacer.

Total, que si alguien sabe alguna forma de imprimir pdf directamente en la impresora y que se pueda hacer de forma seguida (indicar fichero e imprimir)... que me lo haga saber.

Había pensado en poner en hilos distintos el loadFile y el print, pero eso debe de ser una locura.

ozsWizzard 13-07-2012 13:11:10

Para que se vea a qué me refiero, estas son las pruebas que he hecho.

Con este código, cuando pulso Button1, no imprime nada, cuando pulso Button2 después de haber pulsado Button1, imprime.

Lo que me ha hecho gracia, y por si a alguien le puede servir para hallar una solución es que, cuando se pulsa Button1 (sin que haya un pdf cargado) hasta los 7 segundos (los 6 del Sleep y algo más), no se ve el pdf en el TAcroPdf.

Utilizo PrintAll porque Print abre un dialogo de impresión, aunque las pruebas las hago con print porque es más rápido ver que abre el dialogo que ir a la impresora (en la otra punta de la oficina) a ver si ha imprimido algo.

Código Delphi [-]
procedure TForm1.CargarFilePdf;
var
   dlg: TOpenDialog;
begin
   dlg := TOpenDialog.Create(Self);
   try
      if dlg.Execute then
      begin
         AcroPdf1.LoadFile(dlg.FileName);
         Application.ProcessMessages;
         AcroPdf1.PrintAll;
      end;
   finally
      dlg.Free;
   end;
end;

procedure TForm1.sButton1Click(Sender: TObject);
begin
   CargarFilePdf;
   Sleep(6000);
   AcroPdf1.PrintAll;
end;

procedure TForm1.sButton2Click(Sender: TObject);
begin
   AcroPdf1.PrintAll;
end;

Saludos.


La franja horaria es GMT +2. Ahora son las 18:05:42.

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