2

Ok, here is how i do it:

procedure TMainWindow.btnRawPrintClick(Sender: TObject);
begin
  BeginPrint;
  SendStr(#27#69);
  SendStr('MyData');
  SendStr(#10);
  EndPrint;
end;

procedure TMainWindow.SendStr(Text: String);
var
  i: Integer;
  data : Array of Char;
begin
  for i := 1 to Length(Text) do
  begin
    SetLength(data,i);
    data[Pred(i)] := Text[i];
  end;

  if (PrintRawData(printHandle,
                   data,
                   Length(data)) < 0) then begin
    ShowMessage('PrintRawData Failed');
    EndRawPrintPage(printHandle);
    EndRawPrintJob(printHandle);
    exit;
  end;
end;

procedure TMainWindow.BeginPrint;
begin
  printHandle := StartRawPrintJob('EPSON TM-T70 Receipt','ESDPRT001','Test Document');

  if printHandle < 0 then
  begin
    ShowMessage('StartRawPrintJob Failed!');
    exit;
  end;

  if (StartRawPrintPage(printHandle) < 0) then begin
    ShowMessage('StartRawPrintPage Failed!');
    EndRawPrintJob(printHandle);
    exit;
  end;
end;

procedure TMainWindow.EndPrint;
begin
  if (EndRawPrintPage(printHandle) < 0) then begin
    ShowMessage('EndRawPrintPage Failed');
    EndRawPrintJob(printHandle);
    exit;
  end;

  if (EndRawPrintJob(printHandle) < 0) then begin
    ShowMessage('EndRawPrintJob Failed');
    exit;
  end;
end;

Also i changed a little code that i took from here:

function PrintRawData(hPrn : THandle;
                      Buffer : pointer;
                      NumBytes : SpoolInt) : integer;
{$IFDEF WIN32}
var
  BytesWritten : DWORD;
 {$ENDIF}
begin
  NumBytes := NumBytes * 2;    //<-- I added this line
  ...

However, something is wrong as some commands (escape sequences) don't work as expected!

Peacelyk
  • 1,126
  • 4
  • 24
  • 48
  • 1
    How are you getting the codes to the printer? Direct to LPT1: or some other method? Have you enabled the printer debug mode to see the hex you are sending? – mj2008 May 09 '11 at 12:30
  • What are you sending in place of `ESC`? For most older Epson printers, it's ASCII character #27. – Ken White May 09 '11 at 12:31
  • Yes, i send #27 instead of ESC. I use win api WritePrinter function for sending commands! – Peacelyk May 09 '11 at 13:05

3 Answers3

6

You're using the wrong function. Use Escape, passing the PASSTHROUGH flag as the second parameter. This sends the raw, unprocessed escape codes to the printer directly.

Joe Hecht (formerly of Borland) has posted a unit several times that makes this easier. I found unit PrtRaw here.

Ken White
  • 123,280
  • 14
  • 225
  • 444
  • Thank you for your post. I updated my post, adding some code. However, i don't understand passing PASSTHROUGH flag as the second parameter. Second parameter to what function? Could you explain that a little more? – Peacelyk May 09 '11 at 14:56
  • Peacelyk, Ken is referring to the [`Escape`](http://msdn.microsoft.com/en-us/library/dd162701.aspx) Windows API function. – Rob Kennedy May 09 '11 at 15:43
  • @Peacelyk: Sorry. I forgot to provide the link to Escape on MSDN in my original answer. I've updated it now. – Ken White May 09 '11 at 17:15
  • Ken, np. I'll definitely check it – Peacelyk May 09 '11 at 17:58
3

Your current code is sending data to the printer in the wrong format due to changes between Ansi and Unicode characters. The printer you're using is evidently able to tolerate some amount of error, which is why some of your commands worked, but there's a limit.

In your version of Delphi, Char is equivalent to WideChar, so change your Char code to use AnsiChar instead, so you can send one-byte characters, as the printer expects. Your PrintRawData function was fine before. Your change is wrong. The printer does not expect to receive two-byte Unicode characters, but that's what your change amounts to.

After restoring the original PrintRawData code, change your SendStr function to this:

procedure TMainWindow.SendStr(const Text: string);
var
  data: AnsiString;
begin
  data := Text;

  if (PrintRawData(printHandle,
                   PAnsiChar(data),
                   Length(data)) < 0) then begin
    ShowMessage('PrintRawData Failed');
    EndRawPrintPage(printHandle);
    EndRawPrintJob(printHandle);
  end;
end;

I made the following changes to the code:

  1. Replace the Char array with an AnsiString.
  2. Instead of growing the data array one character at a time with a loop, do the Unicode-to-Ansi conversion with a single assignment statement and let the RTL take care of the conversion.
  3. Type-cast the data string to PAnsiChar for passing to PrintRawData.
  4. Pass string parameters as const unless you need to modify their contents.
  5. No need for an explicit exit statement when the function is already finished.
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • Pedantic point: I like to comment the line data := Text to say "Unicode to ansi conversion happens here", because it's a potentially Lossy Conversion. – Warren P May 09 '11 at 23:12
0
Procedure StrLstYazdir(pYazilacakListe: TStringList; pYazici: String);
var
  hPrn: THandle;
  yazilacakVeri: AnsiString;
  intA: Integer;
begin
  hPrn := StartRawPrintJob(PChar(pYazici), '', 'Varakim');
  if (Integer(hPrn) < 0) then
  Begin
    ShowMessage('StartRawPrintJob Hatalı');
    Exit;
  End;

  if (StartRawPrintPage(hPrn) < 0) then
  Begin
    ShowMessage('StartRawPrintPage Hatalı');
    EndRawPrintJob(hPrn);
    Exit;
  end;

  For intA := 0 to pYazilacakListe.Count - 1 do
  Begin
    yazilacakVeri := pYazilacakListe[intA] + #13 + #10;

    if (PrintRawData(hPrn, PAnsiChar(yazilacakVeri), Length(yazilacakVeri)) < 0)
    then
    begin
      ShowMessage('PrintRawData Hatalı');
      EndRawPrintPage(hPrn);
      EndRawPrintJob(hPrn);
      Exit;
    End;
  End;
  if (EndRawPrintPage(hPrn) < 0) then
  begin
    ShowMessage('EndRawPrintPage Hatalı');
    EndRawPrintJob(hPrn);
    Exit;
  End;

  if (EndRawPrintJob(hPrn) < 0) then
  begin
    ShowMessage('EndRawPrintJob Hatalı');
    Exit;
  End;
End;

Usage:

StrLstYazdir(Memo1.Lines ,'Lexmark Forms Printer 2491')
LU RD
  • 34,438
  • 5
  • 88
  • 296
Ali KOCA
  • 21
  • 2
  • 2
    While this code may solve the problem, a few words of explanation would be of big help to current and future readers. – Thom May 11 '15 at 11:28