⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcprint.cpp

📁 磁盘容量扫描、但界面和程序结构非常不错
💻 CPP
字号:
#include "stdafx.h"
#include "LCPrint.h"

#define LEFT_MARGIN 2
#define RIGHT_MARGIN 4
#define HEADER_HEIGHT 4
#define FOOTER_HEIGHT 3

//Set it all to 0
//********************************CONSTRUCTOR************************************
CListPrinting::CListPrinting()
{
	lc = 0;
	pOldFont = 0;
	TitleStr = "";
	DateStr = "";
	
	page_rc.SetRect(0,0,0,0);	
	m_nRowHeight = 0;
	m_nRowsPerPage = 0;
	m_nMaxRowCount = 0;
	m_ratiox = 0;
	m_ratioy = 0;
	hc_items = 0;
	return;
}

//Using default for printer guess at # of pages.
//If no printer exists return FALSE;
//************************ONPREPAREPRINTING*******************************
BOOL CListPrinting::OnPreparePrinting(CPrintInfo* pInfo, CView * cview, CListCtrl * t_lc) 
{
	if(t_lc==NULL || pInfo == NULL)          return FALSE;
	lc = t_lc;//Set Pointer to list Control
	
	//Lets make a guess as to how many pages there are based on the default printer.
	CPrintDialog pdlg(FALSE);
	if (!pdlg.GetDefaults()) return FALSE;//If no defaults then no printer!!
	CDC t_pDC;
	t_pDC.Attach(pdlg.GetPrinterDC());
	compute_metrics(&t_pDC);
	m_nMaxRowCount = lc->GetItemCount(); if(!m_nMaxRowCount) return FALSE;//Get the number of rows
	int nMaxPage = m_nMaxRowCount/m_nRowsPerPage + 1;
	pInfo->SetMaxPage(nMaxPage);
	pInfo->m_nCurPage = 1;  // start printing at page# 1
	
	//If you want to be able to do this remove it.
	pInfo->m_pPD->m_pd.Flags |=PD_HIDEPRINTTOFILE; 
	
	if (cview)
		return cview->DoPreparePrinting(pInfo);
	else 
		return TRUE;
}

//Call this from your view class OnBeingPrinting function
//*************************ONBEGINGPRINTING*************************
void CListPrinting::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo, CString & t_title, CString & t_date)
{
	if(pDC == NULL || pInfo==NULL)          
		return;
	
	TitleStr = t_title;
	DateStr = t_date;
	
	//create lc font, and Bold lc Font
	LOGFONT  lf;
	CFont * lcfont_ptr = lc->GetFont();
	lcfont_ptr->GetLogFont(&lf);
	lcFont.CreateFontIndirect(&lf);
	lf.lfWeight = FW_BOLD;
	lf.lfHeight+=22;//Make it a little bigger
	lf.lfWidth = 0;
	BoldFont.CreateFontIndirect(&lf);
	
	compute_metrics(pDC);
	int nMaxPage = m_nMaxRowCount/m_nRowsPerPage + 1;//Compute this again in case user changed printer
	pInfo->SetMaxPage(nMaxPage);
	pInfo->m_nCurPage = 1;  // start printing at page# 1
	
	return;
}

//***********************ONPRINT*************************
void CListPrinting::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
	if(NULL == pDC || NULL == pInfo)           
		return;
	
	//This has to be in OnPrint() or else PrintPreview goes screwy
	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;
	
	PrintHeader(pDC, pInfo);     //print the header
	
	pDC->SetWindowOrg(-1*page_rc.left, 0);
	PrintFooter(pDC, pInfo);	  //Print the footer
	pDC->SetWindowOrg(-1*page_rc.left, -1*HEADER_HEIGHT*m_nRowHeight);
	PrintHeaderControl(pDC, pInfo);//Print the header Control, Manually
	pDC->SelectObject(&lcFont);//Use the LC normal font
	pDC->SetTextColor(RGB(0,0,0));//Black text on
	pDC->SetBkColor(RGB(255,255,255));//White paper
	
	CRect     rcBounds;
	lc->GetItemRect(nStartRow, &rcBounds, LVIR_BOUNDS);
	
	//offset top margin of rcBounds by ListControl header
	CRect     rc;
	lc->GetHeaderCtrl()->GetClientRect(&rc);
	rcBounds.OffsetRect(0, -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);
	pDC->SelectObject(pOldFont);//Put the old font back
	
	return;
}

//Set the extents after calling this function because it uses printer extents
//He is using a list in here have to figure out what to do.
//********************************PRINT_HEADER************************************
void CListPrinting::PrintHeader(CDC *pDC, CPrintInfo *pInfo)
{
	pDC->SelectObject(&BoldFont);
	pDC->SetTextColor(RGB(0,0,0));//Black text on
	pDC->SetBkColor(RGB(255,255,255));//White paper
	
	CRect rc = page_rc;
	rc.bottom = rc.top+m_nRowHeight;
	
	//print App title on top right margin
	pDC->DrawText(TitleStr, &rc,  DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_RIGHT  | DT_NOCLIP);
	
	return;
}

//print footer with a line and date, and page number
//****************************PRINT_FOOTER****************************************
void CListPrinting::PrintFooter(CDC *pDC, CPrintInfo *pInfo)
{
	CRect     rc = page_rc;
	rc.top = rc.bottom - FOOTER_HEIGHT*m_nRowHeight;
	rc.bottom = rc.top + m_nRowHeight;
	draw_line_at(pDC, rc.top);     //draw line
	
	//draw page number
	CString   sTemp ;
	rc.OffsetRect(0, m_nRowHeight/2);
	sTemp.Format("%d", pInfo->m_nCurPage);
	pDC->DrawText(sTemp,-1,rc, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
	
	//Now draw the DateStr at bottom of page
	pDC->DrawText(DateStr,-1,rc, DT_RIGHT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
	
	return;
}


//Do the cleanup
//********************ONEND_PRINTING*****************
void CListPrinting::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	lcFont.DeleteObject();
	BoldFont.DeleteObject();
	return;
}

//This function sets alls of the row and metric member vars
//************************COMPUTE_METRICS*********************
void CListPrinting::compute_metrics(CDC *pDC)
{
	//This includes width for all columns
	CRect row_rc;	lc->GetItemRect(0, &row_rc, LVIR_BOUNDS);
	
	//Get the list control window DC
	CDC  *pCtlDC = lc->GetDC(); if(NULL == pCtlDC) 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);
	
	lc->ReleaseDC(pCtlDC);
	
	//Set up a page rc in list control units that accounts for left and right margins
	page_rc.SetRect(0,0, pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
	page_rc.bottom = page_rc.bottom/m_ratioy;//Convert units to List Control
	page_rc.right = page_rc.right/m_ratiox;
	page_rc.left = LEFT_MARGIN*tm.tmAveCharWidth;//adjust sides for magins
	page_rc.right -= RIGHT_MARGIN*tm.tmAveCharWidth;
	
	m_nRowHeight = row_rc.Height();//Get the height of a row.
	int pRowHeight = (int)(m_nRowHeight*m_ratioy);//Get RowHeight in printer units.
	m_nRowsPerPage = pDC->GetDeviceCaps(VERTRES)/pRowHeight;//How many rows will fit on page?
	m_nRowsPerPage -= (HEADER_HEIGHT+FOOTER_HEIGHT);//After header and footer rows
	m_nRowsPerPage -= 1; //After header Control row
	
	return;
}

//You can't just have the header control print itself. 1st of all it looks crappy.
//2nd if part of header control is off screen does not print itself.
//So we will manually print it.
//************************PRINTHEADERCONTROL****************************
void CListPrinting::PrintHeaderControl(CDC *pDC, CPrintInfo *pInfo)
{
	UINT    dtFlags = DT_SINGLELINE|DT_NOPREFIX|DT_VCENTER|DT_LEFT;//drawing flags
	CHeaderCtrl* hc = lc->GetHeaderCtrl();
	hc_items = hc->GetItemCount(); 
	if (hc_items < 1) return; //Remember that hc_items is also used to draw rows.
	int order_array[30];//Shouln't have more than 30 columns
	hc->GetOrderArray(order_array, hc_items);
	
	char temp_str[1024];
	HDITEM  phi;
	phi.mask = HDI_TEXT | HDI_WIDTH ;
	phi.cchTextMax = 1024;
	phi.pszText = temp_str;
	
	CRect rc(0,0,0,m_nRowHeight);
	
	for (int i = 0; i < hc_items; i++)
	{
		hc->GetItem(order_array[i], &phi);//Get in viewed order
		rc.right += phi.cxy;
		pDC->DrawText(temp_str, -1, rc, dtFlags);
		rc.left += phi.cxy;
	}
	
	//Now draw the line below header control
	draw_line_at(pDC, rc.bottom);
	
	return;
}

//*************************************DRAWROW********************************************
void CListPrinting::DrawRow(CDC *pDC, int nItem)
{
	if (hc_items < 1) //Then nothing to print
		return;  
	
	int order_array[30];//Shouln't have more than 30 columns
	lc->GetColumnOrderArray(order_array, hc_items);
	
	CString temp_str;
	LV_COLUMN lvc;
	lvc.mask = LVCF_WIDTH;
	
	CRect rc; lc->GetItemRect(nItem, rc, LVIR_BOUNDS);
	int offset = pDC->GetTextExtent(" ", 1).cx;//Returns CSIZE so get cx member of CSIZE object.
	rc.left += offset/2;//This makes it so that label will be over a little bit
	rc.right -= offset;//Just keep this stuff it DOES look better.
	
	for (int i = 0; i < hc_items; i++)
	{
		lc->GetColumn(order_array[i], &lvc);//Get in viewed order
		temp_str = lc->GetItemText(nItem, order_array[i]);
		rc.right += lvc.cx;
		pDC->DrawText(temp_str, -1, rc, DT_SINGLELINE|DT_NOPREFIX|DT_VCENTER|DT_LEFT);
		draw_line_at(pDC, rc.bottom);//draw a line below each row
		rc.left += lvc.cx;
	}
	
	return;
}

//Just pass this function a y position to draw the line at.
//*************************DRAW_LINE_AT************************************
void CListPrinting::draw_line_at(CDC *pDC, unsigned int y)
{
	pDC->MoveTo(0, y);
	pDC->LineTo(page_rc.right, y);//Use the page_rc to figure out the width of the line
	
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -