CView::OnDraw has a second very important purpose in MFC besides housing your painting code. The framework implements both printing and print preview using your view's OnDraw function. The basic idea is that in MFC you simply draw to the current device — sometimes it's the display, sometimes it's a printer, and sometimes it's a printer emulation on the display (print preview).
Because of this, the File Print command is mapped to class CView, which does all of the necessary setup work and then calls OnDraw to render the image using the device context object passed to it. For drawing on the display, the CDC pointer passed is for the display. For drawing on a printer, the CDC is for the current printer. And for drawing a scaled image in a print preview window, the CDC that is passed wraps two device contexts. One represents the display; the other represents the printer. Using both device contexts, drawing output in OnDraw emulates printer output in the print preview window to approximate the output you could expect to see on the printer.
When you move your printing code into OnDraw, you get to abandon much of it. MFC takes care of displaying File Print and File Print Setup dialog boxes. It also manages the print loop in large measure. Most of what you keep is the actual GDI code that renders the image on the printer.
As shown in Figure 12, when it's time to print a page, MFC calls your view's OnPrepareDC and OnPrint member functions, passing the number of the page to print (page counts start at 1). OnPrepareDC makes adjustments to the device context before drawing takes place. OnPrint calls OnDraw, passing along its device context pointer, and OnDraw draws the current page. For simple printing, all of this takes place with no intervention from you. But if you are doing multiple-page printing, printing headers and/or footers, and the like, you'll need to override OnPrepareDC and/or OnPrint.
If you need to make your own adjustments to the device context before printing a page, override OnPrepareDC in your view class. You might, for instance, move the viewport origin and the clipping region to ensure that the appropriate portion of the document gets printed. For multiple-page documents, this is how you set up to print specified pages, placing the viewport origin at the calculated upper left corner of the page within your document.
Override OnPrint to perform any rendering that should be done only during printing and not for screen display. For example, you can draw headers and footers in OnPrint before (and after) OnDraw renders the rest of the page.
If your application is not WYSIWYG ("What you see is what you get") — that is, if what you print differs significantly from what you display on the screen — you can separate the print-only logic from the display logic in OnDraw, perhaps like this:
... if (IsPrinting) // another CView member function { // Do print-only drawing } else // Do display drawing }
Or you can do all of your print-only drawing in your OnPrint override without calling OnDraw from there. In this way, OnDraw is called only for screen display, while OnPrint is called only for printing and print preview.
SHOWDIB's printing logic (not shown in this guide or the samples) is necessarily separate from its screen display logic, so you would avoid calling OnDraw from OnPrint. This is because you display a bitmap on screen all at once, but you print it in "bands" or strips. Screen display is handled in OnDraw, while printing is handled in OnPrint. This is the exceptional case in which the two processes cannot be independent of the device being used. Fortunately, a fair amount of the printing code (involving dialog boxes and some parts of the printing loop) disappears under MFC due to all of the things the framework does for you.