Windows:如何告诉打印机在打印过程中发出 FormFeed? [英] Windows: How to tell printer to issue a FormFeed during printing?

查看:57
本文介绍了Windows:如何告诉打印机在打印过程中发出 FormFeed?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要告诉打印机驱动程序发出换页.

我正在使用以下工具直接打印到打印机:

解决方案

是的,那行不通.您故意绕过打印机驱动程序,这是一段代码,为任何打印机提供通用接口.这让您需要处理每种特定打印机型号的特性.

有一些通用接口,您在代码中使用的接口是旧点阵打印机使用的接口.PCL 在 Hewlett Packard 激光打印机上很常见.Postscript 在高端打印机上很常见.后两者有自己的咒语来获取表单.

然后是廉价的激光和喷墨打印机的海洋.它们通常根本没有定义明确的接口.打印机内部没有处理器将打印机命令转换为纸上的点,而是让打印机驱动程序完成所有繁重的工作.你永远不会得到其中一个,界面是专有的,没有记录.

打印机驱动程序是您的朋友.PrintDocument 类来使用它.获取表单很容易,只需设置 e.HasMorePages = true 并退出PrintPage 事件处理程序.您已经看到了我链接的 StreamPrinter 类.

i need to tell a printer driver to issue a form feed.

i'm printing directly to a printer using the:

set of API calls.

A lot of the inspiration came from KB138594 - HOWTO: Send Raw Data to a Printer by Using the Win32 API. An important point to note in that KB article is that they (and my copied code) start the document in RAW mode:

// Fill in the structure with info about this "document."
docInfo.pDocName = "My Document";
docInfo.pOutputFile = NULL;
docInfo.pDatatype = "RAW";
StartDocPrinter(hPrinter, 1, docInfo);

Note: RAW mode (as opposed to TEXT mode) means we are issuing raw bytes to the printer driver. We promise to talk in the language it understands.

We can then use WritePrinter to write everything we want:

WritePrinter(hPrinter, "Hello, world!"); //note, extra parameters removed for clarity
WritePrinter(hPrinter, 0x0c); //form-feed

The problem here is the 0x0c form-feed character. Because we've opened the printer in RAW mode, we are promising we will send the printer driver bytes it can process. The drivers of most printers take 0x0C to mean you want to issue a form-feed.

The problem is that other printers (PDF printer, Microsoft XPS Printers) expect RAW print jobs to be in their own printer language. If you use the above to print to an XPS or PDF printer: nothing happens (i.e. no save dialog, nothing printed).

i asked for a solution to this question a while ago, and a response was that you have to change the document mode from RAW:

docInfo.pDatatype = "RAW";

to TEXT:

docInfo.pDataType = "TEXT";

Well this probably is because you send "RAW" data directly to the printer, and RAW can be any PDL. But the XPS driver will probably only understands XPS, and it will probably just ignore your "unknown: Hello, world!0xFF" PDL. The XPS driver will probably, if any, only accept XPS data when you write directly to it.

If you want to render text on the XPS driver, you should use GDI. You might be able to send plain text to the driver if you specify "TEXT" as the datatype. The print processor attached to the driver will then "convert" the plaintext for you by rendering the job via GDI to the driver.

So that worked, i changed my code to declare the print document as TEXT:

// Fill in the structure with info about this "document."
docInfo.pDocName = "My Document";
docInfo.pOutputFile = NULL;
docInfo.pDatatype = "TEXT";
StartDocPrinter(hPrinter, 1, docInfo);
WritePrinter(hPrinter, "Hello, world!");
WritePrinter(hPrinter, 0x0c); //form-feed

And then the Save As dialog for XPS and PDF printers appear, and it saves correctly. And i thought all was fixed.

Except months later, when i tried to print to a <quote>real</quote> printer: the form-feed doesn't happen - presumably because i am no longer printing in "raw printer commands" mode.

So what i need is the Windows-ish way of issuing a form feed. i need the API call that will tell printer driver that i want the printer to perform a form-feed.

My question: How to tell a printer to issue a Form-Feed during printing?


Background on Data Types

The print processor tells the spooler to alter a job according to the document data type. It works in conjunction with the printer driver to send the spooled print jobs from the hard drive to the printer.

Software vendors occasionally develop their own print processors to support custom data types. Normally, the print processor does not require any settings or intervention from administrators.

Data types

The Windows printing process normally supports five data types. The two most commonly used data types, enhanced metafile (EMF) and ready to print (RAW), affect performance in different ways on both the client computer and the print server computer.

RAW is the default data type for clients other than Windows-based programs. The RAW data type tells the spooler not to alter the print job at all prior to printing. With this data type, the entire process of preparing the print job is done on the client computer.

EMF, or enhanced metafile, is the default datatype with most Windows-based programs. With EMF, the printed document is altered into a metafile format that is more portable than RAW files and usually can be printed on any printer. EMF files tend to be smaller than RAW files that contain the same print job. Regarding performance, only the first portion of a print job is altered, or rendered on the client computer, but most of the impact is on the print server computer, which also helps the application on the client computer to return control to the user faster.

The following table (taken from MSDN) shows the five different data types supported by the default Windows print processor:

Data type: RAW
Directions to spooler: Print the document with no changes.
Use: This is the data type for all clients not based on Windows.

Data type: RAW [FF appended]
Directions to spooler: Append a form-feed character (0x0C), but make no other changes. (A PCL printer omits the document's last page if there is no trailing form-feed.)
Use: Required for some applications. Windows does not assign it, but it can be set as the default in the Print Processor dialog box.

Data type: RAW [FF auto]
Directions to spooler: Check for a trailing form-feed and add one if it is not already there, but make no other changes.
Use: Required for some applications. Windows does not assign it, but it can be set as the default in the Print Processor dialog box.

Data type: NT EMF 1.00x
Directions to spooler: Treat the document as an enhanced metafile (EMF) rather than the RAW data that the printer driver puts out.
Use: EMF documents are created by Windows.

Data type: TEXT
Directions to spooler: Treat the entire job as ANSI text and add print specifications using the print device's factory defaults. Use: This is useful when the print job is simple text and the target print device cannot interpret simple text.

You can see the print processors available for a printer, and the data types that each processor supports, through the properties of a printer in the control panel:

See also

解决方案

Yeah, that doesn't work. You are intentionally bypassing the printer driver, the chunk of code that presents a universal interface to any printer. Which leaves you to deal with the peculiarities of each specific printer model.

There are some common interfaces, the one you used in your code is the one that dot matrix printers of old used. PCL is common on Hewlett Packard laser printers. Postscript is common on high-end printers. The latter two have their own incantations to get a form feed.

Then there's the ocean of cheap laser and ink jet printers. They often don't have a well defined interface at all. Instead of having a processor inside the printer that translates printer commands to dots on paper, they let the printer driver do all the hard work. You'll never get one of those going, the interface is proprietary and undocumented.

The printer driver is your friend here. PrintDocument the class to use it. Getting a form feed is easy, just set e.HasMorePages = true and exit the PrintPage event handler. You already saw the StreamPrinter class I linked.

这篇关于Windows:如何告诉打印机在打印过程中发出 FormFeed?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆