Adding Pagination
Scribble is a fairly simple application, so it supports drawings of only one size, and each one fits on a single page. To illustrate pagination, Step 5 of Scribble prints each drawing as a two-page document: a title page, and the drawing itself.
To add pagination, you’ll:
Modify the OnPreparePrinting member function.
Override the default OnPrint member function.
Add two new helper functions:
PrintTitlePage
, which prints the title page, andPrintPageHeader
, which prints a header on the drawing page.
To modify OnPreparePrinting
Use WizardBar to jump to the
OnPreparePrinting
function definition of classCScribbleView
, and replace the existing comment and code with the following code:pInfo->SetMaxPage(2); // the document is two pages long: // the first page is the title page // the second page is the drawing
This function specifies the length of the document by calling SetMaxPage for the pInfo parameter. Since all Scribble documents are two pages long, the function uses a numeric constant rather than a variable to represent the number of the last page of the document. The title page and the drawing page are numbered 1 and 2, respectively. Later, you’ll add a Scribble-specific version of the call to DoPreparePrinting that AppWizard generated (which you just replaced), when you enhance Scribble’s Print Preview. This function displays the Print dialog box and creates a device context for the printer.
To override OnPrint
Use WizardBar to open ScribbleView.cpp in the text editor.
Click the arrow on the action button, located on the right end of WizardBar.
On the menu, Click Add Virtual Function.
The New Virtual Override dialog box appears.
From the New Virtual Functions list, select
OnPrint
.Click Add and Edit.
Replace the //TODO comments and existing code with the following code:
if (pInfo->m_nCurPage == 1) // page no. 1 is the title page { PrintTitlePage(pDC, pInfo); } else { CString strHeader = GetDocument()->GetTitle(); PrintPageHeader(pDC, pInfo, strHeader); // PrintPageHeader() subtracts out from the pInfo->m_rectDraw the // amount of the page used for the header. pDC->SetWindowOrg(pInfo->m_rectDraw.left,-pInfo->m_rectDraw.top); // Now print the rest of the page OnDraw(pDC); } return;
The behavior of the OnPrint
member function depends on which of the two pages is being printed. If the title page is being printed, OnPrint
simply calls the PrintTitlePage
function and then returns. If it’s the drawing page, OnPrint
calls PrintPageHeader
to print the header and then calls OnDraw
to do the actual drawing. Before calling OnDraw
, OnPrint
sets the window origin at the upper-left corner of the rectangle defined by m_rectDraw; this rectangle was reduced by PrintPageHeader
to account for the size of the header. This keeps the drawing from overlapping the header.
Notice that the drawing itself isn’t divided into multiple pages. Consequently, OnDraw
never has to display just a portion of the drawing (for example, it never has to display the section that fits on a particular page without displaying the surrounding sections). Either the title page is being printed and OnDraw
isn’t called at all, or else the drawing page is being printed and OnDraw
displays the entire drawing at once.
This also explains why CScribbleView
doesn’t override the OnPrepareDC member function: there’s no need to adjust the viewport origin or clipping region depending on which page is being printed.