另一个 ListView 打印(预览)示例。






4.67/5 (14投票s)
演示了如何打印基于 MFC 的 ListView 内容。
引言
本文档展示了如何在报告模式下为 MFC CListView
类添加打印预览功能,同时保留列的顺序和相对宽度。请注意,此实现并不尝试将所有列表列都放在同一页上。
工作原理
OnBeginPrinting
函数准备打印机字体,并计算纸张、页面、页眉、页脚和正文矩形。
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); ... }
字符大小稍后用于计算页眉和页脚的垂直高度,正文字符大小用于计算行(单元格)高度、每页的行数以及水平 X 比例,以调整列宽。
字符大小的计算方法很简单,就是选择字体并获取示例字符串的范围,如下所示。
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; }
水平文本比例是使用正文字体字符大小和列表控件平均字符大小计算得出的。
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); }
使用代码
将 CListDemoViewPrint
类成员添加到您的 CListView
派生类中。
class CListDemoView : public CListView { ... CListDemoViewPrint m_Print; };
将以下打印函数添加到您的类中。
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); }