Newsgroup: it.comp.lang.delphi
Titolo: Inviare sequenze ESC alla stampante EPSON T30

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  

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); 
....
 
 

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

 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.

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.
 
 
 


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 

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

 
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.


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