delphi – Zebra打印机直接通信

基于
this question,我实现了以下代码,将直接命令发送到Zebra TLP2844

var
  cmm: AnsiString;
  i: integer;
begin
  commands.saveToFile('path\to\a\file');
  Printer.BeginDoc;
  cmm := '';
  for i := 0 to commands.Count-1 do
    cmm := cmm + commands[i] + #10;
  Escape(Printer.Canvas.Handle, PASSTHROUGH, Length(cmm), PAnsiChar(cmm), nil);
  Printer.EndDoc;
end;

命令是一个TSringList,包含我要发送给打印机的所有命令.
请注意,我将所有命令保存到文本文件中.

好吧,如果我发送这个文本文件打印,通过驱动程序首选项,使用工具 – >行动 – >发送文件,它打印完美.

如果我使用上面的代码,它会在打印后吐出一些额外的标签行.

显然,这显示我在这里做错了什么,但我无法弄清楚是什么.

我试过了什么

>逐个发送命令,而不是像代码中那样连接它们.结果:没有打印出来.
>改变#13#10的#10.结果:同样的疯狂行为(事实上Zebra EPL documentatins说它会忽略它找到的任何#13)

我还应该尝试以什么方式将命令发送到打印机,与Zebra的工具完全相同?

最佳答案 AFAIK您需要按照ExtEscape()API布局的预期格式化缓冲区.我从未使用Escape(),而是使用ExtEscape() – 它与Zebra打印机一起使用.

这是what the MSDN doc states

lpszInData [in] A pointer to the input structure required for the
specified escape. The first word in the buffer contains the number of
bytes of input data
. The remaining bytes of the buffer contain the
data itself.

所以你可以这样编码:

  cmm := '00'; // reserve space for the initial `word`
  for i := 0 to commands.Count-1 do
    cmm := cmm + commands[i] + #10;
  pword(cmm)^ := length(cmm)-2; // store the length
  if ExtEscape(Printer.Canvas.Handle, PASSTHROUGH, Length(cmm), pointer(cmm), 0, nil)<0 then
    raise Exception.Create('Error at printing to printer');
  Printer.EndDoc;

请注意,如果您的命令格式不正确(例如缺少字符),则可能只会在打印机后台处理程序中创建内存不足错误 – 是的,我已经看到了!在这种情况下,您可能必须杀死然后重新启动打印机后台处理程序服务…修复您的代码…然后再试一次……

并且不要忘记按照Zebra doc的要求将ESC字符放在每个命令[]的开头.

点赞