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, and PrintPageHeader, which prints a header on the drawing page.

To modify OnPreparePrinting

  • Use WizardBar to jump to the OnPreparePrinting function definition of class CScribbleView, 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

  1. Use WizardBar to open ScribbleView.cpp in the text editor.

  2. Click the arrow on the action button, located on the right end of WizardBar.

  3. On the menu, Click Add Virtual Function.

    The New Virtual Override dialog box appears.

  4. From the New Virtual Functions list, select OnPrint.

  5. Click Add and Edit.

  6. 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.