驱动、串口、网络处理打印机
一、驱动打印
主要参数:打印机名称,Y坐标 ,相当于通过DC在窗口上绘制
1、根据打印机名称创建打印机DC
HDC CreateDC( LPCTSTR lpszDriver, // driver name LPCTSTR lpszDevice, // device name LPCTSTR lpszOutput, // not used; should be NULL CONST DEVMODE* lpInitData // optional printer data);
2、设置字体、背景等
m_hFont = CreateFont(m_iFontSize, m_FontName); ::SelectObject(HDC hdc, m_hFont); ::SetBkMode(HDC hdc, TRANSPARENT);
::SetTextColor(HDC hdc, RGB(0, 0, 0));
TEXTMETRIC tm={0}; GetTextMetrics(hDC, &tm);
m_iTextWidth = tm.tmAveCharWidth;
m_iTextHeight = tm.tmHeight+tm.tmExternalLeading;
m_iPageWidth = GetDeviceCaps(hDC, HORZRES);
m_iPageHeight = GetDeviceCaps(hDC, VERTSIZE);
3、开始打印文档、打印页
DOCINFOA docInfo; docInfo.cbSize = sizeof(docInfo); docInfo.fwType = 0; docInfo.lpszDatatype = NULL; docInfo.lpszOutput = NULL; docInfo.lpszDocName = pDocName; if (::StartDocA(m_hPrintDC, &docInfo) <= 0) { RunLogFile("CDriverPrint StartDoc StartDocA Fail[%d]", GetLastError()); break; } if(::StartPage(m_hPrintDC) <= 0) { RunLogFile("CDriverPrint StartDoc StartPage Fail[%d]", GetLastError()); break; }
4、结束打印页、打印文档,开始打印、清理句柄
if(::EndPage(m_hPrintDC) <= 0)
{
RunLogFile("CDriverPrint EndDoc EndPage Fail[%d]", GetLastError());
break;
}
if(::EndDoc(m_hPrintDC) <= 0)
{
RunLogFile("CDriverPrint EndDoc EndDoc Fail[%d]", GetLastError());
break;
}
::DeleteObject(m_hFont);
::DeleteDC(m_hPrintDC);
二、串口打印
主要参数:端口名称、波特率
1、连接打印机
HANDLE hPrintPort = CreateFile(StringAsciiToUnicode(szKey).c_str(),GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hPrintPort==INVALID_HANDLE_VALUE) { return PC_ERR_PRINT_ERR; } else { //设置端口缓冲 BOOL bFlag = SetupComm(hPrintPort,1024,1024); //设定通讯端口超时参数 COMMTIMEOUTS tmouts; tmouts.ReadIntervalTimeout = 100; tmouts.ReadTotalTimeoutMultiplier = 100; tmouts.ReadTotalTimeoutConstant = 100; tmouts.WriteTotalTimeoutConstant = 100; tmouts.WriteTotalTimeoutMultiplier = 100; SetCommTimeouts(m_hPrintPort,&tmouts); //设定通讯端口通讯参数 DCB dcb; BOOL bol = TRUE; bol = GetCommState(hPrintPort,&dcb); dcb.BaudRate = lPort; dcb.ByteSize = 8; bol = SetCommState(hPrintPort,&dcb);//配置串口 //清除通讯端口缓存 PurgeComm(hPrintPort,PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT); }
2、初始化打印数据命令
BYTE by[2]; //初始化打印机命令 by[0] = 0x1B; by[1] = 0x40; DWORD dwWrite; WriteFile(hPrintPort,by,(DWORD)2,&dwWrite,NULL);
BYTE by[6]; //切纸命令
by[0] = '\r';
by[1] = '\n';
by[2] = 0x1D;
by[3] = 0x56;
by[4] = 0x42;
by[5] = 0x00;
3、关闭端口
CloseHandle(hPrintPort);//关闭端口
三、网络打印
主要参数:ip、端口号
1、网络连接打印机
string strAddr = szServerAddress; strAddr.TrimLeft(); strAddr.TrimRight(); addrinfo* pRes = NULL; addrinfo hints; memset(&hints,0,sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; if(getaddrinfo(strAddr,LongToString(lPort),&hints,&pRes)) { RunLogFile("getaddrinfo [%s] error %d",strAddr.c_str(),::WSAGetLastError()); return INVALID_SOCKET; } SOCKET hSocket = socket(pRes->ai_family,SOCK_STREAM,IPPROTO_TCP); if(hSocket == INVALID_SOCKET) { RunLogFile("socket [%s] error %d",strAddr.c_str(),::WSAGetLastError()); freeaddrinfo(pRes); return hSocket; } //邦定本地端口和IP if(pRes->ai_family == AF_INET6) { sockaddr_in6 addr; memset(&addr,0,sizeof(addr)); addr.sin6_family = AF_INET6; addr.sin6_port = htons(0); addr.sin6_addr = in6addr_any; if(bind(hSocket,(sockaddr*)&addr,sizeof(addr)) != 0) { RunLogFile("bind [%s] error %d",strAddr.c_str(),::WSAGetLastError()); freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } } else { sockaddr_in addr; memset(&addr,0,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(0); addr.sin_addr.s_addr = 0; if(bind(hSocket,(sockaddr*)&addr,sizeof(addr)) != 0) { RunLogFile("bind [%s] error %d",strAddr.c_str(),::WSAGetLastError()); freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } } //设为非阻塞socket #ifdef WIN32 u_long bNoBlock = TRUE; int iRet = ioctlsocket(hSocket,FIONBIO,&bNoBlock); #else int flags = fcntl(hSocket,F_GETFL,0); int iRet = fcntl(hSocket,F_SETFL,flags|O_NONBLOCK); #endif if(iRet == SOCKET_ERROR) { RunLogFile("ioctlsocket NoBlock [%s] error %d",strAddr.c_str(),::WSAGetLastError()); freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } //连接 iRet = connect(hSocket,pRes->ai_addr,pRes->ai_addrlen); //检查是否成功连接 fd_set setWrite; FD_ZERO(&setWrite); FD_SET(hSocket,&setWrite); fd_set setError; FD_ZERO(&setError); FD_SET(hSocket,&setError); timeval tv; tv.tv_sec = dwWaitMilliSecond/1000;//连接超时(秒) tv.tv_usec = (dwWaitMilliSecond%1000)*10; #ifdef WIN32 iRet = select(0,NULL,&setWrite,&setError,&tv); #else fd_set setRead; FD_ZERO(&setRead); FD_SET(hSocket,&setRead); iRet = select(hSocket+1,&setRead,&setWrite,&setError,&tv); #endif if(iRet < 0) { ::RunLogFile("connect %s:%d error1 %d",szServerAddress,lPort,WSAGetLastError()); freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } if(iRet == 0) { //"连接超时 ::RunLogFile("connect %s:%d timeout error %d",szServerAddress,lPort,WSAGetLastError()); freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } if(FD_ISSET(hSocket,&setError)) { //"连接错误 // int nError = WSAGetLastError(); ::RunLogFile("connect %s:%d error2 %d",szServerAddress,lPort,WSAGetLastError()); freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } if(!FD_ISSET(hSocket,&setWrite)) { //连接出错; ::RunLogFile("connect %s:%d error3 %d",szServerAddress,lPort,WSAGetLastError()); freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } #ifndef WIN32 if(FD_ISSET(hSocket,&setRead)) { int nError = 0; int nErrorlen = sizeof(int); if(getsockopt(hSocket,SOL_SOCKET,SO_ERROR,(char*)&nError,(socklen_t*)&nErrorlen) == -1) { freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } else { if(nError != 0) { freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } } } #endif //连接成功,设为阻塞socket #ifdef WIN32 bNoBlock = 0; iRet = ioctlsocket(hSocket,FIONBIO,&bNoBlock); #else flags = fcntl(hSocket,F_GETFL,0); iRet = fcntl(hSocket,F_SETFL , flags & (~O_NONBLOCK)); #endif if(iRet == SOCKET_ERROR) { RunLogFile("ioctlsocket Block [%s] error %d",strAddr.c_str(),::WSAGetLastError()); freeaddrinfo(pRes); CloseSocket(hSocket); hSocket = INVALID_SOCKET; return hSocket; } freeaddrinfo(pRes); return hSocket;
2、通过套接字,向打印机发送数据
long CSocketFunc::SendData(SOCKET sk,const void* lpBuf, int nBufLen,DWORD dwWaitMilliSecond) { int iLen,iComepleteLen,iSendLen; char *pBuf = NULL; iLen = nBufLen; pBuf = (char*)lpBuf; iComepleteLen = 0; //取当前时间(毫秒) DWORD_PTR dStart = GetTickCountPtr(); do { //检查是否超时 DWORD_PTR dBetween = GetTickCountPtr() - dStart; if(dBetween >= dwWaitMilliSecond) { //超时 return PC_ERR_TIMEOUT; } if(!IsCanSend(sk,dwWaitMilliSecond - dBetween)) { //超时 return PC_ERR_TIMEOUT; } iSendLen = send(sk,pBuf + iComepleteLen,min(1024,(iLen - iComepleteLen)),0); if(iSendLen == SOCKET_ERROR) { RunLogFile("SendData err : %d", WSAGetLastError()); return PC_ERR_CONNECT_CLOSE; } iComepleteLen += iSendLen; }while(iComepleteLen < iLen); return 0; }
BOOL CSocketFunc::IsCanSend(SOCKET sk ,DWORD dwWaitMilliSecond)
{
fd_set set;
FD_ZERO(&set);
FD_SET(sk,&set);
timeval tv;
tv.tv_sec = dwWaitMilliSecond/1000;
tv.tv_usec = (dwWaitMilliSecond%1000)*10;
int iRet = select(sk+1,NULL,&set,NULL,&tv);
return iRet == 1;
}
设置网络打印机方法:
一、为打印机设置ip;打印机在连接上网线以后会通过路由器的DHCP服务自动设置一个ip,但是此ip不一定与自己的计算机的ip处在同一个ip段【同段ip为192.168.0.***,即前三位相同(不一定为192.168.0),只有最后一位不同】,ip不再同一段是无法连接的。
二、那么就需要手动设置ip;
手动设置打印机ip:
1、打印一张打印机自测页(与打印机测试页不同):以HP2015为例,按绿键大约5秒放开即可;
2、从自测页上可以找到打印机的ip,以192.168.0.250为例;
3、然后将计算机的ip设置为与打印机相同段的ip,例:原来为192.168.2.200,改为192.168.0.200;
4、在ie浏览页中输入打印机的ip:192.168.0.250,会出现打印机的设置页,将其ip设置为局域网段的ip,例192.168.2.250,记着保存。
5、在ie地址栏重新输入192.168.0.250,如果还能打开打印机的设置页,说明上步中ip设置失败,请重新设置,直到成功。
6、将计算机恢复为原来的ip:192.168.2.200;
7、在ie地址栏输入设置后的打印机的ip,192.168.2.250,一定能打开打印机的设置页
,打印机ip设置完成。