问题
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!
回答1:
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.
回答2:
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:
- Replace the
Char
array with anAnsiString
. - 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.
- Type-cast the data string to
PAnsiChar
for passing toPrintRawData
. - Pass string parameters as const unless you need to modify their contents.
- No need for an explicit
exit
statement when the function is already finished.
回答3:
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')
来源:https://stackoverflow.com/questions/5936511/correct-way-to-send-commands-directly-to-printer