基于MFC对话框的报表打印和预览功能第一步:在工程中加入实现打印功能的四个文件PrintFrame.h,PringtView.h,PrintFrame.cpp, PrintView.cppCPrintFrame和CPrintView类是两个个可重用的类,开发者只需要把这两个类对应的四个文件拷贝到工程文件所在目录中(PrintFrame.h,PringtView.h,PrintFrame.cpp, PrintView.cpp),并将这四个文件加入工程,并在需要执行打印功能的代码处加入#include "PrintFrame.h"#include "PrintView.h"第二步:添加三个消息响应函数来执行该功能ON_MESSAGE(WM_BEGIN_PRINTING,OnBeginPrinting)ON_MESSAGE(WM_END_PRINTING,OnEndPrinting)ON_MESSAGE(WM_MY_PRINT,OnMyPrint)这三个消息响应函数放在.cpp文件的BEGIN_MESSAGE_MAP(CReportDlg, CDialog)与END_MESSAGE_MAP()之间,如下:BEGIN_MESSAGE_MAP(CReportDlg, CDialog) //{{AFX_MSG_MAP(CReportDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON1, OnButton1)ON_MESSAGE(WM_BEGIN_PRINTING,OnBeginPrinting)ON_MESSAGE(WM_END_PRINTING,OnEndPrinting)ON_MESSAGE(WM_MY_PRINT,OnMyPrint)ON_BN_CLICKED(IDC_BUTTON2, OnButton2)//}}AFX_MSG_MAPEND_MESSAGE_MAP()其中OnMyPrint是跟具体要打印什么内容有关的开发人员要重点完成的代码,可以打印表格,图片,数据,只要GDI绘图可以进行的操作在这里都可以完成。
由于打印预览的一部分工作在CView类里完成,因此在用户程序中只需要相应WM_MY_PRINT消息就可以执行打印预览的功能,而不需要另外编写打印预览代码。
第三步:建立一个CPrintFrame的对象,设该对象的指针为pFrame,并将对话框的指针传给该对象的m_pCallerDlg,即pFrame->m_pCallerDlg = this;调用对象的Create函数创建框架窗口;例如pFrame->Create(NULL,"频谱打印",WS_OVERLAPPEDWINDOW,CRect(0,0,0,0));如果要执行打印,则调用pFrame->m_pView->OnMyPrint();如果要执行打印预览,则调用:pFrame->m_pView->OnMyPrintPreview();例如:ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview);ON_BN_CLICKED(IDC_PNT, OnPnt);pFrame->m_pCallerDlg->SendMessage(WM_MY_PRINT,(WPARAM) pDC, (LPARAM) pInfo);pFrame->m_pView->OnMyPrintPreview();void CDlgPrintDlg::OnPrint() //执行打印功能{CPrintFrame *pFrame = new CPrintFrame;pFrame->m_pCallerDlg = this;pFrame->Create(NULL,"CurvePrint",WS_OVERLAPPEDWINDOW,CRect(0,0,0,0));pFrame->m_pView->OnMyPrint();}void CDlgPrintDlg::OnPrintPreview() //执行打印预览功能{CPrintFrame *pFrame = new CPrintFrame;pFrame->m_pCallerDlg = this;pFrame->Create(NULL,"Curve PrintPreview",WS_OVERLAPPEDWINDOW,CRect(0,0,0,0));pFrame->m_pView->OnMyPrintPreview();}OnBeginPrinting事例LRESULT 类名::OnBeginPrinting(WPARAM wParam, LPARAM lParam){CDC* pDC = (CDC*)wParam;CPrintInfo* pInfo = (CPrintInfo *)lParam;pInfo->m_pPD ->GetDevMode ()->dmOrientation=1 ;pInfo->SetMaxPage (pagecount);//打印的总页数return TRUE;}OnEndPrinting事例LRESULT 类名::OnEndPrinting(WPARAM wParam, LPARAM lParam){CPrintInfo* pInfo = (CPrintInfo *)lParam;pInfo->m_pPD ->GetDevMode ()->dmOrientation=1 ;return TRUE;}OnMyPrint事例//具体要打印的内容CDC* pDC = (CDC*)wParam;CPrintInfo* pInfo = (CPrintInfo *)lParam;PrintPageHeader(pDC,pInfo->m_nCurPage, pInfo);int nPageNumber = pInfo->m_nCurPage;CFont *pOldFont;CFont font;CSize size;TEXTMETRIC tm;font.CreatePointFont (110,"宋体",pDC);pOldFont=pDC->SelectObject (&font);//选择设备pDC->GetTextMetrics (&tm);int m_width=(pDC->GetDeviceCaps (HORZRES)-3*tm.tmHeight );nPosY+=(int)(0.2*tm.tmHeight );pDC->TextOut ((int)(1.5*tm.tmHeight) ,nPosY," EPC号 "); pDC->TextOut ((int)(1.5*tm.tmHeight+m_width/9*1.6) ,nPosY,"充值前余额 ");pDC->TextOut ((int)(1.5*tm.tmHeight) +m_width/9*3,nPosY,"本次充值金额");pDC->TextOut ((int)(1.5*tm.tmHeight) +m_width/9*4,nPosY,"充值时间 ");nPosY+=(int)(1.2*tm.tmHeight) ;int m_height=(pDC->GetDeviceCaps (VERTRES)-1*tm.tmHeight-nPosY )/48; for(int i=0;i<48;i++){int nPosYtemp=nPosY+m_height*i;CString str=m_List.GetItemText ((nPageNumber-1)*48+i,0);str=str.Right (str.GetLength ()-2);pDC->TextOut ((int)(1.5*tm.tmHeight) ,nPosYtemp,str);pDC->TextOut((int)(1.5*tm.tmHeight+m_width/9*1.6),nPosYtemp,m_List.GetItemText ((nPageNumber-1)*48+i,1));pDC->TextOut ((int)(1.5*tm.tmHeight)+m_width/9*3,nPosYtemp,m_List.GetItemText ((nPageNumber-1)*48+i,2));pDC->TextOut ((int)(1.5*tm.tmHeight)+m_width/9*4,nPosYtemp,m_List.GetItemText ((nPageNumber-1)*48+i,3));}pDC->MoveTo ((int)(1*tm.tmHeight) ,nPosY+m_height*48);pDC->LineTo (pDC->GetDeviceCaps(HORZRES)-(int)(1*tm.tmHeight) ,nPosY+m_height*48);CString strpage="";strpage+="第(";CString str;str.Format ("%d",nPageNumber);strpage+=str;strpage+=")页";font.DeleteObject ();font.CreatePointFont (110,"宋体",pDC);pDC->SelectObject (&font);//选择设备pDC->TextOut (pDC->GetDeviceCaps(HORZRES)-6*tm.tmHeight,(int)(nPosY+m_height*48.2),strpage);pDC->SelectObject (pOldFont);pDC->SelectObject(pOldFont);return TRUE;}PrintPageHeader函数void 类名::PrintPageHeader(CDC *pDC, UINT nPageNumber, CPrintInfo*pInfo){AfxMessageBox("222222");CFont *pOldFont;CFont fontHeader;CPen pen;CPen *pOldPen;pen.CreatePen (PS_SOLID,(int)(5*printxs),RGB(0,0,0));pOldPen=pDC->SelectObject (&pen);fontHeader.CreatePointFont (140,"宋体",pDC);pOldFont=(CFont *)(pDC->SelectObject(&fontHeader));TEXTMETRIC tm;pDC->GetTextMetrics (&tm);nPosY=(int)(0.5*tm.tmHeight) ;CSize sz=pDC->GetTextExtent(strworkname);nPosX=(pDC->GetDeviceCaps (HORZRES)-sz.cx )/2;pDC->TextOut (nPosX,nPosY,strworkname);nPosY+=tm.tmHeight ;fontHeader.DeleteObject ();fontHeader.CreatePointFont (110,"宋体",pDC);pDC->SelectObject(&fontHeader);//绘制用户类型nPosX=tm.tmHeight ;nPosY=nPosY+(int)(0.5*tm.tmHeight );pDC->TextOut(nPosX,nPosY,"用户类型:"+usertype);//绘制姓名nPosX=(pDC->GetDeviceCaps (HORZRES)-2*tm.tmHeight )/3; pDC->TextOut(nPosX,nPosY,"姓名:"+Printname);//绘制打印日期nPosX=(pDC->GetDeviceCaps (HORZRES)-2*tm.tmHeight )/3*2; pDC->TextOut(nPosX,nPosY,"打印日期:"+Printdate);nPosY+=(int)(1.2*tm.tmHeight) ;pDC->GetTextMetrics (&tm);pDC->MoveTo ((int)(1*tm.tmHeight) ,nPosY);pDC->LineTo (pDC->GetDeviceCaps(HORZRES)-(int)(1*tm.tmHeight) ,nPosY);//资源释放pDC->SelectObject(pOldFont);pDC->SelectObject (pOldPen);fontHeader.DeleteObject();pen.DeleteObject ();}。