www.gusucode.com > 几个VC++打印小例子-源码程序 > 几个VC++打印小例子-源码程序/code/Dlg_PrintTest/PrintView.cpp

    //Download by http://www.NewXing.com
// PrintView.cpp : implementation file
//

#include "stdafx.h"
#include "Dlg_PrintTest.h"
#include "PrintView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CPrintView

IMPLEMENT_DYNCREATE(CPrintView, CView)

CPrintView::CPrintView()
{
	m_pDlg = new CDlg_PrintTestDlg;
}

CPrintView::~CPrintView()
{
}


BEGIN_MESSAGE_MAP(CPrintView, CView)
	//{{AFX_MSG_MAP(CPrintView)
	ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPrintView drawing

void CPrintView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CPrintView diagnostics

#ifdef _DEBUG
void CPrintView::AssertValid() const
{
	CView::AssertValid();
}

void CPrintView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CPrintView message handlers

void CPrintView::OnFilePrint() 
{
	// TODO: Add your command handler code here
	CView::OnFilePrint();
}

void CPrintView::OnFilePrintPreview() 
{
	// TODO: Add your command handler code here
	CView::OnFilePrintPreview();
}

void CPrintView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
	// TODO: Add your specialized code here and/or call the base class
	if(m_pDlg)
	{
		//设置上、下、左、右页边距,单位为0.1mm
		SetMargin(pDC,pInfo,200,100, 200, 100);
		//添加页眉
		SetHead(pDC,pInfo,"打印预览",1 ,100);
		//添加右侧页脚,显示“第几页”
		CString str;
		str.Format("第%d页",pInfo->m_nCurPage);
		SetFoot(pDC,pInfo,str,1 ,100);
		//添加左侧页脚,显示打印时间
		CTime time = CTime::GetCurrentTime();
		str.Format("打印日期:%d-%d-%d",time.GetYear(),time.GetMonth(),time.GetDay());
		SetFoot(pDC,pInfo,str,-1 ,100);
		//打印主窗口编辑框中的内容
		pDC->DrawText(m_pDlg->m_strTest,&pInfo->m_rectDraw,DT_LEFT|DT_NOPREFIX);
	}
	CView::OnPrint(pDC, pInfo);
}

BOOL CPrintView::OnPreparePrinting(CPrintInfo* pInfo) 
{
	// TODO: call DoPreparePrinting to invoke the Print dialog box
	
	return DoPreparePrinting(pInfo);
}

void CPrintView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView) 
{
	// TODO: Add your specialized code here and/or call the base class	
	CView::OnEndPrintPreview(pDC, pInfo, point, pView);
	//设置主窗口为可视状态
	m_pFrameWnd->ShowWindow(SW_SHOW);
	//打印预览结束后,显示原来的主窗口
	AfxGetApp()->m_pMainWnd = m_pFrameWnd;
	//关闭打印预览的父窗口,否则只能关闭打印预览的子窗口
	GetParentFrame()->DestroyWindow();
}


void CPrintView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
{
	// TODO: Add your specialized code here and/or call the base class

	CView::OnPrepareDC(pDC, pInfo);
	//打印设置
	SetPrint(pDC,pInfo);	
}

//打印设置
void CPrintView::SetPrint(CDC *pDC,CPrintInfo *pInfo)
{
	//设置设备坐标与逻辑坐标之间的映射方式
	pDC->SetMapMode(MM_ANISOTROPIC);

	//设置窗口范围,单位为像素
	CSize window = CSize(800,600);
	pDC->SetWindowExt(window);

	//获取打印机设备的横方向和纵方向的分辨率
	//即每英寸像素点数
	int xPixPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
	int yPixPerInch = pDC->GetDeviceCaps(LOGPIXELSY);

	//将窗口坐标转化为视口坐标,得到视口坐标范围,单位为像素
	//若设备是VGA显示器,Windows自动将1英寸转化为96个像素点
	long xView = (long)window.cx*xPixPerInch/96;
	long yView = (long)window.cy*yPixPerInch/96;

	//设置视口坐标范围
	pDC->SetViewportExt((int)xView,(int)yView);
}


void CPrintView::SetMargin(CDC *pDC,CPrintInfo *pInfo,int top,int bottom,int left,int right)
{
	
	//获取打印机设备的横方向和纵方向的分辨率
	//即每英寸像素点数
	int xPixPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
	int yPixPerInch = pDC->GetDeviceCaps(LOGPIXELSY);
	
	//1 inch = 25.4mm,计算1个像素点占多少个0.1mm打印设备
	double xPointMM = 254.0/(double)xPixPerInch;	
	double yPointMM = 254.0/(double)yPixPerInch;

	//获取可打印区域的上边距、左边距、宽度、高度,单位为像素点
	int x = pDC->GetDeviceCaps(PHYSICALOFFSETX);
	int y = pDC->GetDeviceCaps(PHYSICALOFFSETY);
	int w = pDC->GetDeviceCaps(PHYSICALWIDTH);
	int h = pDC->GetDeviceCaps(PHYSICALHEIGHT);

	//计算打印纸的宽度、高度,单位为0.1mm
	int PageWidth = (int)((double)w*xPointMM + 0.5);
	int PageHeight = (int)((double)h*yPointMM + 0.5);

	//计算左边距、上边距,单位为0.1mm
	int Left = (int)((double)x*xPointMM + 0.5);
	int Top = (int)((double)y*yPointMM + 0.5);

	//调整左边距
	if(left < Left)
		left = Left;
	//调整上边距
	if(top < Top)
		top = Top;

	//左边距、上边距、右边距、下边距,单位为0.1mm
	int l = left;
	int t = top;
	int r = PageWidth - right - l;
	int b = PageHeight - bottom - t ;
	//转化为物理坐标范围,单位为像素
	int lPix = (int)(l/xPointMM + 0.5);
	int tPix = (int)(t/xPointMM + 0.5);
	int rPix = (int)(r/yPointMM + 0.5);
	int bPix = (int)(b/yPointMM + 0.5);
	//逻辑坐标转化为物理坐标
	pDC->LPtoDP(&pInfo->m_rectDraw);
	//设置打印区域
	pInfo->m_rectDraw.left = lPix;
	pInfo->m_rectDraw.right = rPix;
	pInfo->m_rectDraw.top = tPix;
	pInfo->m_rectDraw.bottom = bPix;
	//物理坐标转化为逻辑坐标
	pDC->DPtoLP(&pInfo->m_rectDraw);

}

void CPrintView::SetHead(CDC *pDC,CPrintInfo *pInfo,CString headstring,int xPos ,int yPos)
{
	//获取打印机设备的横方向和纵方向的分辨率
	//即每英寸像素点数
	int xPixPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
	int yPixPerInch = pDC->GetDeviceCaps(LOGPIXELSY); 
	//将距打印纸顶部的距离转化为物理距离,单位为像素
	int yPositionPix = yPos * yPixPerInch/254;
	//获取可打印区域的上边距,单位为像素
	int y = pDC->GetDeviceCaps(PHYSICALOFFSETY);
	//获取当前打印区域的逻辑坐标范围
	CRect rect = pInfo->m_rectDraw;
	//逻辑坐标转化为物理坐标
	pDC->LPtoDP(&rect);
	//物理坐标下的页眉范围
	rect.bottom = rect.top;
	rect.top = y + yPositionPix;
	//物理坐标转化为逻辑坐标
	pDC->DPtoLP(&rect);
	//设置页眉的水平位置
	int nFlag;
	switch(xPos)
	{
	case 0 :
		nFlag = DT_CENTER;//居中
		break;
	case -1:
		nFlag = DT_LEFT;//靠左
		break;
	case 1:
		nFlag = DT_RIGHT;//靠右
		break;
	default:
		break;
	}
	//显示页眉
	pDC->DrawText(headstring,&rect,DT_TOP|nFlag);
}

void CPrintView::SetFoot(CDC *pDC,CPrintInfo *pInfo,CString footstring,int xPos ,int yPos)
{
	//获取打印机设备的横方向和纵方向的分辨率
	//即每英寸像素点数
	int xPixPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
	int yPixPerInch = pDC->GetDeviceCaps(LOGPIXELSY); 
	//将距打印纸底部的距离转化为物理距离,单位为像素
	int yPositionPix = yPos * yPixPerInch/254;
	//获取可打印区域的高度,单位为像素	
	int h = pDC->GetDeviceCaps(PHYSICALHEIGHT);
	//获取当前打印区域的逻辑坐标范围	
	CRect rect = pInfo->m_rectDraw;
	//逻辑坐标转化为物理坐标
	pDC->LPtoDP(&rect);
	//物理坐标下的页脚范围
	rect.top = rect.bottom;
	rect.bottom = h - yPositionPix;

	pDC->DPtoLP(&rect);
	//设置页脚的水平位置
	int nFlag;
	switch(xPos)
	{
	case 0 :
		nFlag = DT_CENTER;//居中
		break;
	case -1:
		nFlag = DT_LEFT;//靠左
		break;
	case 1:
		nFlag = DT_RIGHT;//靠右
		break;
	default:
		break;
	}
	//显示页脚
	pDC->DrawText(footstring,&rect,DT_BOTTOM|nFlag);
}