In this example, the document contains an array of 50 CRect objects that define circles. The circles are randomly positioned in a 6-by-6-inch area and have random diameters of as much as 0.5 inch. The circles, when drawn on the display, look like two-dimensional simulations of soap bubbles. Instead of drawing the circles on the printer, the application prints the corresponding CRect coordinates in numeric form, 12 to a page, with headers and footers. Here are the steps:
Run the MFC Application Wizard to generate a project named Ex17b. Select Single Document, and accept the defaults for all the other settings.
Edit the
#include <afxtempl.h>
Edit the
typedef CArray<CRect, CRect&> CRectArray;
Next, add the following public data members to the
public: enum { nLinesPerPage = 12 }; enum { nMaxEllipses = 50 }; CRectArray m_ellipseArray;
The two enumerations are object-oriented replacements for #defines.
Edit the
BOOL CEx17bDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; int n1, n2, n3; // Make 50 random circles srand((unsigned) time(NULL)); m_ellipseArray.SetSize(nMaxEllipses); for (int i = 0; i < nMaxEllipses; i++) { n1 = rand() * 600 / RAND_MAX; n2 = rand() * 600 / RAND_MAX; n3 = rand() * 50 / RAND_MAX; m_ellipseArray[i] = CRect(n1, -n2, n1 + n3, -(n2 + n3)); } return TRUE; } void CEx17bDoc::Serialize(CArchive& ar) { m_ellipseArray.Serialize(ar); }
Edit the
public: int m_nPage; private: void PrintPageHeader(CDC *pDC); void PrintPageFooter(CDC *pDC);
The m_nPage data member holds the document's current page number for printing. The private functions are for the header and footer subroutines.
Edit the OnDraw function in
void CEx17bView::OnDraw(CDC* pDC) { int i, j; CEx17bDoc* pDoc = GetDocument(); j = pDoc->m_ellipseArray.GetUpperBound(); for (i = 0; i < j; i++) { pDC->Ellipse(pDoc->m_ellipseArray[i]); } }
Insert the OnPrepareDC function in
void CEx17bView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { pDC->SetMapMode(MM_LOENGLISH); }
Insert the OnPrint function in
void CEx17bView::OnPrint(CDC* pDC, CPrintInfo* pInfo) { int i, nStart, nEnd, nHeight; CString str; CPoint point(720, -1440); CFont font; TEXTMETRIC tm; pDC->SetMapMode(MM_TWIPS); CEx17bDoc* pDoc = GetDocument(); m_nPage = pInfo->m_nCurPage; // for PrintPageFooter's benefit nStart = (m_nPage - 1) * CEx17bDoc::nLinesPerPage; nEnd = nStart + CEx17bDoc::nLinesPerPage; // 14-point fixed-pitch font font.CreateFont(-280, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_MODERN, "Courier New"); // Courier New is a TrueType font CFont* pOldFont = (CFont*) (pDC->SelectObject(&font)); PrintPageHeader(pDC); pDC->GetTextMetrics(&tm); nHeight = tm.tmHeight + tm.tmExternalLeading; for (i = nStart; i < nEnd; i++) { if (i > pDoc->m_ellipseArray.GetUpperBound()) { break; } str.Format("%6d %6d %6d %6d %6d", i + 1, pDoc->m_ellipseArray[i].left, pDoc->m_ellipseArray[i].top, pDoc->m_ellipseArray[i].right, pDoc->m_ellipseArray[i].bottom); point.y -= nHeight; pDC->TextOut(point.x, point.y, str); } PrintPageFooter(pDC); pDC->SelectObject(pOldFont); }
Edit the OnPreparePrinting function in
BOOL CEx17bView::OnPreparePrinting(CPrintInfo* pInfo) { CEx17bDoc* pDoc = GetDocument(); pInfo->SetMaxPage(pDoc->m_ellipseArray.GetUpperBound() / CEx17bDoc::nLinesPerPage + 1); return DoPreparePrinting(pInfo); }
Insert the page header and footer functions in
void CEx17bView::PrintPageHeader(CDC* pDC) { CString str; CPoint point(0, 0); pDC->TextOut(point.x, point.y, "Bubble Report"); point += CSize(720, -720); str.Format("%6.6s %6.6s %6.6s %6.6s %6.6s", "Index", "Left", "Top", "Right", "Bottom"); pDC->TextOut(point.x, point.y, str); } void CEx17bView::PrintPageFooter(CDC* pDC) { CString str; CPoint point(0, -14400); // Move 10 inches down CEx17bDoc* pDoc = GetDocument(); str.Format("Document %s", (LPCSTR) pDoc->GetTitle()); pDC->TextOut(point.x, point.y, str); str.Format("Page %d", m_nPage); CSize size = pDC->GetTextExtent(str); point.x += 11520 - size.cx; pDC->TextOut(point.x, point.y, str); // right-justified }
Build and test the application. For one set of random numbers, the bubble view window looks like this:
Each time you choose New from the File menu, you should see a different picture. In Print Preview, the first page of the output should look like this:
In the Print dialog box, you can specify any range of pages to print.