65.9K
CodeProject is changing. Read more.
Home

Another ListView print (preview) sample.

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (14 votes)

Jan 8, 2003

CPOL
viewsIcon

141808

downloadIcon

1787

Illustrates how MFC based List View content can be printed.

Sample Image - ListPrintDemo.jpg

Introduction

This article shows how to add print preview functionality to MFC CListView class in report mode, preserving column order and relative column with. Note that this implementation does NOT try to fit all list columns on one page.

How it works

The OnBeginPrinting function prepares printer fonts and calculates paper, page, header, footer and body rectangles.

void CListDemoViewPrint::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{   
   // Create fonts
   m_pFontHeader = CreateFont(pDC,_T("Arial"), 12, FW_BOLD);
   m_pFontFooter = CreateFont(pDC,_T("Arial"), 10);
   m_pFontColumn = CreateFont(pDC,_T("Arial"), 9, FW_BOLD);
   m_pFontBody   = CreateFont(pDC,_T("Times New Roman"), 10);

   // Calculate character size
   m_CharSizeHeader = GetCharSize(pDC, m_pFontHeader);
   m_CharSizeFooter = GetCharSize(pDC, m_pFontFooter);
   m_CharSizeBody   = GetCharSize(pDC, m_pFontBody);

   // Prepare layout 
   m_rectPaper  = GetPaperRect(pDC);
   m_rectPage   = GetPageRect();
   m_rectHeader = GetHeaderRect();
   ...
   m_RatioX = GetTextRatioX(pDC);   
   ...
}

Character sizes are used later to calculate header and footer vertical height, body character size is used to calculate row (cell) height, number of rows per page and horizontal X ratio to adjust column width.

Character size is calculated simply by selecting font and getting sample string extent as follows.

CSize CListDemoViewPrint::GetCharSize(CDC* pDC, CFont* pFont)
{
   CFont *pOldFont = pDC->SelectObject(pFont);
   CSize charSize = pDC->GetTextExtent(_T("abcdefghijkl
       mnopqrstuvwxyzABCDEFGHIJKLMNOPQRSATUVWXYZ"),52);
   charSize.cx /= 52;
   pDC->SelectObject(pOldFont);
   return charSize;
}

Horizontal text ratio is calculated using body font character size and list control average character size.

double CListDemoViewPrint::GetTextRatioX(CDC* pDC)
{
   ASSERT(pDC != NULL);
   ASSERT(m_pListCtrl);
   CDC* pCurrentDC = m_pListCtrl->GetDC();
   TEXTMETRIC tmSrc;
   pCurrentDC->GetTextMetrics(&tmSrc);
   m_pListCtrl->ReleaseDC(pCurrentDC);
   return ((double)m_CharSizeBody.cx) / ((double)tmSrc.tmAveCharWidth);
}

Using the code

Add the CListDemoViewPrint class member to your CListView derived class.

class CListDemoView : public CListView
{
  ...
  CListDemoViewPrint m_Print;
};

Add the following printing functions to your class.

BOOL CListDemoView::OnPreparePrinting(CPrintInfo* pInfo)
{
   m_Print.OnPreparePrinting(pInfo);
   return DoPreparePrinting(pInfo);
}

void CListDemoView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{   
   m_Print.OnBeginPrinting(pDC, pInfo);
}

void CListDemoView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
   m_Print.OnPrint(pDC, pInfo);
}

void CListDemoView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
   m_Print.OnEndPrinting(pDC, pInfo);
}