PDF 打印机仅在未设置输出文件名时生成 PDF
PDF printer generates PDF only when output file name is not set
以下代码片段将 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 中指定其名称)?
Windows 打印系统以这种方式运行,因为,直白地说,这就是它应该运行的方式。如果您在此时指定文件名,则打印系统会将输出发送到该文件。如果您不指定文件名,那么它将继续进行正常处理。
通常您会将打印机驱动程序输出发送到端口,对于 PDF 打印机,自定义端口监视器会获取输出(在本例中为 PostScript)并进一步处理。对于 PDF 打印机,他们将 PostScript 发送到将 PostScript 转换为 PDF 的过程(几乎总是使用 Ghostscript,尽管 Adobe 打印到 PDF 工具的工作方式相同)。
如果您想改变 PDF 过程的输出(即将其写入不同的文件),那么您需要改变 端口监视器 的工作方式,而不是打印子系统的工作方式,这就是您的代码当前正在做的事情。通过在您所在的位置设置文件名,您只是使进程短路,从不调用端口监视器,这就是 'save file' 对话框不出现以及输出为 PostScript 的原因。
可能有一种方法可以指定为您正在使用的特定 PDF 打印机记录的输出文件。如果没有,那么对于开源产品(如果 GS 是内置的,它们应该获得 GPL 许可),您可以索取该产品的源代码副本并根据自己的需要进行修改。
或者,您可以获取一份 Ghostscript 和 RedMon(开源端口监视器)并创建您自己的工具来完成相同的工作。
以下代码片段将 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 中指定其名称)?
Windows 打印系统以这种方式运行,因为,直白地说,这就是它应该运行的方式。如果您在此时指定文件名,则打印系统会将输出发送到该文件。如果您不指定文件名,那么它将继续进行正常处理。
通常您会将打印机驱动程序输出发送到端口,对于 PDF 打印机,自定义端口监视器会获取输出(在本例中为 PostScript)并进一步处理。对于 PDF 打印机,他们将 PostScript 发送到将 PostScript 转换为 PDF 的过程(几乎总是使用 Ghostscript,尽管 Adobe 打印到 PDF 工具的工作方式相同)。
如果您想改变 PDF 过程的输出(即将其写入不同的文件),那么您需要改变 端口监视器 的工作方式,而不是打印子系统的工作方式,这就是您的代码当前正在做的事情。通过在您所在的位置设置文件名,您只是使进程短路,从不调用端口监视器,这就是 'save file' 对话框不出现以及输出为 PostScript 的原因。
可能有一种方法可以指定为您正在使用的特定 PDF 打印机记录的输出文件。如果没有,那么对于开源产品(如果 GS 是内置的,它们应该获得 GPL 许可),您可以索取该产品的源代码副本并根据自己的需要进行修改。
或者,您可以获取一份 Ghostscript 和 RedMon(开源端口监视器)并创建您自己的工具来完成相同的工作。