How to Print to a PDF File using printer driver in C++

  • Thread starter Thread starter Richard Guion
  • Start date Start date
R

Richard Guion

I have an MFC Win32 client application that needs to generate PDF
files. The easiest way to do it is to have our customers purchase and
install Adobe Acrobat, and then our program will use the "Adobe PDF" printer
driver to output our text to PDF files.

From any application like Notepad, Word, Excel, using the Adobe PDF writer
works fine when I do File\Print, click "Print to File", uncheck the printer
property of downloading fonts to printer--my PDF file is created fine.

I need to do this from C++. The user is not going to use File\Print in our
app, we need to convert files as we chug online in certain operations.

Something is not working in my code which I've pasted below. I'm using
OpenPrinter
to open the "Adobe PDF" printer (return code is good), I call
StartDocPrinter setting
my output file name to "D:\temp\test.pdf" and set the datatype either to RAW
or NULL,
same result occurs: a test.pdf file is created, but it is pure text "this is
a test"
instead of PDF content.

Anyone see what I am doing wrong? It appears to me that I need another code
for
pDatatype. Or should I not be using these OS calls for a printer driver?
=========================
#include <winspool.h>
....
BOOL PrintStringDirect( LPCSTR Str, LPTSTR PrinterName, LPSTR DeviceName )
{
BOOL bRet = FALSE;
HANDLE hPrinter;

if ( OpenPrinter( PrinterName, &hPrinter, NULL ) )
{
DOC_INFO_1 doc_info = {0};

doc_info.pDocName = "Test Document";
doc_info.pOutputFile = DeviceName;
//doc_info.pDatatype = (LPTSTR) NULL;
doc_info.pDatatype = "raw";

DWORD jobid = StartDocPrinter( hPrinter, 1, (LPBYTE)&doc_info );

if ( jobid != 0 )
{
DWORD written;
DWORD dwNumBytes = lstrlen( Str );

WritePrinter( hPrinter, (void*) Str,
dwNumBytes, &written );

if ( written == dwNumBytes )
bRet = TRUE;
}

EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
}

return bRet;
}


PrintStringDirect("This is a test", "Adobe PDF", "D:\\temp\\test.pdf");
 
Richard Guion said:
Something is not working in my code which I've pasted below. I'm using
OpenPrinter
to open the "Adobe PDF" printer (return code is good), I call
StartDocPrinter setting
my output file name to "D:\temp\test.pdf" and set the datatype either to RAW
or NULL,
same result occurs: a test.pdf file is created, but it is pure text "this is
a test"
instead of PDF content.

1. General problem with use of the printer API - you are using
WritePrinter. That is defined to send exactly what you pass direct to
the printer, hence your result. That is only used if you have a string
already in printer language. To print you must render to the printer
DC just as you would render to the screen DC. In other words you use
calls such as TextOut. Familiarity with the GDI part of the Windows
SDK is a must (or use some other classes or libraries equivalent).

2. Specific problem with the Adobe PDF printer. If you had used GDI
correctly you would not get a PDF file. You would get a PostScript
file, because this method always bypasses the "PDF port" which creates
the PDF. To get over this you must use the Distiller API, in the
Acrobat SDK, to convert the PostScript file to PDF, and recreate what
happens automatically on a manual print operation.
 
Aandi,

Thank you very much for your advice. I tried what you described and now I
can generate both
postscript and PDF files.

The only kicker is that I need to handle the pagination, thru
StartPage/EndPage calls. I also need
to handle margin settings, etc., all as the .PS file gets generated.
Whereas if you print a text file
thru Notepad, select "Adobe PDF" driver, it handles all that for you.

Cheers,
// Richard
 
Back
Top