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));
=
RaiseLastOSError (früher
RaiseWin32Error)
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;