驾校打印约车小票,使用EPSON MT532打印机。xp系统重装,原来的部署丢失了。需重新配置环境。遇到很多问题,这里综述一下,内网(国内网)能搜到的资料非常有限。官方文档,几乎没有,这里找到几篇文章,可以参考https://bbs.csdn.net/topics/100013356。
安装完应用程序和打印机驱动后,打印机无法打印。找了好多办法,都没有解决。
首先说一下,用的这个打票程序结果也是套牌的机器。自己提供打印机板子,然后用的打印机还是EPSON的。首先简单说下打印机自检的流程。
-
打印机断电,打印机自身有电源,先断电;
-
关机后按住面板上feed(进纸键) 按住后开机 开机也不松手 等到机器打印出来一张纸(显示打印机的连接方式,驱动设置会用,第三行提示接口类型:并口),能完成这一步,证明打印机硬件连接没有问题;
下面的操作需要安装驱动了,因为本质上打印机是EPSON MT532类型,驱动使用EPSON BA-T500 full cut。这个百度可以搜到,就不贴地址。下载安装,先都默认。这里根据SP-CB532搜到时背景一家公司,网上也可以找到操作文档http://www.docin.com/p-91217950.html。
驱动设置按下图操作,安装完驱动需要重启打印机(断电/给电)
驱动安装成功没有需要看一下设备管理,显示打印机端口,如图
然后重启一下打印服务(右键停止服务/右键启用服务),方法如图
然后再DOS窗口可以测试打印服务是否可用,dir > LPT1: 重定向到打印机输出,会打出一张纸(那不是我的手,哈哈)。
然后就可以测试打印,方法,打印机驱动右键-属性-打印测试页,如果一切正常,就可以打印出纸条了,full cut 是自动裁剪的意思,一定长度会自动采集纸条
到这里,打印机硬件连接测试的部分就完成了,然后是通过WinAPI驱动打印机,实现打印。先把源码贴出来,网上粘过来的代码,供参考(我现在也在用)
void CYcInfoPrintDlg::PrintKm2()
{
RECT rect;
rect.left = 50;
rect.right = 580;
rect.top = 0;
rect.bottom = 1000;
RECT rectjl;
rectjl.left = 50;
rectjl.right = 380;
rectjl.top = 130;
rectjl.bottom = 1000;
RECT rectjl1;
rectjl1.left = 50;
rectjl1.right = 380;
rectjl1.top = 140;
rectjl1.bottom = 1000;
RECT rectjl2;
rectjl2.left = 50;
rectjl2.right = 380;
rectjl2.top = 170;
rectjl2.bottom = 1000;
RECT rectjl3;
rectjl3.left = 50;
rectjl3.right = 380;
rectjl3.top = 200;
rectjl3.bottom = 1000;
RECT rectjlbctime;
rectjlbctime.left = 150;
rectjlbctime.right = 380;
rectjlbctime.top = 255;
rectjlbctime.bottom = 1000;
RECT rectxy;
rectxy.left = 50;
rectxy.right = 380;
rectxy.top = 430;
rectxy.bottom = 1000;
RECT rectxy1;
rectxy1.left = 50;
rectxy1.right = 380;
rectxy1.top = 460;
rectxy1.bottom = 1000;
RECT rectxy2;
rectxy2.left = 50;
rectxy2.right = 380;
rectxy2.top = 460;
rectxy2.bottom = 1000;
RECT rectxy22;
rectxy2.left = 50;
rectxy2.right = 380;
rectxy2.top = 490;
rectxy2.bottom = 1000;
RECT rectxy3;
rectxy3.left = 50;
rectxy3.right = 380;
rectxy3.top = 540;
rectxy3.bottom = 1000;
RECT rectxy4;
rectxy4.left = 50;
rectxy4.right = 380;
rectxy4.top = 570;
rectxy4.bottom = 1000;
RECT rectxy5;
rectxy5.left = 50;
rectxy5.right = 380;
rectxy5.top = 635;
rectxy5.bottom = 1000;
RECT rectlog;
rectlog.left = 160;
rectlog.right = 380;
rectlog.top = 900;
rectlog.bottom = 1000;
CString m_all = _T("");
char szprinter[80];
char*szDevice, *szDriver, *szOutput;
HDC hdcprint; // 定义一个设备环境句柄
//定义一个打印作业
static DOCINFO di = { sizeof(DOCINFO), _T("printer"), NULL };
try{
// 得到设备字符串存入数组szprinter
GetProfileStringA("windows", "device", ",,,", szprinter, 80);
// 将设备字符串分解
if (NULL != (szDevice = strtok(szprinter, ",")) && NULL != (szDriver = strtok(NULL, ",")) && NULL != (szOutput = strtok(NULL, ",")))
// 创建一个打印机设备句柄
if ((hdcprint = CreateDCA(szDriver, szDevice, szOutput, NULL)) != 0)
if (StartDoc(hdcprint, &di) > 0)//开始执行一个打印作业
{
StartPage(hdcprint); //打印机走纸,开始打印
SaveDC(hdcprint); //保存打印机设备句柄
HFONT hFont;
hFont = CreateFont(40, 25, 0, 0, FW_NORMAL, false, false, false,
CHINESEBIG5_CHARSET, OUT_CHARACTER_PRECIS,
CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY,
FF_MODERN, _T("宋体"));
// SelectObject(hDC, hFont);
SelectObject(hdcprint, hFont);
m_all = _T("三公驾培信息管理系统\n 畅通驾校约车凭证\n");
DrawText(hdcprint, m_all, -1, &rect, DT_CENTER | DT_VCENTER);
//画直线
HPEN hPen;
HPEN hPenOld;
hPen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
hPenOld = (HPEN)SelectObject(hdcprint, hPen);
MoveToEx(hdcprint, 50, 100, NULL); //线的初始点
LineTo(hdcprint, 500, 100); //线的终点
SelectObject(hdcprint, hPenOld);
//字体
// HFONT hFont;
hPen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
hPenOld = (HPEN)SelectObject(hdcprint, hPen);
hFont = CreateFont(25, 15, 0, 0, FW_NORMAL, false, false, false,
CHINESEBIG5_CHARSET, OUT_CHARACTER_PRECIS,
CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY,
FF_MODERN, _T("宋体"));
// SelectObject(hDC, hFont);
SelectObject(hdcprint, hFont);
//教练
CString m_jlname(m_Student.stjlName.c_str());
CString m_stjlCarnumber(m_Student.stjlCarnumber.c_str());
CString m_stjlPhone(m_Student.stjlPhone.c_str());
CString m_stbcKsDate(m_Student.stbcKsDate.c_str());
CString m_stbcJsDate(m_Student.stbcJsDate.c_str());
CString m_stxySysDate(m_Student.stxySysDate.c_str());
int lenwz = m_stxySysDate.FindOneOf(_T(" "));
CString m_stxRq = m_stxySysDate.Left(lenwz);
//m_all = _T("\n教练姓名:") + m_jlname + _T("\n车牌号码:") + m_stjlCarnumber + _T("\n教练电话:") + m_stjlPhone + _T("\n预约时间段:")+m_stxRq + _T("\n");
m_all = _T("教练姓名:") + m_jlname;
DrawText(hdcprint, m_all, -1, &rectjl, DT_LEFT);
m_all = _T("\n车牌号码:") + m_stjlCarnumber;
DrawText(hdcprint, m_all, -1, &rectjl1, DT_LEFT);
m_all = _T("\n教练电话:") + m_stjlPhone;
DrawText(hdcprint, m_all, -1, &rectjl2, DT_LEFT);
m_all = _T("\n预约时间段:") + m_stxRq;
DrawText(hdcprint, m_all, -1, &rectjl3, DT_LEFT);
CString m_Timebc;
//遍历数组
//int liki = m_info;
//int lin = (sizeof(m_info) / sizeof(m_info[0]));
for (int j = 0; j < 7; j++)
{
m_Timebc += m_info[0][j].c_str();
m_Timebc += "\n";
}
//int lenwz4 = m_Timebc.FindOneOf(_T("\n"));
//m_Timebc = m_Timebc.Left(lenwz4+2);
DrawText(hdcprint, m_Timebc, -1, &rectjlbctime, DT_LEFT);
// pDc->DrawText(m_all, &rectjl, DT_LEFT);
// pDc->DrawText(m_all, -1, &rectjl, DT_LEFT);
//TextOut(hdcprint, 1, 1, m_all, 16);
//printf("测试");
//画直线
// HPEN hPen;
// HPEN hPenOld;
hPen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
hPenOld = (HPEN)SelectObject(hdcprint, hPen);
MoveToEx(hdcprint, 50, 420, NULL); //线的初始点
LineTo(hdcprint, 500, 420); //线的终点
SelectObject(hdcprint, hPenOld);
//学员
CString m_stxyNmae(m_Student.stxyNmae.c_str());
CString m_stxyClassType(m_Student.stxyClassType.c_str());
CString m_stxyEgistrationTime(m_Student.stxyEgistrationTime.c_str());
CString m_stxyLoginTime(m_Student.stxyLoginTime.c_str());
CString m_stxyTotAlhours(m_Student.stxyTotAlhours.c_str());
CString m_stxyRemhours(m_Student.stxyRemhours.c_str());
int lenwz2 = m_stxyEgistrationTime.FindOneOf(_T(" "));
m_stxyEgistrationTime = m_stxyEgistrationTime.Left(lenwz2);
int lenwz3 = m_stxyLoginTime.FindOneOf(_T(" "));
m_stxyLoginTime = m_stxyLoginTime.Left(lenwz3);
m_all = _T("\n学员姓名:") + m_stxyNmae;
DrawText(hdcprint, m_all, -1, &rectxy, DT_LEFT);
m_all = _T("\n班次类型:") + m_stxyClassType;
DrawText(hdcprint, m_all, -1, &rectxy1, DT_LEFT);
m_all = _T("\n报名登录:\n") + m_stxyEgistrationTime + "-" + m_stxyLoginTime;
//m_all = _T("\n报名登录:");
DrawText(hdcprint, m_all, -1, &rectxy2, DT_LEFT);
//m_all = _T("\n")+m_stxyEgistrationTime + "-" + m_stxyLoginTime;
//DrawText(hdcprint, m_all, -1, &rectxy22, DT_LEFT);
m_all = _T("\n学时(剩余/总数):") + m_stxyRemhours + _T("/") + m_stxyTotAlhours;
DrawText(hdcprint, m_all, -1, &rectxy3, DT_LEFT);
m_all = _T("\n打印时间:\n") + m_stxySysDate;
DrawText(hdcprint, m_all, -1, &rectxy4, DT_LEFT);
m_all = _T("\n签字:\n");
DrawText(hdcprint, m_all, -1, &rectxy5, DT_LEFT);
DrawText(hdcprint, m_Timebc, -1, &rectjlbctime, DT_LEFT);
hPen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
hPenOld = (HPEN)SelectObject(hdcprint, hPen);
MoveToEx(hdcprint, 50, 720, NULL); //线的初始点
LineTo(hdcprint, 900, 720); //线的终点
SelectObject(hdcprint, hPenOld);
//打印二维码
CDC dcPrinter; //定义一个设备
dcPrinter.Attach(hdcprint); //把打印机附于这个设备
DrawBmp(&dcPrinter);
hFont = CreateFont(18, 10, 0, 0, FW_NORMAL, false, false, false,
CHINESEBIG5_CHARSET, OUT_CHARACTER_PRECIS,
CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY,
FF_MODERN, _T("宋体"));
SelectObject(hdcprint, hFont);
m_all = _T("\n关注e车事,约车更轻松\n");
DrawText(hdcprint, m_all, -1, &rectlog, DT_LEFT);
RestoreDC(hdcprint, -1); //恢复打印机设备句柄
EndPage(hdcprint); //打印机停纸,停止打印
EndDoc(hdcprint); //结束一个打印作业
SetDlgItemText(IDC_STATIC22, _T("打印完成,请取小票"));
}
}
catch (runtime_error err)
{
if (hdcprint != NULL)
{
RestoreDC(hdcprint, -1); //恢复打印机设备句柄
EndPage(hdcprint); //打印机停纸,停止打印
EndDoc(hdcprint); //结束一个打印作业
}
PrintTest();
}
}
这里有个地方不明白,贴出来
GetProfileStringA("windows", "device", ",,,", szprinter, 80);
这一句提示,从某个配置文件里读信息,属性段是【windows】属性名称【device】,这里在网上搜了一下可能是这个意思
VC下打印机的使用
显示器和打印机、绘图仪都被视为输出设备。系统默认的输出设备是显示器。要使用打印机,首先需要创建一个指向打印机的设备环境句柄,然后通过该句柄调用相关的绘图函数把所需的文字和图形输出至打印机上。当打印结束后,删除这个设备环境句柄即可。
一、技术细节
当我们在Windows95下安装好打印机后,总是需要设置一个为默认打印机,在Windows95的启动配置文件WIN.INI中[window]段中列出了带有关键字device的默认打印机。如果在文件WIN.INI中有如下几行:
[windows]
[其他程序行]
device=EPSON LQ-1600K,EPSON24,LPT1:
在device后的字符串中就包含了系统中默认的打印机的三个重要属性.它们依次是打印机的设备名是LQ-1600K,驱动程序名是EPSON24,输出端口为LPT1。在程序中我们可调用API函数GetProfileString从WIN.INI文件中获得这个设备字符串。再将这个设备字符串进行分解,获得这三个属性,作为参数用API函数CreateDC调用。如果调用成功,则为默认打印机创建一个设备环境句柄,否则返回一个空值(NULL)。
CreateDC函数的原形如下:
HDC CreateDC(
LPCTSTR lpszDriver,
LPCTSTR lpszDevice,
LPCTSTR lpszOutput,
CONST DEVMODE *lpinitData
);
流程走到这里,暂时无法验证,因为没有机器供验证了。后续补全。验证思路,不更新win.ini,直接调用打印程序是否可以打印?如果无法打印,按照格式更新win.ini文件,再次触发打印,是否可以打印。
经过检验,windows.ini配置实用默认就可以,只要驱动安装正确,打印服务已经启动,命令行重定向到打印机可以打印出内容,基本打印机配置就成功了。亲测可用。