下面的程序实现了套打的功能,当然也可以按自己想要的方式打印;同时还实现了打印设备的无关性。
该打印程序源码放在:http://download.csdn.net/detail/dijkstar/4667098
上面链接里同时还放了一个TinyPDF,供没有真实打印机的朋友使用。
程序的思路非常简单,使用CPrintDialog建立起一个标准打印对话框,点击确定后,在最上面和左边打印位置字符串,如图:
有了这些位置,后面就可以和要打印的纸张对比(对着灯光或太阳),很容易定位到打印处。下面是实现的代码(整个程序就一个函数):
void CTestDlg::OnButton1() { // TODO: Add your control notification handler code here CFont fontSmall; CPen penBold; CPrintDialog dlgPrint(FALSE);//标准打印对话框 if(dlgPrint.DoModal() == IDOK) { HDC hPrintDC; try { hPrintDC = dlgPrint.CreatePrinterDC(); } catch(...) { AfxMessageBox("无法建立打印机设备环境句柄。\n请重新设置打印机。", MB_OK | MB_ICONWARNING); hPrintDC = NULL; } CDC PrintDC; if (hPrintDC && PrintDC.Attach(hPrintDC)) { PrintDC.m_bPrinting = TRUE; PrintDC.SetMapMode(MM_TEXT); //映射为“文本”方式:坐标原点在左上角,y轴向下,x轴向右 PrintDC.StartDoc("打印报告"); int nVertRes = PrintDC.GetDeviceCaps(VERTRES); //单位为dots int nVertSize = (int)((float)PrintDC.GetDeviceCaps(VERTSIZE) * 1440 / 25.4);//单位为twips,这里意思是:获取垂直方向上多少个twips int nHorzRes = PrintDC.GetDeviceCaps(HORZRES); //单位为dots int nHorzSize = (int)((float)PrintDC.GetDeviceCaps(HORZSIZE) * 1440 / 25.4);//水平方向上的twips数? float fMapRatioV = (float)nVertRes / nVertSize;//建立【像素】与【毫米】之间的垂直方向的映射关系 float fMapRatioH = (float)nHorzRes / nHorzSize;//水平方向 float cxFont = (105 * fMapRatioH);//自定义一种字体,规定它的高和宽 float cyFont = (210 * fMapRatioV); float cyLine = cyFont / 3.0;//间距(可选) //按自定义的字体高和宽,创建为一种字体 fontSmall.CreateFont(cyFont, cxFont, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "宋体"); CFont *pOldFont = PrintDC.SelectObject(&fontSmall); float xNums = nHorzRes/cxFont; //计算水平上的行数 float yNums = nVertRes/cyFont; //计算垂直上的列数 PrintDC.StartPage(); int i = 0; CString str; // // 在页面最上面打印水平上的"01234567890123456789............" // for (i=0; i<xNums; i++) { str.Format("%d", i%10); PrintDC.TextOut(cxFont*i, 0, str); //顺便把“列竖线”画出来 if (i%10 == 0) { PrintDC.MoveTo(cxFont*i, 0); PrintDC.LineTo(cxFont*i, nVertRes); } } // // 在页面最左边面打印垂直"01234567890123456789............" // for (i=0; i<yNums; i++) { str.Format("%d", i%10); PrintDC.TextOut(0, (cyFont+0)*i, str); //顺便把“行横线”画出来 if (i%10 == 0) { PrintDC.MoveTo(0, (cyFont+0)*i); PrintDC.LineTo(nHorzRes, (cyFont+0)*i); } } //前面垂直打印第一列字符时,将画的第一列竖线擦掉了,重新画该竖线 { PrintDC.MoveTo(0, 0); PrintDC.LineTo(0, nVertRes); } // // 通过上面功能找好了位置,下面开始你自己的打印 // //........................................ //释放 PrintDC.SelectObject(pOldFont); PrintDC.EndPage(); PrintDC.EndDoc(); PrintDC.Detach(); } } }
上面的程序已经找好了打印位置,分别是(cxFont,cyFont),后面该怎么做,不用多说了吧。
注意程序里建立【像素】和真实【毫米】之间关系的代码,通过那段程序,实现了不同纸张格式,不同的DPI打印机下“所见所得”,若不相信,自己通过TinyPDF的设置不同的DPI和不同纸张大小来验证实验。