Tutorial 10: Print Previewing
In the previous tutorial we saw how we can send output to a printer. In
this tutorial we will show how to preview the printed page before sending it
to the printer.
Many application that support printing also support print previewing. A
print preview provides users with an opportunity to see how output will
before it is printed, and make any necessary adjustments.
Declaring the CPrintPreview class member
CPrintPreview works by using the same function that prints a page. The
function used to print a page is called PrintPage, and is declared as
follows.void PrintPage(CDC& dc, int page = 1);
When we declare a CPrintPreview variable, we specify the source of the
PrintPage function as the template parameter. In the following code,
PrintPage is a member function of CView, so we specify CView as the template
parameter.
CPrintPreview m_preview<CView>;
We also need to specify the view in m_preview's constructor. We can do
that by adding m_preview to CMainFrame's member initializer list as follows.
CMainFrame::CMainFrame() : m_preview(m_richView) {}
Initiating the Print Preview
When we use CPrintPreview, we use SetSource to specify the source of the
PrintPage function. We then use DoPrintPreview to specify the owner window
to recieve messages from CPrintPreview and create the preview.
The following code shows how we can display the print preview in the
frame's view. We use SetView to change the frame's view to the CPrintPreview
variable.
// Previews a print job before sending it to the printer.
void CMainFrame::OnFilePreview()
{
try
{
// Get the device contect of the default or currently chosen printer.
CPrintDialog printDlg;
CDC printerDC = printDlg.GetPrinterDC();
// Create the preview window if required.
if (!m_preview.IsWindow())
m_preview.Create(*this);
// Set the preview's owner (for messages).
m_preview.DoPrintPreview(*this);
// Swap views.
SetView(m_preview);
// Hide the menu and toolbar.
ShowMenu(FALSE);
ShowToolBar(FALSE);
// Update status.
CString status = _T("Printer: ") + printDlg.GetDeviceName();
SetStatusText(status);
}
catch (const CException& e)
{
// An exception occurred. Display the relevant information.
MessageBox(e.GetText(), _T("Print Preview Failed"), MB_ICONWARNING);
SetView(m_view);
ShowMenu(GetFrameMenu() != 0);
ShowToolBar(GetToolBar().GetButtonCount() > 0);
}
}
Handling Messages from CPrintPreview
The
CPrintPreview class sends the following messages to its owner window.
- UWM_PREVIEWCLOSE - sent when CPrintPreview's 'Close' button is
pressed.
- UWN_PREVIEWNOW - sent when CPrintPreview's 'Print Now' button
is pressed.
- UWM_PREVIEWSETUP - sent when CPrintPreview's 'Print Setup button
is pressed.
We handle these messages in the owner window's window procedure, as
follows.
// Handle the frame's messages.
LRESULT CMainFrame::WndProc(UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case UWM_PREVIEWCLOSE: OnPreviewClose(); break;
case UWM_PREVIEWNOW: OnPreviewPrint(); break;
case UWM_PREVIEWSETUP: OnPreviewSetup(); break;
}
return WndProcDefault(msg, wparam, lparam);
}
In the following code, we respond to the UWM_PREVIEWSETUP message by
displaying a dialog that allows the user to select printing options such as
the paper size. Once the user has made a selection we call DoPrintPreview to
display the page with the new options.
// Called when the Print Preview's "Print Setup" button is pressed.
void CMainFrame::OnPreviewSetup()
{
// Call the print setup dialog.
CPrintDialog printDlg(PD_PRINTSETUP);
try
{
// Display the print dialog.
if (printDlg.DoModal(*this) == IDOK)
{
CString status = _T("Printer: ") + printDlg.GetDeviceName();
SetStatusText(status);
}
}
catch (const CException& e)
{
// An exception occurred. Display the relevant information.
MessageBox(e.GetErrorString(), e.GetText(), MB_ICONWARNING);
}
// Initiate the print preview.
m_preview.DoPrintPreview(*this);
}
In the following code, we respond to the UWM_PREVIEWNOW message by
sending the page(s) to the printer without initiating a dialog.
// Called when the Print Preview's "Print Now" button is pressed.
void CMainFrame::OnPreviewPrint()
{
m_view.QuickPrint(_T("Frame Sample"));
}
In the following code, we respond to the UWM_PREVIEWCLOSE message by
returning the frame's view to normal. There is no need to destroy the
CPrintPreview window, as it is hidden when we use SetView to select m_view
as the frame's view.
// Called when the Print Preview's "Close" button is pressed.
void CMainFrame::OnPreviewClose()
{
// Swap the view.
SetView(m_view);
// Show the menu and toolbar.
ShowMenu(GetFrameMenu() != 0);
ShowToolBar(GetToolBar().IsWindow());
SetStatusText(LoadString(IDW_READY));
}
The source code for this tutorial is located within the Tutorial folder
of the software available from SourceForge at
http://sourceforge.net/projects/win32-framework.