MFC自定义打印功能

最近做了几个模块的打印功能,在这之前对打印功能不是很了解(更别说理解了),在捣鼓了几天之后,自己总结出了一些东西,以后可做参考。

使用MFC实现打印功能一般在程序会在视图中增加一个打印功能和在对话框中增加打印功能。

第一种,在视图中增加打印功能。

在视图类中增加打印功能,需要实现几个打印功能相关的虚函数,下面列举出来:

	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView);
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)





上面五个虚函数,就是我们在视图类中实现打印功能的关键,我们可以实现打印预览和直接打印功能。

void CYourselfView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	CFormView::OnEndPrinting(pDC, pInfo);
}

void CYourselfView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	CFormView::OnEndPrintPreview(pDC, pInfo, point, pView);
}

BOOL CYourselfView::OnPreparePrinting(CPrintInfo* pInfo) 
{
	// 	if(m_bPreviewMode)/*打印预览,则设置预览模式*/
	// 	{
	//pInfo->m_bPreview = TRUE;
	// 	}
	// 	else/*打印,则设置直接打印模式*/
	// 	{
	pInfo->m_bDirect = TRUE;
	// 	}
	
	return DoPreparePrinting(pInfo);
}

void CYourselfView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
	TRY
	{
		DEVMODE* pDev = pInfo->m_pPD->GetDevMode();/*获取打印设备信息*/
		
		pDC->SetMapMode(MM_TEXT);
		pDC->SetTextColor(RGB(0,0,0));
		
		CRect  rectPaper = pInfo->m_rectDraw;
		double fPHeight = pInfo->m_rectDraw.Height();
		double fPWeight = pInfo->m_rectDraw.Width();
		
		//设置绘制区域
		CRect rect;
		rect.top = rectPaper.top;
		rect.left = rectPaper.left ;
		rect.right = rect.left + long(fPWeight);
		rect.bottom = rect.top + long(fPHeight);
		
		//打印信息
		DrawYourselfInfo(rect,pDC,pInfo);
	}
	CATCH(CException,e)
	{
		return;
	}
	END_CATCH
		
	CFormView::OnPrint(pDC, pInfo);
}

void CYourselfView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) 
{
	/*这里计算打印页数*/
	pInfo->SetMinPage(1);
	pInfo->SetMaxPage(1);//根据内容多少设置最大页数
}





 除了上述五个虚函数之外,我们还需要一个触发打印的函数。

void CYourselfView::OnButtonPrint() 
{
	// TODO: Add your control notification handler code here
	
	//[ 获得打印机相关信息]
	PRINTDLG pd;  //该结构包含打印对话框中的所有信息
	LPDEVMODE  lpDevMode; 
	int nPaperSize = 0;
	if(AfxGetApp()->GetPrinterDeviceDefaults(&pd)) //获得默认的打印机的信息
	{
		lpDevMode=(LPDEVMODE)GlobalLock(pd.hDevMode); 
		if(lpDevMode)
		{   
			//int nQuality = lpDevMode->dmPrintQuality;
			//m_fXCoefficient = (double)(((double)nQuality) / PRINT_DPI_DEFAULT);
		}
		GlobalUnlock(pd.hDevMode);
	}
	
	CFormView::OnFilePrint();
	//如果是打印预览,则注释上一行,开放下一行
	//CFormView::OnFilePrintPreview();
}




 经过上面几个步骤,我们就实现了打印功能。

第二种,在对话框中实现打印功能

由于对话框中没有视图框架类对应打印功能的虚函数(也就是上面说的5个虚函数),但是它的实现更加简单。

假设我们的需求是在对话框中增加一个“打印”按钮,实现打印功能。

void CDlgYourself::OnBtnPrint() 
{
	PRINTDLG pd;
	pd.lStructSize = sizeof(PRINTDLG);
	pd.Flags = PD_RETURNDC;
	pd.hDC = NULL;
	pd.hwndOwner = NULL;
	pd.hInstance = NULL;
	pd.nMaxPage = 1;
	pd.nMinPage = 1;
	pd.nFromPage = 1;
	pd.nToPage = 1;
	pd.nCopies = 1;
	pd.hDevMode = NULL;
	pd.hDevNames = NULL;
 	if(!PrintDlg(&pd)) 
 		return ; 

	ASSERT(pd.hDC!=NULL);
	CDC *pDC=CDC::FromHandle(pd.hDC);
	DOCINFO di;
	di.cbSize = sizeof(DOCINFO);
	di.lpszDocName = "信息打印"; 
	di.lpszOutput = (LPTSTR) NULL; 
	di.lpszDatatype = (LPTSTR) NULL; 
	di.fwType = 0;

	StartDoc(pd.hDC, &di);//启动打印
	for(int i=0;i<(nSize/COUNT_ROW+1);++i)
	{
		m_nCurPrintPage = i+1;//打印的页码
		StartPage(pd.hDC);//开始新的一页
		DrawPrintInfo(pDC);
		EndPage(pd.hDC);//结束新的一页
	}
	EndDoc(pd.hDC);//结束打印

	pDC->DeleteDC(); 
	 
}




 只需要上面一个函数就能实现打印功能,不过中间会弹出标准打印确认框(我暂时没有去了解怎么不让它显示,而直接打印)。

以上总结了两种不同情况下的打印功能实现,可能大家看到其他人写的打印功能和这个不太一样。我现在还没有深入的了解打印功能,这里只是做个记录。

吐槽:做MFC你会发现,同样一个功能,你能在网上找到各种版本,而且他们大部分都能实现你要的功能,但你就是不知道其中的实现缘由!


顺便补充一点,如果我们需要在没有连接打印机的情况下测试打印功能。

可以使用Microsoft XPS document write,这是一个虚拟的打印机,这里假设你已经创建了一个这样的打印机。


然后我们需要自定义一个纸张规格,选择【打印服务器属性】,会弹出一个对话框。


在上面弹出的对话框中设置自定义纸张规格。

然后点击打印机,鼠标右键【打印首选项】,会弹出一个对话框。


在上图中的【高级】里面,选择默认的纸张格式。

然后把打印机设为默认打印机即可。

你可能感兴趣的:(VS)