www.pudn.com > HReportTest.rar > HReportListPrint.cpp
// HReportListPrint.cpp: implementation of the CHReportListPrint class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HReportListPrint.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
BOOL CHReportListPrint::OnPreparePrinting(CPrintInfo *pInfo)
{
ASSERT(m_pList != NULL);
pInfo->SetMinPage(1);
if(m_pList->GetItemCount() <= 0)
return FALSE;
CHeaderCtrl* pHeader = (CHeaderCtrl*) (m_pList->GetHeaderCtrl());
ASSERT(pHeader != NULL);
const int nColCount = pHeader->GetItemCount();
if (nColCount <= 0)
return FALSE;
m_pDx = new int[nColCount+1];
m_pFormat = new int[nColCount];
m_pColTitle = new char *[nColCount];
ZeroMemory(m_pDx, sizeof(int) * (nColCount + 1));
ZeroMemory(m_pFormat, sizeof(int) * nColCount);
ZeroMemory(m_pColTitle, sizeof(char *) * nColCount);
char txt[128];
for (int i = 0; i < nColCount; ++i)
{
HDITEM hi;
hi.cchTextMax = 128;
hi.pszText = txt;
hi.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT;
if (pHeader->GetItem(i, &hi))
{
m_pDx[i+1] = hi.cxy;
m_pFormat[i] = hi.fmt;
if (hi.cchTextMax > 0 && hi.pszText)
{
m_pColTitle[i] = new char[hi.cchTextMax];
ASSERT(m_pColTitle[i]);
lstrcpy(m_pColTitle[i], hi.pszText);
}
}
}
return TRUE;
}
void CHReportListPrint::OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo)
{
ASSERT(m_pList != NULL);
pInfo->m_rectDraw.SetRect(0, 0, pDC->GetDeviceCaps(HORZRES),
pDC->GetDeviceCaps(VERTRES));
pDC->DPtoLP(pInfo->m_rectDraw);
// 创建字体
// m_fontPrint.CreatePointFont(m_nPrintSize * 10, m_strPrintName, pDC);
CreateFontX(m_fontPrint, pDC, m_strPrintName, m_nPrintSize, m_bPrintBold);
CreateFontX(m_fontHead, pDC, m_strHeadName, m_nHeadSize, m_bHeadBold);
CreateFontX(m_fontFoot, pDC, m_strFootName, m_nFootSize, m_bFootBold);
// 计算字体宽度
CString str = "H";
CFont* oldFont = pDC->SelectObject(&m_fontPrint);
m_sizePrint = pDC->GetTextExtent(str);
pDC->SelectObject(&m_fontHead);
m_sizeHead = pDC->GetTextExtent(str);
pDC->SelectObject(&m_fontFoot);
m_sizeFoot = pDC->GetTextExtent(str);
pDC->SelectObject(oldFont);
m_sizePrint.cy += 4;
m_sizeHead.cy += m_nHeadMargin;
// 计算列宽
const int nColCount = m_pList->GetHeaderCtrl()->GetItemCount();
for (int i = 1; i <= nColCount; ++i)
m_pDx[i] += m_pDx[i-1];
CRect rcPrint(pInfo->m_rectDraw);
SubtractMargin(pDC, rcPrint);
double db = rcPrint.Width();
db /= (double) m_pDx[nColCount];
for (i = 0; i <= nColCount; ++i)
m_pDx[i] = (int)double(m_pDx[i] * db);
// 计算
PrintListHead(pDC, rcPrint, TRUE);
PrintPageHead(pDC, rcPrint, TRUE);
CSize sz1 = PrintListFoot(pDC, rcPrint, TRUE);
CSize sz2 = PrintPageFoot(pDC, rcPrint, 0, 0, TRUE);
m_nFootHeight = sz1.cy + sz2.cy + 2;
// 计算总页数
m_nItemsOfPage = rcPrint.Height() / (m_sizePrint.cy + m_nLineSpace) - 1; // 每页行数
int nPages = m_pList->GetItemCount() / m_nItemsOfPage + 1; // 总页数
pInfo->SetMaxPage(nPages);
}
void CHReportListPrint::OnPrint(CDC *pDC, CPrintInfo *pInfo)
{
CRect rcPrint(pInfo->m_rectDraw);
SubtractMargin(pDC, rcPrint);
int nOldMode = pDC->SetBkMode(TRANSPARENT);
//打印页头
PrintPageHead(pDC, rcPrint, FALSE);
//打印表头
PrintListHead(pDC, rcPrint, FALSE);
int nFirst = (pInfo->m_nCurPage - 1) * m_nItemsOfPage;
int nLast = (pInfo->m_nCurPage) * m_nItemsOfPage;
int y = rcPrint.top;
int x = rcPrint.left;
CFont * pOldFont = pDC->SelectObject(&m_fontPrint);
const int nMax = m_pList->GetItemCount();
const int nColCount = m_pList->GetHeaderCtrl()->GetItemCount();
CRect rc;
for (int i = nFirst; i < nLast; ++i)
{
for (int t = 0; t < nColCount; ++t)
{
rc.SetRect( rcPrint.left + m_pDx[t] + m_nLeftMargin,
y,
rcPrint.left + m_pDx[t+1],
y + m_sizePrint.cy + m_nLineSpace);
if (i < nMax)
{
UINT format = DT_LEFT;
if ( m_pFormat[t] & HDF_CENTER )
format = DT_CENTER;
else if ( m_pFormat[t] & HDF_RIGHT )
format = DT_RIGHT;
//打印单元格文字
pDC->DrawText(m_pList->GetItemText(i, t), rc, format| DT_VCENTER | DT_SINGLELINE);
}
//画单元格的左边和顶边
pDC->MoveTo(rc.left - m_nLeftMargin, rc.bottom);
pDC->LineTo(rc.left - m_nLeftMargin, rc.top);
pDC->LineTo(rc.right, rc.top);
}
//画一行的右边
pDC->LineTo(rc.right, rc.bottom+1);
y += m_sizePrint.cy + m_nLineSpace;
}
//画表格最下面的横线
pDC->MoveTo(rcPrint.left, y);
pDC->LineTo(rcPrint.right, y);
pDC->SelectObject(pOldFont);
rcPrint = pInfo->m_rectDraw;
SubtractMargin(pDC, rcPrint);
rcPrint.top = rcPrint.bottom - m_nFootHeight;
PrintListFoot(pDC, rcPrint, FALSE);
PrintPageFoot(pDC, rcPrint, pInfo->m_nCurPage, (int) pInfo->GetMaxPage(), FALSE);
pDC->SetBkMode(nOldMode);
}
#define SAFE_DELETE(p) if(p) { delete p; p = NULL; }
#define SAFE_DELETE_ARRAY(p) if(p) { delete [] p; p = NULL; }
void CHReportListPrint::OnEndPrinting(CDC *pDC, CPrintInfo *pInfo)
{
ASSERT(m_pList != NULL);
const int nColCount = m_pList->GetHeaderCtrl()->GetItemCount();
if (nColCount > 0)
{
SAFE_DELETE(m_pDx);
SAFE_DELETE_ARRAY(m_pFormat);
if (m_pColTitle)
{
for (int i = 0; i < nColCount; ++i)
SAFE_DELETE_ARRAY(m_pColTitle[i]);
SAFE_DELETE_ARRAY(m_pColTitle);
}
}
m_fontPrint.Detach();
m_fontHead.Detach();
m_fontFoot.Detach();
}
// 打印页头
CSize CHReportListPrint::PrintPageHead(CDC* pDC, CRect& rcPage, BOOL bCalc)
{
CFont* pOldFont = pDC->SelectObject(&m_fontHead);
CSize sizePage(0,0);
//打印标题
if (!m_strPageHead.IsEmpty())
{
CRect rc(rcPage);
rc.bottom = rc.top + m_sizeHead.cy;
if ( bCalc )
pDC->DrawText(m_strPageHead, rc, DT_CALCRECT | DT_CENTER);
else
pDC->DrawText(m_strPageHead, rc, DT_CENTER);
if (rc.Height() > sizePage.cy)
sizePage.cy = rc.Height();
}
rcPage.top += sizePage.cy + m_nHeadMargin;
pDC->SelectObject(pOldFont);
return sizePage;
}
CSize CHReportListPrint::PrintPageFoot(CDC* pDC, CRect& rcPage, const int nPage,
const int nMaxPage, BOOL bCalc)
{
CFont* pOldFont = pDC->SelectObject(&m_fontFoot);
CSize sizePage(0,0);
// 打印"第%d页 共%d页"
if (!m_strPageFormat.IsEmpty())
{
CString str;
str.Format(m_strPageFormat, nPage, nMaxPage);
CRect rc (rcPage);
rc.top = rc.bottom - m_sizeFoot.cy - 4;
if (bCalc)
pDC->DrawText(str, rc, DT_WORDBREAK | DT_CALCRECT | DT_CENTER);
else
pDC->DrawText(str, rc, DT_WORDBREAK | DT_CENTER);
sizePage.cy = rc.Height();
}
rcPage.bottom -= sizePage.cy;
pDC->SelectObject(pOldFont);
return sizePage;
}
CSize CHReportListPrint::PrintListHead(CDC * pDC, CRect & rcPage, BOOL bCalc)
{
if (!bCalc)
{
CFont* pOldFont = pDC->SelectObject(&m_fontPrint);
CRect rcc(rcPage.left, rcPage.top, rcPage.right, rcPage.top + m_sizePrint.cy);
const int nColCount = m_pList->GetHeaderCtrl()->GetItemCount();
CRect rc;
CString str;
int y = rcPage.top;
for (int i = 0; i < nColCount; i++)
{
rc.SetRect( rcPage.left + m_pDx[i] + m_nLeftMargin,
y,
rcPage.left + m_pDx[i+1],
y + m_sizePrint.cy + m_nLineSpace);
str = m_pColTitle[i] ? m_pColTitle[i] : "";
UINT format = DT_LEFT;
if ( m_pFormat[i] & HDF_CENTER )
format = DT_CENTER;
else if ( m_pFormat[i] & HDF_RIGHT )
format = DT_RIGHT;
pDC->DrawText(str, rc, format | DT_VCENTER | DT_SINGLELINE);
//画单元格的左边和顶边
pDC->MoveTo(rc.left - m_nLeftMargin, rc.bottom);
pDC->LineTo(rc.left - m_nLeftMargin, rc.top);
pDC->LineTo(rc.right, rc.top);
}
//画一行的右边
pDC->LineTo(rc.right, rc.bottom + 1);
pDC->SelectObject(pOldFont);
}
rcPage.top += m_sizePrint.cy + m_nLineSpace;
return CSize(0, m_sizePrint.cy);
}
CSize CHReportListPrint::PrintListFoot(CDC* pDC, CRect& rcPage, BOOL bCalc)
{
return CSize(0, 0);
}
void CHReportListPrint::SubtractMargin(CDC* pDC, CRect& rc)
{
CRect rcMarginMM = CRect(10, 10, 10, 10);
CSize sizeUp(rcMarginMM.left * 100, rcMarginMM.top * 100);
CSize sizeDown(rcMarginMM.right * 100, rcMarginMM.bottom * 100);
pDC->HIMETRICtoDP(&sizeUp);
pDC->HIMETRICtoDP(&sizeDown);
rc.top += sizeUp.cy;
rc.left += sizeUp.cx;
rc.right -= sizeDown.cx;
rc.bottom -= sizeDown.cy;
}
//创建字体
void CHReportListPrint::CreateFontX(CFont& font, CDC* pDC, const CString &strFont, int nSize, BOOL bBold)
{
//初始化
LOGFONT lf;
GetObject(GetStockObject(SYSTEM_FONT), sizeof(lf), &lf);
lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL;
//更改字体
_tcscpy(lf.lfFaceName, strFont);
const int LOGY = pDC->GetDeviceCaps(LOGPIXELSY);
//更改大小
LOGFONT lf2;
// font.CreatePointFont(-MulDiv(nSize, -LOGY, 72), lf.lfFaceName, pDC);
font.CreatePointFont(nSize * 20, lf.lfFaceName, NULL);
font.GetLogFont(&lf2);
lf.lfHeight = lf2.lfHeight;
lf.lfWidth = lf2.lfWidth;
lf.lfCharSet= lf2.lfCharSet;
font.DeleteObject();
BOOL bCreated = font.CreateFontIndirect(&lf);
ASSERT(bCreated);
}