Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi QR-Code mit ESC-Commands (https://www.delphipraxis.net/211048-qr-code-mit-esc-commands.html)

Thomas Feichtner 20. Jul 2022 15:24

QR-Code mit ESC-Commands
 
Hallo zusammen,

hat jemand schon mal einen QR-Code mit ESC-Commands an einen STAR Bondrucker geschickt?
Ich komme bei der Beschreibung nicht weiter.
Leider habe ich auch keinen Drucker zum Testen und dann dies nur beim Kunden machen.

https://www.manualslib.com/manual/16...age=136#manual

Mit dem Befel ESC GS y D 1 komme ich nicht klar wie ich den schicken soll?

Ich möchte folgenden Text schicken "Hallo QR-Code"

Redeemer 20. Jul 2022 15:43

AW: QR-Code mit ESC-Commands
 
Was ist die Frage? Wie du nicht druckbare Zeichenliterale in Pascal schreibst? So:
#$1B
#$1D

Ggf. nach RawByteString casten (ab D2009).

Thomas Feichtner 26. Jul 2022 06:59

AW: QR-Code mit ESC-Commands
 
Die Frage ist folgende.
Hat schon jemand mit ESC-Befehlen einen QR-Code mit STAR-BONDRUCKER gedruckt?

Achim Kalwa 26. Jul 2022 17:00

AW: QR-Code mit ESC-Commands
 
Zitat:

Zitat von Thomas Feichtner (Beitrag 1508976)
hat jemand schon mal einen QR-Code mit ESC-Commands an einen STAR Bondrucker geschickt?

Vermutlich nicht, sonst hättest Du eine entsprechende Meldung bekommen. Aber Du kannst der Erste sein!
Zitat:

Zitat von Thomas Feichtner (Beitrag 1508976)
Ich komme bei der Beschreibung nicht weiter. Leider habe ich auch keinen Drucker zum Testen und dann dies nur beim Kunden machen.
https://www.manualslib.com/manual/16...age=136#manual
Mit dem Befel ESC GS y D 1 komme ich nicht klar wie ich den schicken soll?
Ich möchte folgenden Text schicken "Hallo QR-Code"

Du möchtest wissen, wie der Text aufbereitet werden muss, um als Escape-Sequenz vom Drucker verstanden zu werden. Die Doku zum Drucker gibt ja bereits die Anfang der Datensequenz für den QR-Code vor. Du musst jetzt "nur noch" die Anzahl der Datenbytes berechnen (nL und nH in der Doku), und dann die Nutzdaten anfügen. Hier wird ein RawByteString verwendet, damit keine Konvertierung der Bytes nach Unicode oder Ansi stattfindet:

Code:
// ungetestet; direkt hier in den Editor getippt:
var
  Data   : RawByteString;
  Message : string;
  i      : Integer;
  CharLen : Integer;
  nLow   : Byte;
  nHigh  : Byte;
begin
  Message := 'Hallo QR-Code';
  CharLen := Length(Message);
  if CharLen > 7089 then
    raise Exception.Create('String too long.');

  nHigh := CharLen div 256;
  nLow := CharLen mod 256;

  Data := #$1B#$1D#$79#$44#$31#$00; // ESC GS y D 1 NUL
  Data := Data + AnsiChar(nLow) + AnsiChar(nHigh);
  for i := 1 to CharLen do
  begin
    Data := Data + AnsiChar(Ord(Message[i]));
  end;
  // Data an den Drucker senden überlasse ich Dir
end;
HTH
Achim

TurboMagic 26. Jul 2022 18:38

AW: QR-Code mit ESC-Commands
 
Wenn man es noch besser machen will, könnte man für $1B etc. Konstanten anlegen...

freimatz 27. Jul 2022 08:07

AW: QR-Code mit ESC-Commands
 
Kathinka sagt: So eine Drucker kostet 200-300. Nach einem halben Tag rumprobieren ins Blaue und/oder einmal zum Kunden fahren weils doch nicht so funktioniert wie's gedacht hat sich das gelohnt. :wink:

himitsu 27. Jul 2022 09:27

AW: QR-Code mit ESC-Commands
 
Oder man lässt sich vom Kunden ein Gerät schicken.
(einige Kunden kaufen sogar extra ein Gerät, nur um es hier her zu schicken, wenn sie grade Keines übrüg haben, und seltener kaufen wir uns Die auch mal selber,
abgesehn von einigen RFID-Readern, welche wir direkt vom Hersteller beziehen, unseren Kunden weiterverkaufen und Kolleke+ich und ein paar Testgeräte abgezwackt hab)

Papaschlumpf73 27. Jul 2022 16:31

AW: QR-Code mit ESC-Commands
 
Wenn Escape-Sequenzen an den Drucker geschickt werden sollen, wird das mit dem ganzen Grafik-Gedöns aller Printer.Canvas und Co. wahrscheinlich nichts werden. Ich habe hier noch ein paar Codeschnipsel gefunden, die schon über 20 Jahre alt sind. Damit habe ich früher 10.000e Seiten PCL-Text in wenigen Sekunden zum Drucker gejagt. Allerdings funktioniert es nicht mehr so richtig - musste zu viel rausnehmen. Aber mal so als Denkansatz oder Google-Hilfe:
Delphi-Quellcode:
uses winapi.WinSpool, Printers;

procedure TForm5.Button1Click(Sender: TObject);
begin
TextToPrinter(Printer.Printers[Printer.PrinterIndex], 'Mein Text');
end;

procedure TForm5.TextToPrinter(Drucker, TextToPrint: String);
var pHandle: THandle; DocInfo1: TDocInfo1; N: DWORD;
begin
DocInfo1.pDocName:=PChar('MeinDokumentname');
DocInfo1.pOutputFile:=nil;
DocInfo1.pDataType:='RAW';
if not OpenPrinter(PChar(Drucker), pHandle, NIL) then raise Exception.Create(SysErrorMessage(GetLastError));
if StartDocPrinter(pHandle, 1, @DocInfo1)=0 then raise Exception.Create(SysErrorMessage(GetLastError));
if not StartPagePrinter(pHandle) then raise Exception.Create(SysErrorMessage(GetLastError));
if not WritePrinter(pHandle, PChar(TextToPrint), Length(TextToPrint), N) then raise Exception.Create(SysErrorMessage(GetLastError));
if not WritePrinter(pHandle, PChar(#12#13), 2, N) then raise Exception.Create(SysErrorMessage(GetLastError));
if not EndPagePrinter(pHandle) then raise Exception.Create(SysErrorMessage(GetLastError));
if not EndDocPrinter(pHandle) then raise Exception.Create(SysErrorMessage(GetLastError));
if not ClosePrinter(pHandle) then raise Exception.Create(SysErrorMessage(GetLastError));
end;

himitsu 27. Jul 2022 16:47

AW: QR-Code mit ESC-Commands
 
Zitat:

Zitat von Papaschlumpf73 (Beitrag 1509381)
die schon über 20 Jahre alt sind. ... Allerdings funktioniert es nicht mehr so richtig

Deswegen verwendet man niemals dynamische Typen für statische Daten.

PChar, vor Delphi 2009, war PAnsiChar aber nun ist es PWideChar.
Ebenso auch für Char und String.
Binär wird so jetzt also etwas Anderes verwendet. (2 Byte pro Char)

Selbst dein
Delphi-Quellcode:
Length(TextToPrint)
oder
Delphi-Quellcode:
2
stimmt somit nicht mehr, da PChar(TextToPrint) doppelt so viele Bytes enthält.
Bzw. für PAnsiChar würde Length aber wieder passen.

Auch in Bezug auf Unicode-Strings, und Konvertierungen durch CodesPages, sollte man passendere Typen verwenden, nicht dass irgendwo Bytes verändert werden, beim Konvertieren/Zuweisen zwischen String/AnsiString/PChar/usw.
Früher missbrauchte man gern mal AnsiString, für "binäre" Daten.
Wenn, dann aber jetzt besser RawByteString (quasi ein AnsiString ohne CodePage) oder besser TBytes (ein ByteArray) für binäre Daten verwenden.




Delphi-Quellcode:
raise Exception.Create(SysErrorMessage(GetLastError));
= Delphi-Referenz durchsuchenRaiseLastOSError (früher Delphi-Referenz durchsuchenRaiseWin32Error)

und fällt dir auf, dass dein halber Code praktisch aus Duplikaten besteht?
Delphi-Quellcode:
procedure TForm5.TextToPrinter(Drucker: string; TextToPrint: RawByteString);
var
  pHandle: THandle;
  DocInfo1: TDocInfo1;
  N: DWORD;
begin
  DocInfo1.pDocName   := PChar('MeinDokumentname');
  DocInfo1.pOutputFile := nil;
  DocInfo1.pDataType  := 'RAW';
  if not OpenPrinter(PChar(Drucker), pHandle, nil)
    or (StartDocPrinter(pHandle, 1, @DocInfo1) = 0)
    or not StartPagePrinter(pHandle)
    or not WritePrinter(pHandle, PAnsiChar(TextToPrint), Length(TextToPrint), N)
    or not WritePrinter(pHandle, PAnsiChar(#12#13), 2, N)
    or not EndPagePrinter(pHandle)
    or not EndDocPrinter(pHandle)
    or not ClosePrinter(pHandle)
  then
    RaiseLastOSError;
end;
Aber eigentlich war falsch, dass ClosePrinter unter Umständen garnicht aufgerufen wird?
Und wenn man ganz genau seind will, könnte man auch noch prüfen, ob WritePrinter wirklich Alles gesendet hat.
Delphi-Quellcode:
procedure TForm5.TextToPrinter(Drucker: string; TextToPrint: RawByteString);
var
  pHandle: THandle;
  DocInfo1: TDocInfo1;
  N: DWORD;
begin
  DocInfo1.pDocName   := PChar('MeinDokumentname');
  DocInfo1.pOutputFile := nil;
  DocInfo1.pDataType  := 'RAW';
  if not OpenPrinter(PChar(Drucker), pHandle, nil) then
    RaiseLastOSError;
  try
    if (StartDocPrinter(pHandle, 1, @DocInfo1) = 0)
      or not StartPagePrinter(pHandle)
      or not WritePrinter(pHandle, PAnsiChar(TextToPrint), Length(TextToPrint), N) or (N <> Length(TextToPrint))
      or not WritePrinter(pHandle, PAnsiChar(#12#13), 2, N) or (N <> 2)
      or not EndPagePrinter(pHandle)
      or not EndDocPrinter(pHandle)
    then
      RaiseLastOSError;
  finally
    ClosePrinter(pHandle); // ja, hier die Fehlerbehandlung "vergessen" ... ist eh alles egal und wir wollen doch vorherige Fehlermeldungen nicht "überschreiben".
  end;
end;

Papaschlumpf73 27. Jul 2022 17:55

AW: QR-Code mit ESC-Commands
 
Hey himitsu, was machst du mit meinem schönen alten Code? Damals war ich jung und dumm. Heute älter, aber kein bißchen... :-D:-D
Das war doch nur ein Denkanstoß, damit er nicht mit Printer.Canvas.Textout oder so herum probiert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:14 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz