VC下如何实现套打的工具(如打印票据中的空白项)?

下面的程序实现了套打的功能,当然也可以按自己想要的方式打印;同时还实现了打印设备的无关性。

该打印程序源码放在:http://download.csdn.net/detail/dijkstar/4667098

上面链接里同时还放了一个TinyPDF,供没有真实打印机的朋友使用。


程序的思路非常简单,使用CPrintDialog建立起一个标准打印对话框,点击确定后,在最上面和左边打印位置字符串,如图:

VC下如何实现套打的工具(如打印票据中的空白项)?_第1张图片

有了这些位置,后面就可以和要打印的纸张对比(对着灯光或太阳),很容易定位到打印处。下面是实现的代码(整个程序就一个函数):

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和不同纸张大小来验证实验。


你可能感兴趣的:(null,工具,float)