下面的程序实现了套打的功能,当然也可以按自己想要的方式打印;同时还实现了打印设备的无关性。
该打印程序源码放在: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和不同纸张大小来验证实验。