驱动、串口、网络处理打印机

 一、驱动打印

  主要参数:打印机名称,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设置完成。

猜你喜欢

转载自www.cnblogs.com/fenglangxiaotian/p/9593838.html