2
votes

I have a large graphics program using C++, MFC, and C++6.0. I need it to print to PDFs without prompting the user for printer settings and file name.

I use CView::OnPrint() to print using Microsoft Print-to-PDF and it works fine except for the user prompts.

I've seen how to bypass those prompts with a PrintDocument object in C# but how can I do that when using CView::OnPrint() in MFC? Surely there must be a way?

My project is much too big to consider re-writing in C#, and I've tried moving forward to Visual studio 2005/2010/2019 etc. without success as changes in default data structure packing and converting existing data files is fraught with problems so solution has to be an addition to existing MFC C++6.0 if at all possible.

Can anybody help?

1
This is why I prefer not to use MFC and instead use wxWidgets.Thomas Matthews

1 Answers

3
votes

I haven't used VC++ 6 in quite a while now, so I'm going from rather distant memories, but the general idea is fairly simple.

Full Approach

Your view has a DoPreparePrinting member function. By default, this creates a CPrintDialog object, then invokes the CPrintDialog's DoModal to show the print settings dialog. Eventually (but not in DoPreparePrinting, if memory serves) that CPrinterDialog's CreatePrinterDC will be called to (obviously enough) create a DC for the printer using the settings the user entered in the dialog.

To bypass the dialog, you can override DoPreparePrinting. That receives a pointer to a CPrintDialog. Since you don't want to show a print dialog, you obviously won't invoke its DoModal member. Instead, you'll fill in its DEVMODE and DEVNAMES structures for the printer and any settings you want. Then when CreatePrinterDC gets called, it'll use what you filled in without displaying the dialog.

My personal advice would be to do a run using the dialog under the debugger, then after the CPrintDialog's DoModal has returned, look through the DEVNAMES structure it returned. You may not need it, but I found the DEVNAMES structure a little confusing the first time I had to set it up on my own. The DEVMODE is bigger and arguably more complex, but I've usually just modified a few bits and pieces, and left most of it with default values.

Simplified Approach

If you just want to use the system's default print settings, there's a simpler approach: you can override OnPreparePrinting. This receives a pInfo parameter, which is a pointer to a CPrintInfo. That has an m_bDirect member, which you can set to true to do "direct" printing, which just uses the default settings without using a printer dialog. I don't remember for sure when m_bDirect was added though. If it's missing, there's a "trick" to get the same effect: the default implementation of DoPreparePrinting doesn't display a print dialog for a print preview, so you override OnPreparePrinting to set m_bPreview to true, invoke DoPreparePrinting, then set m_bPreview back to false.