PDF打印机仅在未设置输出文件名时生成PDF

时间:2017-05-22 14:46:36

标签: c++ winapi printing pdf-generation postscript

以下代码段将PostScript内容(保存在pBuf缓冲区中)发送到CutePDF打印机:

if (OpenPrinter(printerName, &hPrinter, NULL))
{
  DOC_INFO_1 di1;
  di1.pDatatype = L"RAW";
  di1.pDocName = L"Raw print document";
  di1.pOutputFile = NULL;
  StartDocPrinter(hPrinter, 1, (LPBYTE)&di1);
  StartPagePrinter(hPrinter);   
  DWORD dwWritten = 0;
  WritePrinter(hPrinter, pBuf, dwBufSize, &dwWritten);
  EndPagePrinter(hPrinter);
  EndDocPrinter(hPrinter);
}

在执行此代码期间,会出现一个对话框,指定输出文件的名称(例如D:/out.pdf),然后生成pdf文件。到现在为止还挺好。当我试图通过更改代码段的第4行来避免文件名指定步骤时,问题就开始了:

di1.pOutputFile = L"D:/out.pdf";

此类代码在执行期间(如预期)不显示对话框,但结果D:/out.pdf不是pdf文件,它是发送到打印机的PostScript文件的副本(内容副本) pBuf缓冲区)。 PDF Writer的行为方式相同。为什么PDF打印机会以这种方式运行?如何实现所需的行为(生成PDF文件而不在UI中指定其名称)?

1 个答案:

答案 0 :(得分:1)

Windows打印系统以这种方式运行,因为,直言不讳,它应该如何表现。如果在该点指定文件名,则打印系统将输出发送到该文件。如果您没有指定文件名,那么它将继续进行正常处理。

通常您会将打印机驱动程序输出发送到端口,对于PDF打印机,自定义端口监视器会拾取输出(本例中为PostScript)并进一步处理。对于PDF打印机,他们将PostScript发送到将PostScript转换为PDF的过程(几乎总是使用Ghostscript,尽管Adobe打印到PDF工具的工作方式相同)。

如果要更改PDF进程的输出(即将其写入其他文件),则需要更改端口监视器的工作方式,而不是打印子系统的工作方式,这是您的代码目前正在做的事情。通过设置文件名,您只需将进程短路,从不调用端口监视器,这就是“保存文件”的原因。对话框没有出现,为什么输出是PostScript。

可能有一种方法可以为您正在使用的特定PDF打印机指定记录的输出文件。如果没有,那么对于开源产品(如果内置GS,它们应该是GPL许可),您可以请求产品的源代码副本并更改它以适合您自己。

或者,您可以获取Ghostscript和RedMon(开源端口监视器)的副本,并创建自己的工具来执行相同的工作。