delphidelphi-4

Error in printing a base64 encoded print command using Thermal Printer


I have an application which receives the print command and decodes it. I save the print command in a text file. And then read it in a byte array. The decoded string also contains image part which are displayed as Junk characters. When I try to send the byte array to the printer using WritePrinter function, it returns False. I tried to check the error code returned which was 1784 but couldn’t find anything about this error code and why it may be happening.

Please find below the code snippet :

AssignFile (decodedfile, st_path + '\Sample.txt');
reset(decodedfile);
SetLength(buffer, FileSize(decodedfile));
For i := 1 to FileSize(decodedfile) do
    Read(decodedfile, buffer[i - 1]);
CloseFile(decodedfile);
DocInfo.pDocName := pChar('Direct to Printer');
DocInfo.pOutput := Nil;
DocInfo.pDatatype := pChar('RAW');
PrinterName := cmbPrinters.Text;;
if not WinSpool.OpenPrinter(pChar(PrinterName), hPrinter, nil) then begin
   raise exception.create('Printer not found');
end;
If StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
    Abort;
try
    If not StartPagePrinter(hPrinter) then
        Abort;
    try
        If not WritePrinter(hPrinter, @buffer, Length(buffer), BytesWritten) then begin
            dError := GetLastError;
            ShowMessage(InttoStr(dError));
            Abort;
        end;
    finally
        EndPagePrinter(hPrinter);
    end;
finally
    EndDocPrinter(hPrinter);
end;
WinSpool.ClosePrinter(hPrinter);

If anyone has faced any issue similar to this, kindly let me know if I have missed anything.

Note:

  1. I have verified that there is no error in decoding the input print command.
  2. I use Delphi 4.

Solution

  • It looks like buffer is a dynamic array. It would have been very helpful if you had included the declarations of your variables with the rest of the code. However, I guess with reasonable confidence that its type is

    buffer: array of Byte;
    

    But you pass @buffer to WritePrinter. That's the address of the pointer to the first byte of the array.

    You need to pass simply the pointer to the first byte. Like this:

    WritePrinter(..., Pointer(buffer), ...);
    

    As an aside the way you load the file is a little archaic. It would probably be simpler to create a TMemoryStream and call LoadFromFile on it.

    stream := TMemoryStream.Create;
    try
      stream.LoadFromFile(filename);
      ....
      if not WritePrinter(..., stream.Memory, stream.Size, ...) then
        ....
    finally
      stream.Free;
    end;