Introduction
If you have a dialog based application and want to print, then you cannot take advantage of the Doc/View framework that MFC provides to do all the dirty work for you.
The code presented below demonstrates the typical steps needed to:
- prompt the user for the printing characteristics such as printer and paper
size (via a call to
CPrintDialog::DoModal)
- Setup a printer DC and printing DOCINFO structure
- Use callbacks to adjust settings such as start and end pages to print, or
printing sizes
- Print all pages to be printed
- Cleanup
The callbacks
In order to keep the MFC Doc/View feel I recomend providing helper callback functions OnBeginPrinting
, OnEndPrinting
and OnPrint
similar to the CView versions. A CDC
and a CPrintInfo
object is passed into each of these functions. You will have to provide these functions yourself. Typically you would undertake any initialisation neessary (such as creating GDI objects) in OnBeginPrinting
. Your OnPrint
function would be where you do the actual printing/drawing, and your OnEndPrinting
function performs any cleanup necessary (such as deleting GDI objects created in OnBeginPrinting
). You can call these functions whatever you want - I've used these names to be consistant with the CView names, and they are only used to show where the various initialisation/printing/cleanup code should be inserted by you.
Typical
implementations would look like:
void OnBeginPrinting(CDC *pDC, CPrintInfo* pInfo)
{
}
void OnPrint(CDC *pDC, CPrintInfo* pInfo)
{
}
void OnEndPrinting(CDC *pDC, CPrintInfo* pInfo)
{
}
The Printing code
void CMyDialog::Print()
{
CDC dc;
CPrintDialog printDlg(FALSE);
if (printDlg.DoModal() == IDCANCEL)
return;
dc.Attach(printDlg.GetPrinterDC());
dc.m_bPrinting = TRUE;
CString strTitle;
strTitle.LoadString(AFX_IDS_APP_TITLE);
DOCINFO di;
::ZeroMemory (&di, sizeof (DOCINFO));
di.cbSize = sizeof (DOCINFO);
di.lpszDocName = strTitle;
BOOL bPrintingOK = dc.StartDoc(&di);
CPrintInfo Info;
Info.m_rectDraw.SetRect(0,0,
dc.GetDeviceCaps(HORZRES),
dc.GetDeviceCaps(VERTRES));
OnBeginPrinting(&dc, &Info);
for (UINT page = Info.GetMinPage();
page <= Info.GetMaxPage() && bPrintingOK;
page++)
{
dc.StartPage();
Info.m_nCurPage = page;
OnPrint(&dc, &Info);
bPrintingOK = (dc.EndPage() > 0);
}
OnEndPrinting(&dc, &Info);
if (bPrintingOK)
dc.EndDoc();
else
dc.AbortDoc();
dc.DeleteDC();
}
Chris Maunder is the co-founder of
CodeProject, DeveloperMedia and ContentLab, and has been a prominent figure in the software development community for nearly 30 years. Hailing from Australia, Chris has a background in Mathematics, Astrophysics, Environmental Engineering and Defence Research. His programming endeavours span everything from FORTRAN on Super Computers, C++/MFC on Windows, through to to high-load .NET web applications and Python AI applications on everything from macOS to a Raspberry Pi. Chris is a full-stack developer who is as comfortable with SQL as he is with CSS.
In the late 1990s, he and his business partner David Cunningham recognized the need for a platform that would facilitate knowledge-sharing among developers, leading to the establishment of CodeProject.com in 1999. Chris's expertise in programming and his passion for fostering a collaborative environment have played a pivotal role in the success of CodeProject.com. Over the years, the website has grown into a vibrant community where programmers worldwide can connect, exchange ideas, and find solutions to coding challenges. Chris is a prolific contributor to the developer community through his articles and tutorials, and his latest passion project,
CodeProject.AI.
In addition to his work with CodeProject.com, Chris co-founded ContentLab and DeveloperMedia, two projects focussed on helping companies make their Software Projects a success. While at CodeProject, Chris' roles included Architecture and coding, Product Development, Content Creation, Community Growth, Client Satisfaction and Systems Automation, and many, many sales meetings. All while keeping his sense of humour.