Delphi 将命令直接发送到打印机的正确方法!
好的,我是这样做的:Delphi 将命令直接发送到打印机的正确方法!,delphi,printing,epson,Delphi,Printing,Epson,好的,我是这样做的: 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; b
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;
procedure TMainWindow.btnRawPrintClick(发送方:ToObject);
开始
开始打印;
SendStr(#27#69);
SendStr(“MyData”);
SendStr(#10);
尾迹;
结束;
过程TMainWindow.SendStr(文本:字符串);
变量
i:整数;
数据:字符数组;
开始
对于i:=1到长度(文本)do
开始
设置长度(数据,i);
数据[Pred(i)]:=文本[i];
结束;
如果(PrintRawData)(printHandle,
数据,
长度(数据))<0)然后开始
ShowMessage(“PrintRawData失败”);
EndRawPrintPage(打印手柄);
EndRawPrintJob(打印句柄);
出口
结束;
结束;
程序TMainWindow.BeginPrint;
开始
printHandle:=StartRawPrintJob('EPSON TM-T70收据'、'ESDPRT001'、'测试文件');
如果printHandle<0,则
开始
ShowMessage('StartRawPrintJob失败!');
出口
结束;
如果(StartRawPrintPage(printHandle)<0),则开始
ShowMessage('StartRawPrintPage失败!');
EndRawPrintJob(打印句柄);
出口
结束;
结束;
程序TMainWindow.EndPrint;
开始
如果(EndRawPrintPage(printHandle)<0),则开始
ShowMessage('EndRawPrintPage失败');
EndRawPrintJob(打印句柄);
出口
结束;
如果(EndRawPrintJob(printHandle)<0),则开始
ShowMessage('EndRawPrintJob失败');
出口
结束;
结束;
此外,我还更改了我从中获取的一些代码:
函数PrintRawData(hPrn:THandle;
缓冲区:指针;
NumBytes:SpoolInt):整数;
{$IFDEF WIN32}
变量
BytesWrite:德沃德;
{$ENDIF}
开始
NumBytes:=NumBytes*2// 你使用了错误的函数。使用,将PASSTHROUGH标志作为第二个参数传递。这会将未经处理的原始转义码直接发送到打印机
Joe Hecht(以前来自Borland)几次发布了一个单元,使这变得更容易。我在这里找到了。由于Ansi和Unicode字符之间的更改,您当前的代码正在以错误的格式向打印机发送数据。您正在使用的打印机显然能够容忍一定数量的错误,这就是为什么您的一些命令可以工作的原因,但有一个限制
在您的Delphi版本中,Char
相当于WideChar
,因此将Char
代码改为使用AnsiChar
,这样您就可以按照打印机的要求发送单字节字符。您的PrintRawData
函数以前没有问题。你找错钱了。打印机不希望接收双字节Unicode字符,但这就是您所做的更改
还原原始的PrintRawData
代码后,将SendStr
函数更改为:
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;
过程TMainWindow.SendStr(常量文本:字符串);
变量
资料来源:AnsiString;
开始
数据:=文本;
如果(PrintRawData)(printHandle,
PAnsiChar(数据),
长度(数据))<0)然后开始
ShowMessage(“PrintRawData失败”);
EndRawPrintPage(打印手柄);
EndRawPrintJob(打印句柄);
结束;
结束;
我对代码做了以下更改:
将Char
数组替换为AnsiString
与使用循环一次增加一个字符的数据数组不同,使用单个赋值语句进行Unicode到Ansi的转换,并让RTL负责转换
键入将数据字符串强制转换为PAnsiChar
,以传递到PrintRawData
除非需要修改字符串参数的内容,否则将其作为常量传递
当函数已经完成时,不需要显式的exit
语句
你是怎样把代码送到打印机的?直接到LPT1:还是其他方法?您是否已启用打印机调试模式以查看正在发送的十六进制数?您将发送什么来代替ESC
?对于大多数较旧的爱普生打印机,它是ASCII字符#27。是的,我发送#27而不是ESC。我使用WinAPI WritePrinter函数发送命令!谢谢你的帖子。我更新了我的帖子,添加了一些代码。但是,我不理解将PASSTHROUGH标志作为第二个参数。第二个参数是什么函数?你能再解释一下吗?Peacelyk,Ken指的是Windows API函数。@Peacelyk:对不起。我忘了在我的原始答案中提供MSDN上转义的链接。我现在已经更新了。肯,np。我一定要检查一下。迂腐的一点:我喜欢注释行数据:=文本来表示“Unicode到ansi的转换在这里发生”,因为这是一种潜在的有损转换。虽然这段代码可能会解决问题,但几句解释将对当前和未来的读者有很大帮助。
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;
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;
StrLstYazdir(Memo1.Lines ,'Lexmark Forms Printer 2491')