斑马打印机直接通讯

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工具相同的方式向打印机发送命令?

3个回答

2
据我所知,您需要按照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;

请注意,如果您的命令格式不正确(例如缺少字符),它可能会在打印机池中创建内存错误 - 是的,我见过这种情况!在这种情况下,您可能需要终止并重新启动打印机池服务...修复您的代码...然后再尝试...

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


1

您可以使用以下过程:其中LabelFile是标签文件的完整路径,我们使用此代码,并与通用文本驱动程序打印机配合使用,并将打印机设置为默认打印机。它适用于zebra打印机和Windows XP操作系统。 https://stackoverflow.com/a/27647044/2977139 我希望这能对您有所帮助。


0

如果您想使用Windows打印机驱动程序,应该使用WinSpool单元中定义的WritePrinter。如果我理解正确,Printers单元中的TPrinter对象不会公开其FPrinterHandle成员,因此您可能需要自己使用OpenPrinterClosePrinter

在工作中使用MarkPoint打印机,它们与Zebra打印机有些相似:如果打印机连接到串行端口,我建议尝试使用几个可用组件之一直接连接到串行端口访问打印机。


您可以使用 ExtEscape() API 直接向打印机发送命令,以及常规的 GDI 命令。这对于想要同时编码磁卡和打印卡片布局的斑马打印机非常方便。最新版本的斑马打印机使用 USB,而旧版本使用并行/centronics 连接器。串行技巧在这里行不通。 - Arnaud Bouchez
如果您想/需要“完全控制”,可以使用QueryDosDevice获取的USB设备名称或连接到'\?\LPT1',例如使用CreateFile和THandleStream。 - Stijn Sanders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接