496 lines
15 KiB
C++
496 lines
15 KiB
C++
/*===========================================================================
|
|
==== ====
|
|
==== ====
|
|
=============================================================================
|
|
==== ====
|
|
==== File : LCPrinter.cpp ====
|
|
==== Project name : ====
|
|
==== Project number : ====
|
|
==== Creation date : 10/08/2000 ====
|
|
==== ====
|
|
==== ====
|
|
=============================================================================
|
|
===========================================================================*/
|
|
|
|
//============================================================================
|
|
// Inclusions
|
|
//============================================================================
|
|
#include "stdafx.h"
|
|
#include "LCPrinter.h"
|
|
|
|
//============================================================================
|
|
// Constants
|
|
//============================================================================
|
|
const int LEFT_MARGIN = 4;
|
|
const int RIGHT_MARGIN = 8;
|
|
const int HEADER_HEIGHT = 2;
|
|
const int FOOTER_HEIGHT = 2;
|
|
|
|
//============================================================================
|
|
// Data types
|
|
//============================================================================
|
|
|
|
|
|
//============================================================================
|
|
// Variables
|
|
//============================================================================
|
|
|
|
|
|
//============================================================================
|
|
// Development tools
|
|
//============================================================================
|
|
|
|
|
|
//============================================================================
|
|
// Templates and global functions
|
|
//============================================================================
|
|
|
|
|
|
//============================================================================
|
|
//============================================================================
|
|
// class CLCPrinter
|
|
//============================================================================
|
|
//============================================================================
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: Constructor.
|
|
|
|
============================================================================*/
|
|
CLCPrinter::CLCPrinter()
|
|
{
|
|
m_nRowHeight = 0;
|
|
m_nRowsPerPage = 0;
|
|
m_nMaxRowCount = 0;
|
|
m_ratiox = 0;
|
|
m_ratioy = 0;
|
|
m_hcItems = 0;
|
|
|
|
m_pLC = NULL;
|
|
m_pOldFont = NULL;
|
|
|
|
m_page_rc.SetRect(0,0,0,0);
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: Sets alls of the row and metric member variables
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
void CLCPrinter::ComputeMetrics(CDC *pDC)
|
|
{
|
|
// This includes width for all columns
|
|
CRect row_rc;
|
|
m_pLC->GetItemRect(0, &row_rc, LVIR_BOUNDS);
|
|
|
|
// Get the list control window DC
|
|
CDC* pCtlDC = m_pLC->GetDC();
|
|
if (pCtlDC == NULL) {
|
|
return;
|
|
}
|
|
|
|
// so we can get the avg character width
|
|
TEXTMETRIC tm;
|
|
pCtlDC->GetTextMetrics(&tm);
|
|
|
|
// Lets get the ratios for scaling to printer DC
|
|
// Fit all columns to 1 page, regardless of column number.
|
|
m_ratiox = pDC->GetDeviceCaps(HORZRES)/(row_rc.Width() + (LEFT_MARGIN+RIGHT_MARGIN)*tm.tmAveCharWidth);
|
|
|
|
// width of pDC/whats got to fit into it in lcDC units
|
|
m_ratioy = pDC->GetDeviceCaps(LOGPIXELSY)/pCtlDC->GetDeviceCaps(LOGPIXELSY);
|
|
|
|
m_pLC->ReleaseDC(pCtlDC);
|
|
|
|
// Set up a page rc in list control units that accounts for left and right margins
|
|
m_page_rc.SetRect(0, 0, pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
|
|
|
|
// Convert units to List Control
|
|
m_page_rc.bottom = m_page_rc.bottom / m_ratioy;
|
|
m_page_rc.right = m_page_rc.right / m_ratiox;
|
|
|
|
// Adjust sides for magins
|
|
m_page_rc.left = LEFT_MARGIN * tm.tmAveCharWidth;
|
|
m_page_rc.right -= RIGHT_MARGIN * tm.tmAveCharWidth;
|
|
|
|
// Get the height of a row.
|
|
m_nRowHeight = row_rc.Height();
|
|
|
|
// Get RowHeight in printer units.
|
|
int pRowHeight = (int)(m_nRowHeight * m_ratioy);
|
|
|
|
// How many rows will fit on page?
|
|
m_nRowsPerPage = pDC->GetDeviceCaps(VERTRES)/pRowHeight;
|
|
|
|
// After header and footer rows
|
|
m_nRowsPerPage -= (HEADER_HEIGHT*2+FOOTER_HEIGHT);
|
|
|
|
//After header Control row
|
|
m_nRowsPerPage -= 1;
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: Draw a horizontal line at the specified position
|
|
|
|
pDC: See MFC
|
|
|
|
y: Y-Axis position at which the line is to be drawned
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
void CLCPrinter::DrawLineAt(CDC *pDC, unsigned int y)
|
|
{
|
|
//Use the m_page_rc to figure out the width of the line
|
|
pDC->MoveTo(0, y);
|
|
pDC->LineTo(m_page_rc.right, y);
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: Draw a row of the list control
|
|
|
|
pDC: See MFC
|
|
|
|
nItem: Index of the item to be printed
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
void CLCPrinter::DrawRow(CDC *pDC, int nItem)
|
|
{
|
|
// If nothing to print, return
|
|
if (m_hcItems < 1) {
|
|
return;
|
|
}
|
|
|
|
// Shouln't have more than 30 columns
|
|
int order_array[30];
|
|
m_pLC->GetColumnOrderArray(order_array, m_hcItems);
|
|
|
|
CRect rc;
|
|
CString temp_str;
|
|
LV_COLUMN lvc;
|
|
lvc.mask = LVCF_WIDTH;
|
|
|
|
m_pLC->GetItemRect(nItem, rc, LVIR_LABEL);
|
|
int offset = pDC->GetTextExtent(_T(" "), 1).cx;
|
|
|
|
// This makes it so that label will be over a little bit
|
|
rc.left += offset / 2;
|
|
|
|
// Just keep this stuff it DOES look better.
|
|
rc.right -= offset;
|
|
|
|
for (int i = 0; i < m_hcItems; i++) {
|
|
// Get in viewed order
|
|
m_pLC->GetColumn(order_array[i], &lvc);
|
|
temp_str = m_pLC->GetItemText(nItem, order_array[i]);
|
|
rc.right += lvc.cx;
|
|
pDC->DrawText(temp_str, -1, rc, DT_SINGLELINE|DT_NOPREFIX|DT_VCENTER|DT_LEFT);
|
|
|
|
// Draw a line below each row
|
|
DrawLineAt(pDC, rc.bottom);
|
|
rc.left += lvc.cx;
|
|
}
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: See MFC
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
void CLCPrinter::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo, const CString& titleStr, const CString& dateStr)
|
|
{
|
|
if (pDC == NULL || pInfo == NULL) {
|
|
return;
|
|
}
|
|
|
|
m_titleStr = titleStr;
|
|
m_dateStr = dateStr;
|
|
|
|
// Create listcontrol font, and bold listcontrol font
|
|
LOGFONT lf;
|
|
CFont* pFont = m_pLC->GetFont();
|
|
pFont->GetLogFont(&lf);
|
|
m_lcFont.CreateFontIndirect(&lf);
|
|
lf.lfWidth = 0;
|
|
lf.lfWeight = FW_BOLD;
|
|
|
|
// Make it a little bigger
|
|
lf.lfHeight+= 22;
|
|
m_boldFont.CreateFontIndirect(&lf);
|
|
|
|
// Compute this again in case user changed printer
|
|
ComputeMetrics(pDC);
|
|
int nMaxPage = m_nMaxRowCount/m_nRowsPerPage + 1;
|
|
pInfo->SetMaxPage(nMaxPage);
|
|
|
|
// Start printing at first page
|
|
pInfo->m_nCurPage = 1;
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: See MFC
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
void CLCPrinter::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
|
|
{
|
|
m_lcFont.DeleteObject();
|
|
m_boldFont.DeleteObject();
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: See MFC
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
BOOL CLCPrinter::OnPreparePrinting(CPrintInfo* pInfo, CView* pView, CListCtrl* pLC)
|
|
{
|
|
if (pLC == NULL || pView == NULL || pInfo == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
// Set Pointer to list Control
|
|
m_pLC = pLC;
|
|
|
|
// Lets make a guess as to how many pages there are based on the default printer.
|
|
CPrintDialog dlg(FALSE);
|
|
if (!dlg.GetDefaults()) {
|
|
//If no defaults then no printer!!
|
|
return FALSE;
|
|
}
|
|
|
|
CDC dc;
|
|
dc.Attach(dlg.GetPrinterDC());
|
|
ComputeMetrics(&dc);
|
|
|
|
// Get the number of rows
|
|
m_nMaxRowCount = m_pLC->GetItemCount();
|
|
if (!m_nMaxRowCount) {
|
|
return FALSE;
|
|
}
|
|
|
|
int nMaxPage = m_nMaxRowCount/m_nRowsPerPage + 1;
|
|
pInfo->SetMaxPage(nMaxPage);
|
|
|
|
// Start printing at first page
|
|
pInfo->m_nCurPage = 1;
|
|
|
|
// If you want to be able to do this remove it.
|
|
pInfo->m_pPD->m_pd.Flags |= PD_HIDEPRINTTOFILE;
|
|
|
|
return pView->DoPreparePrinting(pInfo);
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: See MFC
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
void CLCPrinter::OnPrint(CDC* pDC, CPrintInfo* pInfo)
|
|
{
|
|
if (pDC == NULL || pInfo == NULL) {
|
|
return;
|
|
}
|
|
|
|
// This has to be in OnPrint() or else PrintPreview goes screwy
|
|
m_pOldFont = pDC->GetCurrentFont();
|
|
|
|
// Fit all columns to 1 page, regardless of column number.
|
|
pDC->SetMapMode(MM_ANISOTROPIC);
|
|
|
|
// For every 1 List Control pixel
|
|
pDC->SetWindowExt(1, 1);
|
|
|
|
// The printer has ratio more dots
|
|
pDC->SetViewportExt(m_ratiox, m_ratioy);
|
|
|
|
int nStartRow = (pInfo->m_nCurPage - 1) * m_nRowsPerPage;
|
|
int nEndRow = nStartRow + m_nRowsPerPage;
|
|
if (nEndRow > m_nMaxRowCount) {
|
|
nEndRow = m_nMaxRowCount;
|
|
}
|
|
|
|
// Print the header
|
|
pDC->SetWindowOrg(-1 * m_page_rc.left, 0);
|
|
PrintHeader(pDC, pInfo);
|
|
|
|
// Print the footer
|
|
PrintFooter(pDC, pInfo);
|
|
pDC->SetWindowOrg(-1 * m_page_rc.left, -1 * HEADER_HEIGHT * m_nRowHeight);
|
|
|
|
// Print the header Control manually
|
|
PrintHeaderControl(pDC, pInfo);
|
|
|
|
// Use the LC normal font
|
|
pDC->SelectObject(&m_lcFont);
|
|
|
|
// Black text on white paper
|
|
pDC->SetTextColor(RGB(0, 0, 0));
|
|
pDC->SetBkColor(RGB(255, 255, 255));
|
|
|
|
CRect rcBounds;
|
|
m_pLC->GetItemRect(nStartRow, &rcBounds, LVIR_BOUNDS);
|
|
|
|
// Offset top margin of rcBounds by ListControl header
|
|
CRect rc;
|
|
m_pLC->GetHeaderCtrl()->GetClientRect(&rc);
|
|
rcBounds.OffsetRect(0, -1 * rc.Height());
|
|
pDC->OffsetWindowOrg(rcBounds.left, rcBounds.top);
|
|
|
|
// Start printing rows
|
|
for (int i = nStartRow; i < nEndRow; i++) {
|
|
DrawRow(pDC, i);
|
|
}
|
|
|
|
// SetWindowOrg back for next page
|
|
pDC->SetWindowOrg(0,0);
|
|
|
|
// Put the old font back
|
|
pDC->SelectObject(m_pOldFont);
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: Print the page footer with a line and a date, and page number
|
|
|
|
pDC: See MFC
|
|
|
|
pInfo: See MFC
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
void CLCPrinter::PrintFooter(CDC *pDC, CPrintInfo *pInfo)
|
|
{
|
|
CRect rc = m_page_rc;
|
|
rc.top = rc.bottom - FOOTER_HEIGHT * m_nRowHeight;
|
|
rc.bottom = rc.top + m_nRowHeight + FOOTER_HEIGHT;
|
|
|
|
// Draw line
|
|
DrawLineAt(pDC, rc.top);
|
|
DrawLineAt(pDC, rc.top + 1);
|
|
DrawLineAt(pDC, rc.top + 2);
|
|
|
|
// Draw page number
|
|
CString sTemp ;
|
|
rc.OffsetRect(0, m_nRowHeight/2);
|
|
sTemp.Format(_T("Page %d - %d"), pInfo->m_nCurPage, pInfo->GetMaxPage());
|
|
pDC->DrawText(sTemp, -1, rc, DT_RIGHT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
|
|
|
|
// Now draw the date at bottom of page
|
|
rc.left = 0;
|
|
pDC->DrawText(m_dateStr, -1, rc, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: Print the page header
|
|
|
|
pDC: See MFC
|
|
|
|
pInfo: See MFC
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
void CLCPrinter::PrintHeader(CDC *pDC, CPrintInfo *pInfo)
|
|
{
|
|
pDC->SelectObject(&m_boldFont);
|
|
|
|
//Black text on white paper
|
|
pDC->SetTextColor(RGB(0, 0, 0));
|
|
pDC->SetBkColor(RGB(255, 255, 255));
|
|
|
|
CRect rc = m_page_rc;
|
|
rc.bottom = rc.top + m_nRowHeight + HEADER_HEIGHT;
|
|
|
|
//Use the m_page_rc to figure out the width of the line
|
|
DrawLineAt(pDC, rc.bottom + 1);
|
|
DrawLineAt(pDC, rc.bottom + 2);
|
|
DrawLineAt(pDC, rc.bottom + 3);
|
|
|
|
// Print App title on top left margin
|
|
pDC->DrawText(m_titleStr, &rc, DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_LEFT | DT_NOCLIP);
|
|
}
|
|
|
|
|
|
|
|
/*============================================================================
|
|
|
|
Description: Print the list control header
|
|
|
|
pDC: See MFC
|
|
|
|
pInfo: See MFC
|
|
|
|
Retour: -
|
|
|
|
============================================================================*/
|
|
void CLCPrinter::PrintHeaderControl(CDC *pDC, CPrintInfo *pInfo)
|
|
{
|
|
CHeaderCtrl* hc = m_pLC->GetHeaderCtrl();
|
|
|
|
// Drawing flags
|
|
UINT dtFlags = DT_SINGLELINE|DT_NOPREFIX|DT_VCENTER|DT_LEFT;
|
|
m_hcItems = hc->GetItemCount();
|
|
|
|
// Remember that m_hcItems is also used to draw rows.
|
|
if (m_hcItems < 1) {
|
|
return;
|
|
}
|
|
|
|
// Shouln't have more than 30 columns
|
|
int order_array[30];
|
|
hc->GetOrderArray(order_array, m_hcItems);
|
|
|
|
TCHAR temp_str[1024];
|
|
HDITEM phi;
|
|
phi.cchTextMax = 1024;
|
|
phi.mask = HDI_TEXT | HDI_WIDTH;
|
|
phi.pszText = temp_str;
|
|
|
|
CRect rc(0, 0, 0, m_nRowHeight);
|
|
|
|
for (int i = 0; i < m_hcItems; i++) {
|
|
// Get in viewed order
|
|
hc->GetItem(order_array[i], &phi);
|
|
rc.right += phi.cxy;
|
|
pDC->DrawText(temp_str, -1, rc, dtFlags);
|
|
rc.left += phi.cxy;
|
|
}
|
|
|
|
// Now draw the line below header control
|
|
DrawLineAt(pDC, rc.bottom);
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
//============================================================================
|
|
// Test section
|
|
//============================================================================
|
|
//============================================================================
|