Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

2,836 views
Skip to first unread message

Richard Guion

unread,
Dec 1, 2003, 11:48:41 PM12/1/03
to
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");


Aandi Inston

unread,
Dec 2, 2003, 2:33:44 AM12/2/03
to
"Richard Guion" <richardguion@NOSPAM_NOSPAM_hotmail.com> wrote:
>
>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 Inston qu...@dial.pipex.com http://www.quite.com
Please support usenet! Post replies and follow-ups, don't e-mail them.

Richard Guion

unread,
Dec 2, 2003, 10:08:43 PM12/2/03
to
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

"Aandi Inston" <qu...@dial.pipex.con> wrote in message
news:3fcc3f94....@reading.news.pipex.net...

Aandi Inston

unread,
Dec 3, 2003, 4:26:27 AM12/3/03
to
"Richard Guion" <richardguion@NOSPAM_NOSPAM_hotmail.com> wrote to
entirely too many groups:

>The only kicker is that I need to handle the pagination, thru
>StartPage/EndPage calls.

Your best bet may be to write a PostScript prologue that defines the
necessary operations. If by "Pagination" you mean "imposition" you
may have too optimistic a view of what you can do with
BeginPage/EndPage. It cannot change the rendering sequence.



> I also need
>to handle margin settings, etc., all as the .PS file gets generated.

Yep, that's entirely up to you. When you call TextOut, or whatever,
you have to choose the location to start the text. That's where the
margins come from - there's nothing automatic in the printer (so far
as I can see).

Hmmm. On the other hand, I seem to recall that the GDI origin is the
top left of the printable area, i.e. inside some minimal margins (not
usually consistent with good practice). If that's the case, you can
query the printer DC to find out what the printer's unprintable
boundary is, and add that to the margin you actually want.

0 new messages