PDA

Ver la Versión Completa : Problemas con TAcroPdf en Tiempo de ejecucuón


Pook
18-04-2006, 12:33:34
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:

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:


//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;



//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;



//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.


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.