Can I use PDFTron PDFNet SDK as a 'virtual PDF printer'?

Q: We asked you before about the concept of 'virtual printer' in
PDFTron PDFNet SDK.
You mentioned previously that using PDFNet SDK we should be able to
implement something like virtual PDF printer but via a class. What is
the status of this issue? Do you have any examples of working with
this?
------
A: The current version of PDFNet SDK (http://www.pdftron.com/pdfnet/
downloads.html) comes with two utility classes PDFDC and PDFDCEX.
These classes can be used to create a PDF Device Context which could
be used to print to PDF from any Windows application. This is
essentially the same as creating a printer DC (e.g. using ::CreateDC)
and sending drawing commands to the printer. The advantage of using
PDFDC / PDFDCEX is that it does not require installation of an actual
printer driver. PDFDC is based on the GDI print path (available on all
Windows versions), whereas PDFDCEX is based on XPS print path (which
is available in Vista, Windows7 - and on XP assuming that .NET 3+ or
Widows Essential Pack is installed). The use of PDFDC and PDFDCEX is
illustrated in PDFDC sample project: http://www.pdftron.com/pdfnet/samplecode.html#PDFDC.

Besides printing to a printer DC directly from your application, PDFDC
and PDFDCEX can be used to implement your own virtual printer drivers
(based on GDI or XPS print path). To speed up development of custom
printer drivers, PDFTron will offer full code for a GDI and XPS driver
(under NDA).

Q: It seems that we need to many changes in our code in order to use
PDFDC/PDFDCEX classes,

Currently we are using an outer driver and "print" to it using MFC
interface and we don't need to know start and end pages.
About your other suggestion of using "PDFTron desktop printers". Will
we need to do changes to our code in order to use it?
-----------
A: You should be able to use PDFDCEX without any significant changes
to your code. MFC would call StartPage/EndPage for you so you only
need to create PDFDCEX and pass the resulting printer DC to MFC.

In case you would rather use a stand-alone virtaul PDF printer, you
can download the driver demo using the following link(s):

32-bit: http://www.pdftron.com/downloads/PDFTronCreator32.exe
64-bit: http://www.pdftron.com/downloads/PDFTronCreator64.exe

Since this is a stand-alone printer driver, you would not need to make
any changes to your application.

Q: I the example you published in http://www.pdftron.com/pdfnet/samplecode.html#PDFDC
it looks like that you expect that we need to run ::StartPage
and ::EndPage functions for every page as following:

hDC2 = pdfDcEx.Begin( pdfdoc2 );
::StartPage(hDC2);
.
.
.
::EndPage
(hDC2); ////////////////////////////////////////////////////////////////////////////
// Page two
// Reuse existing font and DC.
::StartPage(hDC2);
.
.
.
::EndPage(hDC2);
// Complete the translation
pdfDcEx.End();
-------------
A: PDFDC ( http://www.pdftron.com/pdfnet/samplecode.html#PDFDC ) is a
Win32 sample. In case of MFC, ::StartPage and ::EndPage should be
automatically called before and after invocation of your OnPrint()
method (i.e. there is no need to explicitly call these functions in
your code). If you put a breakpoint in your OnPrint() method you
should be able to step through MFC code to better understand MFC print
process.

Q: I downloaded the trial version and replaced the original code as
following:

OLD code - //HDC hDC = ::CreateDC( _T( "WINSPOOL" ), PDF_DRIVER_NAME,
NULL, NULL );
NEW code - HDC hDC = CCreateAPI::GetInstance().GetDeviceContext();
The only thing that CCreateAPI::GetInstance().GetDeviceContext() is :
return m_pdfDcEx.Begin(m_pdfdoc);

This is the only change I added to the code, when running I'm getting
the following error:
after StartDoc function; "Could not start print job"
------------
A: What is the operating system you are using? If you are running XP
you would need to install Windows XPS Essential Pack (http://
www.microsoft.com/downloads/details.aspx?FamilyId=B8DCFFDD-E3A5-44CC-8021-7649FD37FFEE),
.NET 3 or above, or XPS Driver Redistributable (in case you don't want
that your application has any external dependencies). Windows 7 and
Vista come with a built-in XPS driver so there is no need to install
any additional components.

Q: Now I don’t get “Could not start print job” any more, and the pdf
file is been created but without pages, therefore cannot be opened.
What I’m doing is: in beginning get dc from PDFDCEX with the command:
m_pdfDcEx.Begin(m_pdfdoc);
and at end of the original code I add the code:

m_pdfDcEx.End();
m_pdfdoc.Save(outfile, SDF::SDFDoc::e_remove_unused, NULL);


A: Based on the provided code snippets it is hard to say what your
application is doing and what is the desired behavior. Do you let the
user to manually select the printer? Where does DOCINFO structure
resides? It would be very useful if you could provide full sample code
(or modification to the existing PDFView MFC sample or to some other
MFC sample).

We were able to get print output by extending PDFView MFC sample
project. Attached are relevant changes to the original PDFView MFC
sample project. Besides using PDFDCEX another, possibly simpler way to
implement ‘print to PDF’ (without need for a custom printer driver)
would be to print using ‘Microsoft XPS printer driver’ (which is
standard component of Vista, Windows 7, and is available as a
redistibutable for XP):

void UILessXPSGeneration(const char* fileName)
{
HDC hDC = CreateDC(NULL, L"Microsoft XPS Document Writer", NULL,
NULL);
DOCINFO docinfo;
memset(&docinfo, 0, sizeof(docinfo));
docinfo.cbSize = sizeof(docinfo);
docinfo.lpszOutput = fileName;
int result = StartDoc(hDC, & docinfo);
result = StartPage(hDC);
const char* message = L"My XPS";
result = TextOut(hDC, 100, 100, message, (int) strlen(message));
result = EndPage(hDC);
result = EndDoc(hDC);
}

then use PDFNet pdftron::PDF::Convert::FromXps(doc, “my.xps”) or
XPSConvert (http://www.pdftron.com/xpsconvert) to convert XPS to PDF.