4

基于这个问题,我实现了以下代码以将直接命令发送到我的 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;

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

好吧,如果我通过驱动程序首选项发送此文本文件进行打印,使用工具 -> 操作 -> 发送文件,它会完美打印。

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

显然,它向我表明我在这里做错了什么,但我不知道是什么。

我试过的

  • 一个接一个地发送命令,而不是像在代码中那样连接它们。结果:没有打印任何内容。
  • 将#10 更改为#13#10。结果:同样疯狂的行为(实际上 Zebra EPL 文档说它会忽略它发现的任何 #13)

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

4

3 回答 3

2

AFAIK 您需要按照ExtEscape()API 布局的预期格式化缓冲区。我从未使用过Escape(),但是ExtEscape()- 它可以与 Zebra 打印机配合使用。

这是MSDN 文档的说明

lpszInData [in] 指向指定转义所需的输入结构的指针。缓冲区中的第一个字包含输入数据的字节数。缓冲区的剩余字节包含数据本身。

所以你可以这样编码:

  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;

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

并且不要忘记按照 Zebra 文档的要求将ESC字符放在每个 . 的开头。commands[]

于 2013-09-04T07:20:19.033 回答
1

您可以使用此过程:LabelFile 是标签文件的完整路径,我们正在使用此代码并与通用文本驱动程序打印机一起使用,并且打印机被设置为默认打印机。它适用于斑马打印机和 windows xp 操作系统。 https://stackoverflow.com/a/27647044/2977139 我希望这会对你有所帮助。

于 2014-12-25T13:42:54.617 回答
0

如果要使用 Windows 打印机驱动程序,则应使用WritePrinter已定义的WinSpool单位。如果我没看错的话,来自Printers单元的 TPrinter 对象不会暴露它的成员,FPrinterHandle所以你可能需要自己使用。OpenPrinterClosePrinter

在工作中使用过MarkPoint打印机,这有点类似于 Zebra 打印机:如果打印机连接到串行端口,我强烈建议尝试通过使用可用的几个组件之一连接到串行端口来直接访问打印机.

于 2013-09-04T07:18:36.807 回答