许多打印机都有“进纸和剪切”或“剪纸”命令(我说的是 POS - 这里的打印机)。
由于使用 POS.NET 并不总是可行(可怕的驱动程序不兼容),而 GDI 可以做的更多,我们希望在使用 GDI 打印时也使用切纸机。
有没有办法这样做?可能在发出 EndDocument() 时?
或者甚至可能来自.NET?
许多打印机都有“进纸和剪切”或“剪纸”命令(我说的是 POS - 这里的打印机)。
由于使用 POS.NET 并不总是可行(可怕的驱动程序不兼容),而 GDI 可以做的更多,我们希望在使用 GDI 打印时也使用切纸机。
有没有办法这样做?可能在发出 EndDocument() 时?
或者甚至可能来自.NET?
GDI 甚至抽象的 Windows 打印模型在这里都可能对您没有帮助。您将不得不以打印机通常期望接收数据的语言向打印机发送进纸和剪切命令。
例如,Epson TM-T88III 热敏收据打印机本机使用 ESC/POS 语言,而不是 GDI 或 PCL 命令序列。但是,这些打印机中的大多数都带有打印机驱动程序,使 Windows 将它们视为常规 GDI 打印机。这些驱动程序通常的工作方式是将所有 GDI 命令光栅化为软件中的一个大位图,然后通过其本地语言“打印位图”命令将位图分配给打印机进行打印。这通常会产生不太理想的效果:
例如,这是我通常不相关的博客上一个广泛示例的代码片段。您可以在接近尾声时看到我如何BinaryWriter
在我们的 Epson 热敏收据打印机上填充必要的字节序列,该序列等于“进纸并剪切”命令(AsciiControlChars
只是一个带有常量的静态类):
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
// Reset the printer bws (NV images are not cleared)
bw.Write(AsciiControlChars.Escape);
bw.Write('@');
// Render the logo
RenderLogo(bw);
// Feed 3 vertical motion units and cut the paper with a 1 point cut
bw.Write(AsciiControlChars.GroupSeparator);
bw.Write('V');
bw.Write((byte)66);
bw.Write((byte)3);
bw.Flush();
return ms.ToArray();
}
然后,您可以直接将字节作为 RAW 文档发送到打印机,或者使用文章末尾的代码,它适用于各种 Win32 打印机功能,或者使用 Microsoft 的RawPrinterHelper 类。
您需要查找特定于您的打印机的命令。很可能它与您在这里看到的没有太大区别:POS 语言开始标准化,但这也就像说 SQL 是一种标准——人类可以相互理解,但如果不进行一些调整就不能真正实现互操作。
如果您仍然想使用 GDI,您可以以通常的方式将 GDI 文档打印到打印机(再次假设存在 GDI 打印机驱动程序,它可能确实存在),然后发出第二个小的 RAW 文档到包含本机进纸和剪切命令的打印机。(或者,一些 GDI 打印机驱动程序允许您在打印机控制面板中指定“打印文档后始终剪切”——但祝您以编程方式以有据可查的方式访问该驱动程序功能!)
希望这有助于描绘 GDI 与 POS 打印机的关系。