Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Inviare sequenze ESC alla stampante EPSON T30

47 views
Skip to first unread message

Daniele

unread,
Nov 6, 2023, 11:28:30 AM11/6/23
to
Ciao a tutti,
mi potete dare una mano sul come mandare *correttamente* una sequenza ESC alla stampante in oggetto??

In pratica per inizializzare la stampante (una Epson T30 receipt pos printer) devo inviare un ESC @ e non so come fare.

La strada che piu' si avvicina a questa e' la seguente:

Procedure TestEscPrinter;
Var S1 : String;
I : Integer;
begin
Printer.BeginDoc;
S1:=Char(27)+Char(64);
S1:=AnsiString(S1);
I:=Escape(Printer.Canvas.Handle, PASSTHROUGH, Length(s1), PAnsiChar(s1), nil);
if I=0 then ShowMessage('Command error: ' + IntToStr(GetLastError));
Printer.Canvas.TextOut(0, 100, 'Test di stampa X = 0 e Y = 100');
Printer.EndDoc;
End;

Questa procedura cosi' com'e' funziona ma prima di scrivere la stringa "test..." stampa una "k" prima della linea.
L'obbiettivo e' eliminare la "k" prima della linea.... e non so come fare.
La stampa avviene correttamente, sul fogliettino, alle coordinate impostate.

A parte quest'unico comando .... non riesco a mandare niente di altro.
Mi potete dire come posso fare??

Grazie
Daniele

Alberto Salvati

unread,
Nov 7, 2023, 9:53:10 AM11/7/23
to
E grazie che non va....mado' che idee confuse!
Prendi una stringa UNICODE, ci metti dentro 2 caratteri, poi fai cast in AnsiString, la rimetti in una stirnga unicode e poi la passi con un ulteriore cast ad pansichar....






Var S1 : ANSISTRING;
I : Integer;
begin
Printer.BeginDoc;
S1:=Char(27)+Char(64);
I:=Escape(Printer.Canvas.Handle, PASSTHROUGH, Length(s1), PAnsiChar(s1), nil);
....


Daniele

unread,
Nov 7, 2023, 12:43:42 PM11/7/23
to
Ciao Alberto,
lo so che e' un caos dentro un'altro caos all'interno di un frullatore; Ma per quanto sembri incomprensibile .... non va niente ....
Per non va niente intendo che non riesco a mandare questa inizializzazione alla stampantina.
La invio, usando il codice corretto da te, e non succede niente .... o meglio ... il risultato non cambia.

Come ultima spiaggia, che sembra funzionare parzialmente, ho trovato un codice "paleolitico" che *sembra* faccia ancora il suo "dovere".
(https://stackoverflow.com/questions/7585084/detect-the-status-of-a-printer-paper)

Ecco il codice:

TPrinterData = record
DataLength: Word;
Data: array [0..255] of AnsiChar; // let's use 1 byte long AnsiChar
end;

BufferIn : TPrinterData;
BufferOut : TPrinterData;
S1 : String;


Printer.BeginDoc
....

S1:=Char(27)+Char(64);
StrPCopy(BufferIn.Data, AnsiString(S1));
BufferIn.DataLength := StrLen(PChar(S1));
FillChar(BufferOut.Data, Length(BufferOut.Data), #0);
BufferOut.DataLength := 0;
Escape(Printer.Canvas.Handle, PASSTHROUGH, 0, @BufferIn, @BufferOut);
.....

Printer.EndDoc



Per l'inizializzazione va .... dovro' provare altre sequenze ESC.

Ora e' nato un nuovo problema (ecco perche' funziona in modo parziale).
Non tutti i driver supportano il PASSTHROUGH e, onestamente, non so come fare per capire se il driver della stampante supporta questa modalita'.
Usando questo codice

TestInt := PASSTHROUGH; // Integer
if Escape(Printer.Handle,
QUERYESCSUPPORT,
sizeof(TestInt),
@TestInt,
nil) > 0 then

non ottengo molto perche' tutti i driver delle stampanti che installato .... ritornano un valore maggiore di zero.

Per esempio sia il PDF24 che la HP deskjet 9010 ritornano un valore maggiore di zero (2, di cui ignoro il significato), eseguo il codice di cui sopra e:
Per PDF24 ottengo un errore indescrivibile
Per HP deskjet 9010 la stampa non viene avviata ed esce un errore di stampa generico.

Come faccio a capire quale stampante accetta o meno le sequenze ESC ???
Sto provando alcune soluzioni (la piu' recente e' del 2012) ... ma nessuna che da un risultato certo.

Lo so ... sto approffittando della tua disponibilita' .....

Grazie per l'interesse

Ciao
Daniele

Alberto Salvati

unread,
Nov 8, 2023, 2:37:12 AM11/8/23
to
On Tuesday, November 7, 2023 at 6:43:42 PM UTC+1, Daniele wrote:
> Ciao Alberto,
> Il giorno martedì 7 novembre 2023 alle 15:53:10 UTC+1 Alberto Salvati ha scritto:
> > E grazie che non va....mado' che idee confuse!
> > Prendi una stringa UNICODE, ci metti dentro 2 caratteri, poi fai cast in AnsiString, la rimetti in una stirnga unicode e poi la passi con un ulteriore cast ad pansichar....
> >
> >
> >
> >
> >
> >
> > Var S1 : ANSISTRING;
> > I : Integer;
> > begin
> > Printer.BeginDoc;
> > S1:=Char(27)+Char(64);
> > I:=Escape(Printer.Canvas.Handle, PASSTHROUGH, Length(s1), PAnsiChar(s1), nil);
> > ....
> lo so che e' un caos dentro un'altro caos all'interno di un frullatore;

Un conto è il caos, un conto è scrivere codice cinofallico e aspettarsi che funzioni.....

> Per l'inizializzazione va .... dovro' provare altre sequenze ESC.

Se va hai risolto, giusto?




>
> Ora e' nato un nuovo problema (ecco perche' funziona in modo parziale).
> Non tutti i driver supportano il PASSTHROUGH e, onestamente, non so come fare per capire se il driver della stampante supporta questa modalita'.
> Usando questo codice
>
> TestInt := PASSTHROUGH; // Integer
> if Escape(Printer.Handle,
> QUERYESCSUPPORT,
> sizeof(TestInt),
> @TestInt,
> nil) > 0 then
>
> non ottengo molto perche' tutti i driver delle stampanti che installato .... ritornano un valore maggiore di zero.

Ma hai letto questo?


The PASSTHROUGH printer escape function is supported by PostScript drivers in GDI-centric mode or compatibility mode, but not in PostScript-centric mode. Drivers in PostScript-centric mode can use the POSTSCRIPT_PASSTHROUGH escape function. To set a PostScript driver mode, call the POSTSCRIPT_IDENTIFY escape function.

For PASSTHROUGH data sent by EPSPRINTING or PostScript-centric applications, the PostScript driver will not make any modifications. For PASSTHROUGH data sent by other applications, if the PostScript driver is using BCP (Binary Communication Protocol) or TBCP (Tagged Binary Communication Protocol) output protocol, the driver does the appropriate BCP or TBCP quoting on special characters, as described in "Adobe Serial and Parallel Communications Protocols Specification." This means that the application should send either ASCII or pure binary PASSTHROUGH data.


A.

Alberto Salvati

unread,
Nov 8, 2023, 2:38:45 AM11/8/23
to
Aggiungo:

https://groups.google.com/g/borland.public.delphi.winapi/c/JeSSdvJKf_o#a7d768caffd3ec31

Codice:

Customer submitted FAQ - How to print raw data!!!
[by Joe C. Hecht]

Writting raw data to the printer.
Category :Windows API
Platform :All
Product :All 16/32 bit

Question:
How do I write a raw string of a data to the printer?

The following unit "PrtRaw.pas" demonstrates a 16/32 bit
raw printing unit for Delphi and Borland C Builder.

Following the unit, is an exmaple on using the
PrtRaw unit.

Notes:

1) You are responsible for embedding all necessary
control codes that the printer may require (including
form feed codes).

2) You must specify a valid printer and port name.

unit PrtRaw;

interface

uses
WinTypes;

{$IFDEF WIN32}
type SpoolInt = DWORD;
{$ELSE}
type SpoolInt = integer;
{$ENDIF}

function StartRawPrintJob(PrinterName : pChar;
Port : pChar;
DocName : pChar) : THandle;

function StartRawPrintPage(hPrn : THandle) : integer;

function PrintRawData(hPrn : THandle;
Buffer : pointer;
NumBytes : SpoolInt) : integer;

function EndRawPrintPage(hPrn : THandle) : integer;

function EndRawPrintJob(hPrn : THandle) : integer;


implementation
uses
WinProcs,
{$IFDEF WIN32}
WinSpool;
{$ELSE}
Print;
{$ENDIF}


function StartRawPrintJob(PrinterName : pChar;
Port : pChar;
DocName : pChar) : THandle;
{$IFDEF WIN32}
var
hPrn : THandle;
DocInfo1 : TDocInfo1;
{$ENDIF}
begin
{$IFDEF WIN32}
if (OpenPrinter(PChar(PrinterName),
hPrn,
nil) = FALSE) then begin
Result := THandle(-1);
Exit;
end;
DocInfo1.pDocName := DocName;
DocInfo1.pOutputFile := Port;
DocInfo1.pDataType := 'RAW';
if (StartDocPrinter(hPrn,
1,
@DocInfo1) = 0) then begin
Result := THandle(-1);
exit;
end;
Result := hPrn;
{$ELSE}
result := OpenJob(Port,
DocName,
0);
{$ENDIF}
end;

function StartRawPrintPage(hPrn : THandle) : integer;
begin
{$IFDEF WIN32}
if (StartPagePrinter(hPrn) = FALSE) then begin
Result := -1;
exit;
end;
result := 1;
{$ELSE}
result := StartSpoolPage(hPrn);
{$ENDIF}
end;


function PrintRawData(hPrn : THandle;
Buffer : pointer;
NumBytes : SpoolInt) : integer;
{$IFDEF WIN32}
var
BytesWritten : DWORD;
{$ENDIF}
begin
if (NumBytes = 0) then begin
Result := 1;
exit;
end;
{$IFDEF WIN32}
if (WritePrinter(hPrn,
Buffer,
NumBytes,
BytesWritten) = FALSE) then begin
Result := -1;
exit;
end;
if (NumBytes <> BytesWritten) then begin
Result := -1;
exit;
end;
Result := 1;
{$ELSE}
result := WriteSpool(hPrn,
Buffer,
NumBytes);
{$ENDIF}
end;


function EndRawPrintPage(hPrn : THandle) : integer;
begin
{$IFDEF WIN32}
if (EndPagePrinter(hPrn) = FALSE) then begin
Result := -1;
exit;
end;
Result := 1;
{$ELSE}
result := EndSpoolPage(hPrn);
{$ENDIF}
end;


function EndRawPrintJob(hPrn : THandle) : integer;
begin
{$IFDEF WIN32}
if (EndDocPrinter(hPrn) = FALSE) then begin
Result := -1;
exit;
end;
if (ClosePrinter(hPrn) = FALSE) then begin
Result := -1;
exit;
end;
Result := 1;
{$ELSE}
result := CloseJob(hPrn);
{$ENDIF}
end;


end.

Example of use:

uses
PrtRaw;


procedure TForm1.Button1Click(Sender: TObject);
var
hPrn : THandle;
Data : array[0..31] of char;
begin

hPrn := StartRawPrintJob('Generic / Text Only',
'LPT1:',
'My Document');
if (integer(hPrn) < 0) then begin
ShowMessage('StartRawPrintJob Failed');
exit;
end;

if (StartRawPrintPage(hPrn) < 0) then begin
ShowMessage('StartRawPrintPage Failed');
EndRawPrintJob(hPrn);
exit;
end;

Data[0] := 'P';
Data[1] := 'a';
Data[2] := 'g';
Data[3] := 'e';
Data[4] := #32;
Data[5] := '1';
Data[6] := #13;
Data[7] := #10;

if (PrintRawData(hPrn,
@data,
8) < 0) then begin
ShowMessage('PrintRawData Failed');
EndRawPrintPage(hPrn);
EndRawPrintJob(hPrn);
exit;
end;

if (EndRawPrintPage(hPrn) < 0) then begin
ShowMessage('EndRawPrintPage Failed');
EndRawPrintJob(hPrn);
exit;
end;

if (StartRawPrintPage(hPrn) < 0) then begin
ShowMessage('StartRawPrintPage Failed');
EndRawPrintJob(hPrn);
exit;
end;
Data[0] := 'P';
Data[1] := 'a';
Data[2] := 'g';
Data[3] := 'e';
Data[4] := #32;
Data[5] := '2';
Data[6] := #13;
Data[7] := #10;

if (PrintRawData(hPrn,
@data,
8) < 0) then begin
ShowMessage('PrintRawData Failed');
EndRawPrintPage(hPrn);
EndRawPrintJob(hPrn);
exit;
end;

if (EndRawPrintPage(hPrn) < 0) then begin
ShowMessage('EndRawPrintPage Failed');
EndRawPrintJob(hPrn);
exit;
end;

if (EndRawPrintJob(hPrn) < 0) then begin
ShowMessage('EndRawPrintJob Failed');
exit;
end;

end;

end.



Daniele

unread,
Nov 8, 2023, 5:11:19 AM11/8/23
to
Ciao Alberto,
grazie per le risposte.
A dire il vero non l'avevo letto ..... mentre il codice nel secondo messaggio l'avevo gia' visto.

Con il codice riportato nel mio precedente messaggio il problema e' risolto. Ora ho il problema di capire quale stampante accetta i codici ESC.

Che tu sappia, una stampante che supporta il postscript puo' anche supportare le sequenze ESC?
Domanda stupida, ma dalle prove eseguite (ecco perche' la domanda ....) sulle due stampanti a disposizione (EPSON T30 e HP DESKJET 9010) ho questi risultati:
HP 9010 POSTSCRIPT supportato
EPSON T30 POSTSCRIP non supportato.

Quindi, deduco (forse erroneamente) che se il postscript non e' supportato allora accetta le sequenze ESC.

Grazie per l'aiuto

Ciao
Daniele

Daniele

unread,
Nov 8, 2023, 6:17:09 AM11/8/23
to
Alberto, scusami ...

questa funzione

TestInt:=PASSTHROUGH;

if Escape(Printer.Handle,
QUERYESCSUPPORT,
sizeof(TestInt),
@TestInt,
Nil) > 0 then

ritorna sempre un valore >0 anche se la stampante NON supporta le sequenze ESC.

Avevo pensato di usare questa funzione per capire se supportava il postscript

function IsPostScriptPrinter(dc : hdc) : bool;
var
TestInt : integer;
a : array[0..255] of char;
err : integer;
s : string;
begin
Result := false;
TestInt := GETTECHNOLOGY;
{$IFDEF WIN32}
if ExtEscape(Dc,
QUERYESCSUPPORT,
sizeof(TestInt),
@TestInt,
0,
Nil) > 0 then begin
Err := ExtEscape(Dc,
GETTECHNOLOGY,
0,
nil,
256,
@a);
{$ELSE}
if Escape(Dc,
QUERYESCSUPPORT,
sizeof(TestInt),
@TestInt,
Nil) > 0 then begin
Err := Escape(Dc,
GetTechnology,
0,
nil,
@a);
{$ENDIF}
if Err > 0 then begin
s := UpperCase(StrPas(a));
if Pos('POSTSCRIPT', s) > 0 then
result := true;
end;
end;
end;

ma su tutte le stampanti ritorna false.
Quindi tutte le stampanti non sono POSTSCRIP e tutte accettano le sequenze ESC ..... ma non e' vero!!

Che suggerisci ??

Grazie

Daniele

Alberto Salvati

unread,
Nov 8, 2023, 10:56:17 AM11/8/23
to

Partiamo da alcuni presupposti:

1) alcune stampanti supportano le sequenze escape
2) alcune stampanti NON supportano le sequenze escape
3) lato software, sembra non vi sia modo di capire se una particolare stampante sia nel gruppo 1 o nel gruppo 2


Dati questi presupposti, ti suggerisco, tanto per iniziare, di fare un passo indietro e tornare al tuo VERO problema.
Il tuo vero problema non è capire se una stampante supporta o meno le sequenze escape ed eventualmente mandare sequence escape.
Quindi, tu, cosa devi fare, esattamente?

A.

Daniele

unread,
Nov 8, 2023, 11:38:27 AM11/8/23
to
Grazie Alberto per il tuo supporto.
Praticamente con il terzo punto mi hai demolito.
Il problema che devo risolvere, risolto in modo ortodosso, e' capire come stampare.
Dato che mi sono spiegato in modo aberrante ..... tento di spiegarmi meglio.
Il programma in questione e' su server e viene utilizzato da 5 pc che stampano in tre modi diversi
1 stampa con pdf24
3 stampano su questa epson t30
1 stampa sulla hp deskjet 9010

dove
PDF24 e HP 9010 non supportano ESC
EPSON T30 supporta ESC

Quello che mi sarebbe piaciuto fare era capire, via software, chi di loro accettava le sequenze ESC ed utilizzarle in modo mirato.

Come ho risolto?
Ho creato una tabella con 3 campi nomepc, nomestampante e usaesc
Ho 5 record dove avro', per esempio, PC1; EPSON-T30; TRUE
In questo caso PRIMA di stampare cerco il record del pc in uso, ho il nome della stampante e se il campo usaesc e' vero eseguo il blocco dell'inizializzazione via ESC altrimenti stampo in modo normale.

Cosi' funziona tutto senza altri problemi.

Ti ringrazio tantissimo per il tuo prezioso aiuto.

Ciao
Daniele
0 new messages