Thema: Delphi QR-Code mit ESC-Commands

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#9

AW: QR-Code mit ESC-Commands

  Alt 27. Jul 2022, 17:47
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 Length(TextToPrint) oder 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.




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;
$2B or not $2B

Geändert von himitsu (27. Jul 2022 um 17:53 Uhr)
  Mit Zitat antworten Zitat