#include "stdafx.h" #include "SpHelper.h" #include "ThermalPrintFSM.h" #include "mod_ThermalPrint.h" #include "base64.h" #include "GetDevInfoHelper.h" #include "SpUtility.h" ErrorCodeEnum CThermalPrintFSM::OnInit() { LOG_FUNCTION(); GET_DEV_ENTITY_BASE_POINTER()->InitializeVendorLogSwitch(); ErrorCodeEnum eErrDev = Error_Succeed; CSimpleStringA csDllName(true); auto pEntity = GET_DEV_ENTITY_BASE_POINTER(); eErrDev = pEntity->ExtractVendorLibFullPath(csDllName); //root.ini文件未配置则置热敏打印机不可用,但是实体依然启动 if(eErrDev== Error_NotConfig) { m_bSupportPrint=false;//表示不支持打印 m_bDevOpen=false;//表示dev打开失败 m_pCommandList=NULL; Dbg("Open device failed , thermalPrint is not support print: root.ini param is null"); return Error_Succeed; } if(eErrDev!=Error_Succeed){ Dbg("Fetch Vendor dllName failed %s.", (LPCTSTR)csDllName); return eErrDev; } Dbg("VendorDllName: %s.", (LPCTSTR)csDllName); eErrDev = m_hDevHelper.LoadUp(csDllName); if(eErrDev!=Error_Succeed) { Dbg("LoadUp failed %s.", (LPCTSTR)csDllName); return eErrDev; } Dbg("Get functions' addresses succed."); //获取端口和波特率 eErrDev = FetchOtherParam(); if(eErrDev!=Error_Succeed) { Dbg("FetchOtherParam failed."); m_hDevHelper.TearDown(); return eErrDev; } Dbg("m_port is %d,m_baudrate is %d",m_port,m_baudrate); bool bOpenFlag = false; bool bCreateDevCom = false; int initCount=0, initCountMax = 3; int MilliSleepSec = 1000; do { eErrDev = m_hDevHelper->DevOpen(m_port,m_baudrate); if(eErrDev!=Error_Succeed) { LOG_THERMALPRINT_ERROR_MSG_MACRO(eErrDev, DevOpen); m_hDevHelper.TearDown(); return Error_DevConnFailed; }else{ m_bSupportPrint=true;//表示支持打印 m_bDevOpen=true;//表示dev打开成功 m_pCommandList = new list(); //初始化指令集合 Dbg("Open device succeeded."); eErrDev = Error_Succeed; } } while (0); return eErrDev; } ErrorCodeEnum CThermalPrintFSM::FetchOtherParam() { ErrorCodeEnum erroCode = Error_Unexpect; CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spRootConfig; erroCode = spEntityFunction->OpenConfig(Config_Root, spRootConfig); if(erroCode==Error_Succeed) { CSimpleStringA strSection = CSimpleStringA("Device.") + GetEntityBase()->GetEntityName(); CSimpleStringA str; spRootConfig->ReadConfigValue(strSection, "Port", str); if(!str.IsNullOrEmpty()){ spRootConfig->ReadConfigValueInt(strSection, "Port", m_port); } str.Clear(); spRootConfig->ReadConfigValue(strSection, "Baudrate", str); if(!str.IsNullOrEmpty()){ spRootConfig->ReadConfigValueInt(strSection, "Baudrate", m_baudrate); } } return erroCode; } ErrorCodeEnum CThermalPrintFSM::OnExit() { m_hDevHelper.TearDown(); //清理打印指令 if(m_pCommandList){ ClearPrintCMD(); delete m_pCommandList; } return Error_Succeed; } ErrorCodeEnum CThermalPrintFSM::GetPrintState(int& state , CSimpleStringA& err_msg) { if(m_bDevOpen){ ThermalState thState; if(m_hDevHelper->GetDevState(thState)==Error_Succeed){ Dbg("热敏检查:纸状态 %d , 硬件状态 %d",(int)thState.paperState,(int)thState.hardwareState); if(thState.hardwareState==STATE_OK){ if(thState.paperState==PAPER_FULL){ state=0; }else if(thState.paperState==PAPER_LOW){ state=1; }else if(thState.paperState==PAPER_EMPTY){ state=2; }else if(thState.paperState==PAPER_JAMMED){ state=3; }else{ state=4; err_msg="未知的硬件故障状态"; } }else if(thState.hardwareState==STATE_OTHER_ERROR){ state=4; DevErrorInfo devOpenErrInfo = {0}; ThermalState thermalState; if((m_hDevHelper->GetLastErrState(thermalState,devOpenErrInfo))==Error_Succeed) { err_msg = devOpenErrInfo.szErrMsg; } else { Dbg("device GetDevState failed : GetLastErrState failed."); } }else{ state=4; err_msg="未知的硬件故障状态"; } return Error_Succeed; }else{ DevErrorInfo devOpenErrInfo = {0}; if((m_hDevHelper->GetLastErr(devOpenErrInfo))==Error_Succeed) { Dbg("device GetDevState failed : %s.", devOpenErrInfo.szErrMsg); } else { Dbg("device GetDevState failed : GetLastErr failed."); } return Error_Hardware; } }else{ return Error_DevNotAvailable; } } //解析每条命令 PrintCommand* CThermalPrintFSM::ParseCommand( scew_element *elem ) { PrintCommand* pcd = new PrintCommand(); const char *name = scew_element_name(elem); Dbg("元素名称=%s",name); if(stricmp(name,"common")==0){ scew_attribute *attr1 = scew_element_attribute_by_name(elem, "name"); scew_attribute *attr2 = scew_element_attribute_by_name(elem, "value"); if(attr1&&attr2){ const char *str1 = scew_attribute_value(attr1); const char *str2 = scew_attribute_value(attr2); if(stricmp(str1,"CMD_COMMON_ROW_SPACE")==0){ pcd->eCommandType=CMD_COMMON_ROW_SPACE; pcd->strCommandType="行距"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_COMMON_ALIGN")==0){ pcd->eCommandType=CMD_COMMON_ALIGN; pcd->strCommandType="字符对齐"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_COMMON_REVERSE")==0){ pcd->eCommandType=CMD_COMMON_REVERSE; pcd->strCommandType="颠倒打印"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_COMMON_LEFT_MARGIN")==0){ pcd->eCommandType=CMD_COMMON_LEFT_MARGIN; pcd->strCommandType="左边距"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_COMMON_PRINTABLE_AREA")==0){ pcd->eCommandType=CMD_COMMON_PRINTABLE_AREA; pcd->strCommandType="可打印区域"; pcd->strCommand=str2; }else{ Dbg("common节点name属性值不支持"); goto on_error; } }else{ Dbg("common节点无name或value属性"); goto on_error; } }else if(stricmp(name,"font")==0){ scew_attribute *attr1 = scew_element_attribute_by_name(elem, "name"); scew_attribute *attr2 = scew_element_attribute_by_name(elem, "value"); if(attr1&&attr2){ const char *str1 = scew_attribute_value(attr1); const char *str2 = scew_attribute_value(attr2); if(stricmp(str1,"CMD_FONT_UNDERLINE")==0){ pcd->eCommandType=CMD_FONT_UNDERLINE; pcd->strCommandType="字体下划线"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_FONT_BOLD")==0){ pcd->eCommandType=CMD_FONT_BOLD; pcd->strCommandType="字体加粗"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_FONT_INVERSE")==0){ pcd->eCommandType=CMD_FONT_INVERSE; pcd->strCommandType="字体反白"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_FONT_DOUBLEHEIGHT")==0){ pcd->eCommandType=CMD_FONT_DOUBLEHEIGHT; pcd->strCommandType="字体倍高"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_FONT_DOUBLEWIDE")==0){ pcd->eCommandType=CMD_FONT_DOUBLEWIDE; pcd->strCommandType="字体倍宽"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_FONT_CUSTOM_SIZE")==0){ pcd->eCommandType=CMD_FONT_CUSTOM_SIZE; pcd->strCommandType="字体宽高自定义"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_FONT_ROTATE")==0){ pcd->eCommandType=CMD_FONT_ROTATE; pcd->strCommandType="字体旋转"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_FONT_LEFT_RIGHT_SPACE")==0){ pcd->eCommandType=CMD_FONT_LEFT_RIGHT_SPACE; pcd->strCommandType="字体间隔距离"; pcd->strCommand=str2; }else{ Dbg("font节点name属性值不支持"); goto on_error; } }else{ Dbg("font节点无name或value属性"); goto on_error; } }else if(stricmp(name,"action")==0){ scew_attribute *attr1 = scew_element_attribute_by_name(elem, "name"); scew_attribute *attr2 = scew_element_attribute_by_name(elem, "value"); if(attr1&&attr2){ const char *str1 = scew_attribute_value(attr1); const char *str2 = scew_attribute_value(attr2); if(stricmp(str1,"CMD_ACTION_PRINT_ONE_LINE")==0){ pcd->eCommandType=CMD_ACTION_PRINT_ONE_LINE; pcd->strCommandType="打印走纸一行"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_ACTION_PRINT_MOVEFORWRAD_LINES")==0){ pcd->eCommandType=CMD_ACTION_PRINT_MOVEFORWRAD_LINES; pcd->strCommandType="打印走纸N行"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_ACTION_PRINT_MOVEBACKWRAD_LINES")==0){ pcd->eCommandType=CMD_ACTION_PRINT_MOVEBACKWRAD_LINES; pcd->strCommandType="打印回纸N行"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_ACTION_CUT_ALL")==0){ pcd->eCommandType=CMD_ACTION_CUT_ALL; pcd->strCommandType="全切纸"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_ACTION_CUT_HALF")==0){ pcd->eCommandType=CMD_ACTION_CUT_HALF; pcd->strCommandType="半切纸"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_ACTION_MOVE_TO_POSITION_RELATIVE")==0){ pcd->eCommandType=CMD_ACTION_MOVE_TO_POSITION_RELATIVE; pcd->strCommandType="横向移动"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_ACTION_MOVE_TO_FORWRAD_LENGTH")==0){ pcd->eCommandType=CMD_ACTION_MOVE_TO_FORWRAD_LENGTH; pcd->strCommandType="纵向移动"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_ACTION_MOVE_TO_BLACKMARK")==0){ pcd->eCommandType=CMD_ACTION_MOVE_TO_BLACKMARK; pcd->strCommandType="移动到黑标位置"; pcd->strCommand=str2; }else if(stricmp(str1,"CMD_ACTION_PRINT_MOVEBACK_TO_LINE")==0){ pcd->eCommandType=CMD_ACTION_PRINT_MOVEBACK_TO_LINE; pcd->strCommandType="移动到行首"; pcd->strCommand=str2; }else{ Dbg("action节点name属性值不支持"); goto on_error; } }else{ Dbg("action节点无name或value属性"); goto on_error; } }else if(stricmp(name,"text")==0){ scew_attribute *attr1 = scew_element_attribute_by_name(elem, "base64"); scew_attribute *attr2 = scew_element_attribute_by_name(elem, "value"); if(attr1&&attr2){ const char *str1 = scew_attribute_value(attr1); const char *str2 = scew_attribute_value(attr2); if(stricmp(str1,"0")==0 && strlen(str2)>0){ Dbg("解析出来的内容:%s",str2); pcd->eCommandType=CMD_PRINT_TEXT; pcd->strCommandType="文本内容"; //utf8转码,为测试使用,不测试时不需要转码 #ifdef RVC_OS_WIN char* gbkstr = ConvertUtf8ToGBK((char*)str2); Dbg("解析出来的文本:%s",gbkstr); //转义字符 pcd->strCommand = decodeXmlContent((const char*)gbkstr); delete[] gbkstr; Dbg("转义出来的内容:%s",pcd->strCommand.GetData()); #else Dbg("解析出来的文本:%s", str2); //转义字符 pcd->strCommand = decodeXmlContent(str2); Dbg("转义出来的内容:%s", pcd->strCommand.GetData()); #endif // RVC_OS_WIN }else if(stricmp(str1,"1")==0 && strlen(str2)>0){ pcd->eCommandType=CMD_PRINT_TEXT; pcd->strCommandType="文本内容"; //base64特殊处理:注意业务传送过来的是utf8格式编码的base64, CSimpleStringA decodeStr=decodeBase64Content(str2); if(decodeStr.GetLength()==0){ Dbg("text节点value属性解码失败"); goto on_error; }else{ //Dbg("base64解码出来的内容:%s",decodeStr.GetData()); #ifdef RVC_OS_WIN char* gbkstr = ConvertUtf8ToGBK((char*)decodeStr.GetData());//windows机用GBK编码 //Dbg("base64解码出来的内容:%s",gbkstr); pcd->strCommand = gbkstr; delete[] gbkstr; #else pcd->strCommand = decodeStr; #endif // RVC_OS_WIN } }else{ Dbg("text节点base64属性值不支持或者value属性值为空"); goto on_error; } }else{ Dbg("text节点无base64或value属性"); goto on_error; } }else if(stricmp(name,"image")==0){ scew_attribute *attr2 = scew_element_attribute_by_name(elem, "value"); if(attr2){ const char *str2 = scew_attribute_value(attr2); if(strlen(str2)>0){ pcd->eCommandType=CMD_PRINT_IMAGE; pcd->strCommandType="图片内容"; pcd->strCommand=str2; }else{ Dbg("image节点value属性值为空"); goto on_error; } }else{ Dbg("image节点无value属性"); goto on_error; } }else if(stricmp(name,"barcode")==0){ scew_attribute *attr1 = scew_element_attribute_by_name(elem, "type"); scew_attribute *attr2 = scew_element_attribute_by_name(elem, "value"); scew_attribute *attr3 = scew_element_attribute_by_name(elem, "param"); if(attr1&&attr2&&attr3){ const char *str1 = scew_attribute_value(attr1); const char *str2 = scew_attribute_value(attr2); const char *str3 = scew_attribute_value(attr3); if(strlen(str1)>0&& strlen(str2)>0&&strlen(str3)>0){ pcd->eCommandType=CMD_PRINT_BARCODE; pcd->strCommandType="条形码"; pcd->eBarcodeType=(BarCodeType)atoi(str1); pcd->strCommand=str2; pcd->strParam=str3; }else{ Dbg("barcode节点param或value或type属性值为空"); goto on_error; } }else{ Dbg("barcode节点无param或value或type属性"); goto on_error; } }else if(stricmp(name,"QRcode")==0){ scew_attribute *attr1 = scew_element_attribute_by_name(elem, "type"); scew_attribute *attr2 = scew_element_attribute_by_name(elem, "value"); scew_attribute *attr3 = scew_element_attribute_by_name(elem, "param"); if(attr1&&attr2&&attr3){ const char *str1 = scew_attribute_value(attr1); const char *str2 = scew_attribute_value(attr2); const char *str3 = scew_attribute_value(attr3); if(strlen(str1)>0&& strlen(str2)>0&&strlen(str3)>0){ pcd->eCommandType=CMD_PRINT_QR; pcd->strCommandType="二维码"; pcd->eQRcodeType=(QRCodeType)atoi(str1); //base64特殊处理 CSimpleStringA decodeStr=decodeBase64Content(str2); if(decodeStr.GetLength()==0){ Dbg("QRcode节点value属性解码失败"); goto on_error; }else{ pcd->strCommand=decodeStr; } pcd->strParam=str3; }else{ Dbg("QRcode节点param或value或type属性值为空"); goto on_error; } }else{ Dbg("QRcode节点无param或value或type属性"); goto on_error; } }else{ Dbg("%s节点不支持",name); goto on_error; } return pcd; on_error: if (pcd) { free(pcd); } return NULL; } CSimpleStringA CThermalPrintFSM::decodeBase64Content( const char* str ) { CSimpleStringA decodeStr=""; int decodeLen = base64_decode_len(str); char* decodeByte = new char[decodeLen]; memset(decodeByte,0,decodeLen); if( base64_decode(decodeByte,str)){ decodeStr = decodeByte; } delete decodeByte; return decodeStr; } CSimpleStringA CThermalPrintFSM::decodeXmlContent(const char* str) { CSimpleStringA decodeStr=str; decodeStr = replaceXmlContent(decodeStr, "<", "<"); decodeStr = replaceXmlContent(decodeStr, ">", ">"); decodeStr = replaceXmlContent(decodeStr, "'", "\'"); decodeStr = replaceXmlContent(decodeStr, """, "\""); decodeStr = replaceXmlContent(decodeStr, "&", "&"); return decodeStr; } CSimpleStringA CThermalPrintFSM::replaceXmlContent(CSimpleStringA& str,const char* regex,const char* replacement) { if(str.IsNullOrEmpty()){ return str; } int index; index = str.IndexOf(regex); CSimpleStringA strNew=""; if (index >= 0) { while (index >= 0) { strNew += str.SubString(0,index)+replacement; str = str.SubString(index + strlen(regex)); index = str.IndexOf(regex); } strNew += str; return strNew; } return str; } ErrorCodeEnum CThermalPrintFSM::ParsePrintXml( CSimpleStringA xml ) { ErrorCodeEnum ret = Error_Succeed; scew_reader *reader = NULL; scew_parser *parser = NULL; scew_tree *tree = NULL; scew_element *root = NULL; //????这个如何delete scew_list* lst = NULL; int count = 0; reader = scew_reader_buffer_create(xml.GetData(),xml.GetLength()); if (!reader) { Dbg("create scew buffer reader!"); ret = Error_Exception; goto on_error; } parser = scew_parser_create(); tree = scew_parser_load(parser, reader); if (!tree) { scew_error code = scew_error_code(); if (code == scew_error_expat) { enum XML_Error expat_code = scew_error_expat_code(parser); Dbg("scew parse error:%d, line:%d column:%d %s", expat_code, scew_error_expat_line(parser), scew_error_expat_column(parser), scew_error_expat_string(expat_code)); } Dbg("parser xml failed! xml=[%s]", xml.GetData()); ret = Error_Exception; goto on_error; } root = scew_tree_root(tree); if (!root) { Dbg("does not have root element!xml=[%s]", xml.GetData()); ret = Error_Exception; goto on_error; } lst = scew_element_children(root); count =scew_list_size(lst); Dbg("共有%d行命令",count); if (lst) { for (scew_list *it = scew_list_first(lst); it; it = scew_list_next(it)) { scew_element* elem = (scew_element*)scew_list_data(it); PrintCommand* command = ParseCommand(elem); if (command) { m_pCommandList->push_back(command); } else { ret = Error_Exception; Dbg("parse xml object failed!"); break; } } } on_error: if (tree) { scew_tree_free(tree); } if (parser) { scew_parser_free(parser); } if (reader) { scew_reader_close(reader); } return ret; } void CThermalPrintFSM::OnStateTrans( int iSrcState, int iDstState ) { Dbg("[ThermalPrintFSM] State trans from %d to %d!", iSrcState, iDstState); } void CThermalPrintFSM::s0_on_entry() { LOG_FUNCTION(); ScheduleTimer(1, 5000); //清理s1,s2遗留下来的打印指令 ClearPrintCMD(); } void CThermalPrintFSM::s0_on_exit() { LOG_FUNCTION(); CancelTimer(1); } unsigned int CThermalPrintFSM::s0_on_event( FSMEvent* e ) { //LOG_FUNCTION(); switch(e->iEvt) { case EVT_TIMER: ScheduleTimer(1, 5000); e->SetHandled(); break; case USER_EVT_PRINT: //打开闪灯 LogEvent(Severity_Middle, LOG_EVT_THERMAL_PRINTER_GREEN_ON, "ThermalPrint light is on."); m_bHasPrintTask = true; e->SetHandled(); break; case USER_EVT_QUIT: e->SetHandled(); LOG_TRACE("s0 on event quit"); break; default: break; } return 0; } void CThermalPrintFSM::s1_on_entry() { LOG_FUNCTION(); //检查打印机状态 PreCheckPrinterTask* task = new PreCheckPrinterTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } void CThermalPrintFSM::s1_on_exit() { LOG_FUNCTION(); } unsigned int CThermalPrintFSM::s1_on_event( FSMEvent* e ) { int ret = 0; switch(e->iEvt) { case USER_EVT_PRECHECK_FINISHED: e->SetHandled(); ret = e->param1; Dbg("ret = %d",e->param1); if(ret!=0){ //预检查失败 //关闭闪灯,等待一段时间 Sleep(3000); LogEvent(Severity_Middle, LOG_EVT_THERMAL_PRINTER_GREEN_OFF, "ThermalPrint light is off."); Dbg("PreCheckPrinter is fail : errorcode [%s] , errormsg [%s]", m_errCode.GetData() ,m_errMsg.GetData()); Dbg("print is fail.************************************************************"); OnPreCheckFailed(); m_bHasPrintTask=false; } break; default: break; } return ret; } void CThermalPrintFSM::s2_on_entry() { LOG_FUNCTION(); PrintTask* task = new PrintTask(this); GetEntityBase()->GetFunction()->PostThreadPoolTask(task); } void CThermalPrintFSM::s2_on_exit() { LOG_FUNCTION(); } unsigned int CThermalPrintFSM::s2_on_event( FSMEvent* e ) { int ret = 0; switch(e->iEvt) { case USER_EVT_PRINT_FINISHED: e->SetHandled(); ret = e->param1; //关闭闪灯,等待一段时间 Sleep(3000); LogEvent(Severity_Middle, LOG_EVT_THERMAL_PRINTER_GREEN_OFF, "ThermalPrint light is off."); if(ret==1){ //打印失败 OnPrintFailed(); Dbg("Print is fail.************************************************************"); //打印具体错误 DevErrorInfo devOpenErrInfo = {0}; ThermalState thermalState; CSimpleStringA err_msg=""; if((m_hDevHelper->GetLastErrState(thermalState,devOpenErrInfo))==Error_Succeed) { err_msg = devOpenErrInfo.szErrMsg; Dbg("Print is fail :[%s],ThermalPaperState is %d ,ThermalHardwareState is %d ",err_msg.GetData(),thermalState.paperState,thermalState.hardwareState); } else { Dbg("Print failed : GetLastErrState failed."); } //需要reset一次 if(m_hDevHelper->Reset()!=Error_Succeed){ DevErrorInfo devOpenErrInfo = {0}; if((m_hDevHelper->GetLastErr(devOpenErrInfo))==Error_Succeed) { Dbg("Reset failed : [%s]", devOpenErrInfo.szErrMsg); } else { Dbg("Reset failed : GetLastErr failed."); } }else{ Dbg("reset success!"); } }else{ //打印成功 OnPrintSucc(); Dbg("Print is OK.************************************************************"); } m_bHasPrintTask=false; break; default: break; } return ret; } void CThermalPrintFSM::OnPreCheckFailed() { // 广播给业务,发送任务失败 PrintResult evt; evt.uuid = CSimpleStringA2W(m_PrintTaskUUID); evt.print_Result=1; evt.error_code = CSimpleStringA2W(m_errCode); evt.error_msg = CSimpleStringA2W(m_errMsg); SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(PrintResult), SP_MSG_SIG_OF(PrintResult), evt); } void CThermalPrintFSM::OnPrintFailed() { // 广播给业务,发送任务失败 PrintResult evt; evt.uuid = CSimpleStringA2W(m_PrintTaskUUID); evt.print_Result=1; evt.error_code = CSimpleStringA2W(m_errCode); evt.error_msg = CSimpleStringA2W(m_errMsg); SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(PrintResult), SP_MSG_SIG_OF(PrintResult), evt); } void CThermalPrintFSM::OnPrintSucc() { // 广播给业务,发送任务失败 PrintResult evt; evt.uuid = CSimpleStringA2W(m_PrintTaskUUID); evt.print_Result=0; evt.error_code = L""; evt.error_msg = L""; SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(PrintResult), SP_MSG_SIG_OF(PrintResult), evt); } //预检查实现 int CThermalPrintFSM::PreCheckPrinter() { if(m_bDevOpen){ ThermalState thState; if(m_hDevHelper->GetDevState(thState)==Error_Succeed){ Dbg("打印预检查:纸状态 %d , 硬件状态 %d",(int)thState.paperState,(int)thState.hardwareState); if(thState.hardwareState==STATE_OK){ if(thState.paperState==PAPER_FULL){ return 0; }else if(thState.paperState==PAPER_LOW){ m_errCode=Error_Paper_low; m_errMsg="凭条打印机少纸"; LogWarn(Severity_Middle,Error_Unexpect,LOG_ERR_THERMAL_PRINTER_PAPER_LOW,"thermal print paper low."); return 0; }else if(thState.paperState==PAPER_EMPTY){ m_errCode=Error_Paper_empty; m_errMsg="凭条打印机缺纸"; LogWarn(Severity_Middle,Error_Unexpect,LOG_ERR_THERMAL_PRINTER_PAPER_EMPTY,"thermal print paper empty."); return 1; }else if(thState.paperState==PAPER_JAMMED){ m_errCode=Error_Paper_jammed; m_errMsg="凭条打印机卡纸"; LogWarn(Severity_Middle,Error_Unexpect,LOG_ERR_THERMAL_PRINTER_PAPER_JAMMED,"thermal print paper jammed."); return 1; }else{ m_errCode=Error_PreCheckPrint; m_errMsg="凭条打印机硬件故障:故障码未知"; LogWarn(Severity_Middle,Error_Unexpect,LOG_ERR_THERMAL_PRINTER_OTHER_DEV_FAULT,"thermal print other dev fault undefined."); return 1; } }else if(thState.hardwareState==STATE_OTHER_ERROR){ DevErrorInfo devOpenErrInfo = {0}; ThermalState thermalState; CSimpleStringA err_msg=""; if((m_hDevHelper->GetLastErrState(thermalState,devOpenErrInfo))==Error_Succeed) { err_msg = devOpenErrInfo.szErrMsg; } else { Dbg("device GetDevState failed : GetLastErrState failed."); } m_errCode=Error_OtherDevFault; m_errMsg="凭条打印机硬件故障:"; m_errMsg.Append(err_msg); LogWarn(Severity_Middle,Error_Unexpect,LOG_ERR_THERMAL_PRINTER_OTHER_DEV_FAULT,"thermal print other dev fault."); return 1; }else{ m_errCode=Error_PreCheckPrint; m_errMsg="凭条打印机硬件故障:故障码未知"; LogWarn(Severity_Middle,Error_Unexpect,LOG_ERR_THERMAL_PRINTER_OTHER_DEV_FAULT,"thermal print other dev fault undefined."); return 1; } }else{ DevErrorInfo devOpenErrInfo = {0}; if((m_hDevHelper->GetLastErr(devOpenErrInfo))==Error_Succeed) { Dbg("device GetDevState failed : %s.", devOpenErrInfo.szErrMsg); } else { Dbg("device GetDevState failed : GetLastErr failed."); } m_errCode=Error_PreCheckPrint; m_errMsg="调用热敏适配器GetDevState方法失败"; return 1; } }else{ m_errCode=Error_DevNotOpen; m_errMsg="厂商设备还未打开"; return 1; } } //打印实现 int CThermalPrintFSM::Print() { if(m_bDevOpen){ //开始调用beginPrint if(m_hDevHelper->BeginPrint(m_paperType,m_paperWidth)!=Error_Succeed){ //失败 m_errCode=Error_Print; m_errMsg="调用热敏适配器BeginPrint方法失败"; return 1; } //循环调用打印命令 bool isOK =true; CSimpleStringA strCMD; list::iterator iter; for(iter=m_pCommandList->begin();iter!=m_pCommandList->end();++iter){ PrintCommand* cmd= *iter; if(cmd){ strCMD = cmd->strCommandType; //执行单个命令 if(ExecutePrintCMD(cmd)!=Error_Succeed){ Dbg("执行%s命令失败",strCMD.GetData()); //尝试把可能执行了一半的错误纸张吐出来,以免影响后面的任务 m_hDevHelper->ControlAction(ACTION_CUT_ALL,1); isOK=false; break; } }else{ strCMD="null"; isOK=false; break; } } if(isOK){ return 0; }else{ m_errCode=Error_Print; m_errMsg="凭条打印机打印失败"; return 1; } }else{ m_errCode=Error_DevNotOpen; m_errMsg="厂商设备还未打开"; return 1; } } int CThermalPrintFSM::ExecutePrintCMD(PrintCommand* cmd) { //针对不同的指令调不同的打印命令 if(cmd->eCommandType<10){ //CommandType return ExecuteParamCMD(cmd); }else if(cmd->eCommandType>=10&&cmd->eCommandType<100){ //FontStyle return ExecuteFontCMD(cmd); }else if(cmd->eCommandType>=100&&cmd->eCommandType<200){ //PrintAction return ExecuteActionCMD(cmd); }else if(cmd->eCommandType>=200){ //printImage or QR return ExecuteImageCMD(cmd); } } int CThermalPrintFSM::ExecuteParamCMD(PrintCommand* cmd){ DWORD value1=0; DWORD value2=0; if(cmd->eCommandType==CMD_COMMON_ROW_SPACE){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetParam(COMMON_ROW_SPACE,value1); }else if(cmd->eCommandType==CMD_COMMON_ALIGN){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetParam(COMMON_ALIGN,value1); }else if(cmd->eCommandType==CMD_COMMON_REVERSE){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetParam(COMMON_REVERSE,value1); }else if(cmd->eCommandType==CMD_COMMON_LEFT_MARGIN){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetParam(COMMON_LEFT_MARGIN,value1); }else if(cmd->eCommandType==CMD_COMMON_PRINTABLE_AREA){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetParam(COMMON_PRINTABLE_AREA,value1); }else { Dbg("打印命令不存在"); return Error_Exception; } } int CThermalPrintFSM::ExecuteFontCMD(PrintCommand* cmd){ DWORD value1=0; DWORD value2=0; if(cmd->eCommandType==CMD_FONT_UNDERLINE){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetFont(FONT_UNDERLINE,value1); }else if(cmd->eCommandType==CMD_FONT_BOLD){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetFont(FONT_BOLD,value1); }else if(cmd->eCommandType==CMD_FONT_INVERSE){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetFont(FONT_INVERSE,value1); }else if(cmd->eCommandType==CMD_FONT_DOUBLEHEIGHT){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetFont(FONT_DOUBLEHEIGHT,value1); }else if(cmd->eCommandType==CMD_FONT_DOUBLEWIDE){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetFont(FONT_DOUBLEWIDE,value1); }else if(cmd->eCommandType==CMD_FONT_CUSTOM_SIZE){ //2个参数 CAutoArray valueArray =cmd->strCommand.Split('|'); if (valueArray.GetCount() != 2) { Dbg("CMD_FONT_CUSTOM_SIZE 参数错误:%s",cmd->strCommand.GetData()); return Error_Exception; } value1 = (DWORD)atoi((LPCTSTR)valueArray[0]); value2 = (DWORD)atoi((LPCTSTR)valueArray[1]); return m_hDevHelper->SetFont(FONT_CUSTOM_SIZE,value1,value2); }else if(cmd->eCommandType==CMD_FONT_ROTATE){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetFont(FONT_ROTATE,value1); }else if(cmd->eCommandType==CMD_FONT_LEFT_RIGHT_SPACE){ //暂时只支持一个参数,参数只有右边距 value2=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->SetFont(FONT_LEFT_RIGHT_SPACE,0,value2); }else { Dbg("打印命令不存在"); return Error_Exception; } } int CThermalPrintFSM::ExecuteActionCMD(PrintCommand* cmd){ DWORD value1=0; DWORD value2=0; if(cmd->eCommandType==CMD_ACTION_PRINT_ONE_LINE){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->ControlAction(ACTION_PRINT_ONE_LINE,value1); }else if(cmd->eCommandType==CMD_ACTION_PRINT_MOVEFORWRAD_LINES){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->ControlAction(ACTION_PRINT_MOVEFORWRAD_LINES,value1); }else if(cmd->eCommandType==CMD_ACTION_PRINT_MOVEBACKWRAD_LINES){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->ControlAction(ACTION_PRINT_MOVEBACKWRAD_LINES,value1); }else if(cmd->eCommandType==CMD_ACTION_CUT_ALL){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->ControlAction(ACTION_CUT_ALL,value1); }else if(cmd->eCommandType==CMD_ACTION_CUT_HALF){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->ControlAction(ACTION_CUT_HALF,value1); }else if(cmd->eCommandType==CMD_ACTION_MOVE_TO_POSITION_RELATIVE){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->ControlAction(ACTION_MOVE_TO_POSITION_RELATIVE,value1); }else if(cmd->eCommandType==CMD_ACTION_MOVE_TO_FORWRAD_LENGTH){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->ControlAction(ACTION_MOVE_TO_FORWRAD_LENGTH,value1); }else if(cmd->eCommandType==CMD_ACTION_MOVE_TO_BLACKMARK){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->ControlAction(ACTION_MOVE_TO_BLACKMARK,value1); }else if(cmd->eCommandType==CMD_ACTION_PRINT_MOVEBACK_TO_LINE){ value1=(DWORD)atoi(cmd->strCommand); return m_hDevHelper->ControlAction(ACTION_PRINT_MOVEBACK_TO_LINE,value1); }else { Dbg("打印命令不存在"); return Error_Exception; } } int CThermalPrintFSM::ExecuteImageCMD(PrintCommand* cmd){ if(cmd->eCommandType==CMD_PRINT_IMAGE){ Dbg("要打印的图片长度:%d",cmd->strCommand.GetLength()); //int ilen = cmd->strCommand.GetLength(); //int begin=0; //while(beginstrCommand.SubString(begin,1000); // }else{ // str1 = cmd->strCommand.SubString(begin,ilen); // } // Dbg("要打印的图片内容:%s",str1.GetData());//内容超长分批打印 // begin=begin+1000; //} BYTE* data = (BYTE*)cmd->strCommand.GetData(); DWORD len = (DWORD)cmd->strCommand.GetLength(); return m_hDevHelper->PrintImage(data,len); }else if(cmd->eCommandType==CMD_PRINT_TEXT){ //Dbg("要打印的文本长度:%d",cmd->strCommand.GetLength()); //Dbg("要打印的文本内容:%s",cmd->strCommand.GetData()); BYTE* data = (BYTE*)cmd->strCommand.GetData(); DWORD len = (DWORD)cmd->strCommand.GetLength(); return m_hDevHelper->PrintText(data,len); }else if(cmd->eCommandType==CMD_PRINT_BARCODE){ //3个参数 //CAutoArray valueArray =cmd->strParam.Split('|'); //if (valueArray.GetCount() != 3) //{ // Dbg("CMD_PRINT_BARCODE 参数错误:%s",cmd->strParam.GetData()); // return Error_Exception; //} //BarCodeType eType = cmd->eBarcodeType; //BYTE* data = (BYTE*)cmd->strCommand.GetData(); //DWORD len = (DWORD)cmd->strCommand.GetLength(); //DWORD unitWidth = (DWORD)atoi((LPCTSTR)valueArray[0]); //DWORD height =(DWORD)atoi((LPCTSTR)valueArray[1]); //HriPosition position =(HriPosition)atoi((LPCTSTR)valueArray[2]); //return m_hDevHelper->PrintBarCode(eType,data,len,unitWidth,height,position); Dbg("CMD_PRINT_BARCODE 打印命令暂不支持"); return Error_Exception; }else if(cmd->eCommandType==CMD_PRINT_QR){ Dbg("CMD_PRINT_QR 打印命令暂不支持"); return Error_Exception; }else { Dbg("打印命令不存在"); return Error_Exception; } } void CThermalPrintFSM::ClearPrintCMD() { if(m_pCommandList){ //循环删除里面的对象 list::iterator iter; for(iter=m_pCommandList->begin();iter!=m_pCommandList->end();++iter){ PrintCommand* cmd= *iter; delete cmd; } //清空集合 m_pCommandList->clear(); } } char* CThermalPrintFSM::ConvertUtf8ToGBK(char* strUtf8) { #if defined(RVC_OS_WIN) int len = MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, NULL, 0); WCHAR* wszGBK = new WCHAR[len + 1]; memset(wszGBK, 0, len * 2 + 2); MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, wszGBK, len); len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); char* szGBK = new char[len + 1]; memset(szGBK, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); delete[] wszGBK; return szGBK; #else std::string str(strUtf8); std::string result = SP::Utility::UTF8ToGBK(str); const int len = result.length(); char* szGBK = new char[len + 1]; memset(szGBK, 0, len + 1); strcpy(szGBK, result.c_str()); return szGBK; #endif //RVC_OS_WIN }