PDA

Ver la Versión Completa : No funciana mandar fichero txt a impresora con XE2


comba
04-06-2014, 10:40:05
Hola a todos

Me surge un problema y haber si alguien me puede orientar.

Antes trabajaba con D6 y utilizaba una funcion (que pongo más abajo) para mandar a imprimir un fichero txt con códigos de escape de una zebra, hasta aquí todo bien y utilizo este método porque es muy rápido ante un quickreport y demás.

El problema viene cuando ahora estoy utilizando XE2 y utilizó la misma función, el compilador no dice nada pero no se imprime lo que mando. Yo creo que el problema tiene que ver con los arrays of char y unicode, pero la verdad no se por donde metermano.

Por eso os pidó ayuda.


procedure imprimir(const sFileName:string;impresora:integer);
const
iBufferSize = 32768;
var
Count, BytesWritten: Cardinal;
hPrinter, hDeviceMode: THandle;
sDevice : array[0..255] of Char;
sDriver : array[0..255] of Char;
sPort : array[0..255] of Char;
DocInfo: TDocInfo1A;
f: File;
pBuffer: Pointer;
begin
Printer.PrinterIndex := impresora;
Printer.GetPrinter(sDevice, sDriver, sPort, hDeviceMode);

if not WinSpool.OpenPrinter(@sDevice, hPrinter, nil) then
exit;

DocInfo.pDocName := 'Probando';
DocInfo.pDatatype := 'RAW';
DocInfo.pOutputFile := nil;

if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
begin
WinSpool.ClosePrinter(hPrinter);
exit;
end;

if not StartPagePrinter(hPrinter) then
begin
EndDocPrinter(hPrinter);
WinSpool.ClosePrinter(hPrinter);
exit;
end;

System.Assign(f, sFileName);
try
Reset(f, 1);
GetMem(pBuffer, iBufferSize);
while not eof(f) do
begin
Blockread(f, pBuffer^, iBufferSize, Count);
if Count > 0 then
begin
if not WritePrinter(hPrinter, pBuffer, Count, BytesWritten) then
begin
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
WinSpool.ClosePrinter(hPrinter);
FreeMem(pBuffer, iBufferSize);
exit;
end;
end;
end;
FreeMem(pBuffer, iBufferSize);
EndDocPrinter(hPrinter);
WinSpool.ClosePrinter(hPrinter);
finally
System.Closefile(f);
end;
end;

engranaje
04-06-2014, 11:09:40
¿Podrias aclararnos para poder ayudarte mejor si has trazado ese procedimiento y en que punto sale?
¿supera este paso sin problema?

if not WinSpool.OpenPrinter(@sDevice, hPrinter, nil) then
exit;

Casimiro Notevi
04-06-2014, 11:44:27
...

Recuerda poner los tags al código fuente, ejemplo:

http://www.clubdelphi.com/images/UtilizarTAGs.png

Gracias

duilioisola
04-06-2014, 12:33:38
A qué ter refieres con "No se imprime lo que mando"
¿No se imprime nada?
¿Se imprime "basura"?
¿Se imprime solo parte?

¿Cómo generas el fichero?
Es Unicode / UTF8 o algo parecido

comba
04-06-2014, 12:38:23
Tomo nota Casimiro.
Y efectivamente engranaje, cuando llega a este punto no lo supera

if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
begin
WinSpool.ClosePrinter(hPrinter);
exit;
end;

ecfisa
04-06-2014, 12:40:08
Tomo nota Casimiro.
Y efectivamente engranaje, cuando llega a este punto no lo supera

if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
begin
WinSpool.ClosePrinter(hPrinter);
exit;
end;

Tomaste nota pero... ¿ Y los Tag's ? :confused:

Saludos :)

comba
04-06-2014, 12:48:30
Perdona ecfisa

Pero he puesto los tag y acabo de hacer la prueba en la vista previa y automáticamente los quita, por lo menos a mí

comba
04-06-2014, 12:52:10
Hola duilioisola

Lo que mando es un fichero txt con código epl para que la impresora zebra los imprimá, pero como he comentado anteriormente cuando llegá a este paso entra y va al exit.

if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
begin
WinSpool.ClosePrinter(hPrinter);
exit;
end;


De antemano gracias a todos.

ecfisa
04-06-2014, 13:05:17
Hola comba.
Perdona ecfisa

Pero he puesto los tag y acabo de hacer la prueba en la vista previa y automáticamente los quita, por lo menos a mí
No hay problema :) , tal vez sea resultado del navegador que usas y la selección de edición con WYSIWYG (What You See Is What You Get) en las opciones de tu panel de control de usuario. Para evitar eso uso "Editor estándard - Controles de formato extra".

Intenta la corrección usando las etiquetas manualmente de este modo: tu_codigo , de momento ya las agregué a tu último mensaje.

Saludos :)

engranaje
04-06-2014, 13:13:23
has probado a modificar esto:

DocInfo.pOutputFile := nil;


para pasar como poutputfile el puerto de la impresora en lugar de nulo?
mas o menos asi:


DocInfo.pOutputFile := sPort;

comba
04-06-2014, 17:41:31
Hola engranaje

He modificado lo que me habias comentado pero me da este error.

E2010 Incompatible types: 'PAnsiChar' and 'array[0..255] of Char'

engranaje
04-06-2014, 18:26:15
cierto, puedes probar con:

DocInfo.pOutputFile := @sPort;


Aunque lo cierto es que creo que es mejor trabajar directamente sobr Pchar, declarando las variables asi:


var
pDevice :PChar;
PDriver :Pchar;
pPort :Pchar;
hdMode : Thandle;


cargandolas asi:

getMem(pDevice, cchDeviceName);
getmem(pDriver,MAX_PATH);
GetMem(pPort,MAX_PATH);
printer.GetPrinter(pDevice,pDriver,pPort,hDMode);


y liberando la memoria cuando corresponda:

if assigned(pDevice) then
freeMem(pDevice, cchDeviceName);
if assigned(pDevice) then
freemem(pDriver,MAX_PATH);
if assigned(pDevice) then
freeMem(pPort,MAX_PATH);

ElKurgan
05-06-2014, 09:16:30
Hola, Comba.

He probado tu código en un XE2 y en un XE5, sin cambiar nada, y en ambos casos ha funcionado correctamente.

Eso si, no tengo ninguna impresora de tickets, pero lo he lanzado a una LaserJet 4200 y ha ido de lujo.

El problema seguramente lo tendrás en otro sitio.

Saludos

hgiacobone
15-06-2017, 16:12:09
Hola amigo Comba,
Parece mentira que a estas alturas tenga el mimo problema.
Por necesidades (ilogicas) hemos mudado el codigo del viejo D7 hacia un XE4 y, entre otras, la funcion de impresion siobre impresoras Zebra no ha funcionado nunca más.

En mi caso tambien, llega hasta el mismo punto y no produce ninguna salida. Aqui parte de mi código muy similar al tuyo:
var
PrinterHandle: THandle;
N: DWORD;
DocInfo1: TDocInfo1;
begin
Result:= FALSE;
if not WinSpool.OpenPrinter(PChar(PrinterName), PrinterHandle, nil) then
begin
ShowMessage(PrinterName+#13+'OpenPrinter error ' + IntToStr(GetLastError));
Exit;
end
else Try
with DocInfo1 do
begin
pDocName := PChar('Keuken Doc');
pOutputFile := nil;
pDataType := 'RAW';
end;
if StartDocPrinter(PrinterHandle, 1, @DocInfo1) <> 0
then ...

Como lo has resuelto?:(

hgiacobone
15-06-2017, 20:04:44
Actualizo la data.
Modifique la instruccion original:
WritePrinter(PrinterHandle, PChar(comando), Length( PChar(comando) ), N);
...por esta nueva instruccion sugerida por otro amigo:
WritePrinter(PrinterHandle, PChar( RawByteString(comando) ), Length( PChar( RawByteString(comando)) ), N);
...pero tampoco funciona. No sale nada por la impresora y en cambio con Delphi7 si lo hace.
:mad:
¿Alguna idea o sugerencia?

ElKurgan
16-06-2017, 07:32:11
A lo mejor el problema está en el soporte para caracteres Unicode de las últimas versiones de Delphi.

Desde la versión 2009 de Delphi se incluye soporte a caracteres Unicode por defecto, por lo que la clase String equivale a la antigua WideString. Lo mismo pasa con los tipos Char.

Si quieres que las cosas funcionen como estaban en versione anteriores de Delphi tienes que sustituir los String por AnsiStirng, y los Char por AnsiChar

A lo mejor tienes que cambiar todas las transformaciones tipo PChar(...) a PAnsiChar(...)

Espero que te sirva

Un saludo

hgiacobone
16-06-2017, 21:09:32
Bueno amigos, luego de mucho andar, he aqui la solución.
La instruccion original, debe modificarse de esta forma:

WritePrinter(PrinterHandle , PAnsiChar( RawByteString(comando) ) , Length(comando) , N);

Con esto, sencillamente, funciona.:eek: