您现在的位置是:网站首页> C/C++

打印实现

  • C/C++
  • 2022-04-17
  • 1108人已阅读
摘要

关于wifi打印服务器方案和USB共享打印机模块工作原理

C++调用USB小票打印机 第一种办法 无驱动

VC驱动方式打印

直接无驱打印

用VC++实现USB接口读写数据的程序 

VC WinUSB  VC++ HIDAPI实现USB数据读写


bSuccess = WriteFile(m_hCom, pbuff, len, &written, &m_ov);

if (!bSuccess )

{

if (ERROR_IO_PENDING == GetLastError())

{

WaitForSingleObject(m_ov.hEvent, 10);   // 无纸或其他情况阻塞只等待10毫秒

// return -1;

}

        }



//链接打印机

int InitPort(PrintDevice &device)

{

    hPort = CreateFile(device.Port.c_str(), GENERIC_READ | GENERIC_WRITE,

        0, NULL,

        OPEN_EXISTING,

        FILE_ATTRIBUTE_NORMAL, NULL);


    if (hPort == INVALID_HANDLE_VALUE)

    {   // 打开端口失败

        return false;

    }

    else

    {


        printf("InitPort Hello\r\n");


        //设置端口缓冲

        SetupComm(hPort, 1024, 1024);


        // 设定通讯端口超时参数

        COMMTIMEOUTS tmouts;

        tmouts.ReadIntervalTimeout = 100;

        tmouts.ReadTotalTimeoutMultiplier = 100;

        tmouts.ReadTotalTimeoutConstant = 100;

        tmouts.WriteTotalTimeoutConstant = 100;

        tmouts.WriteTotalTimeoutMultiplier = 100;

        SetCommTimeouts(hPort, &tmouts);


        //设定通讯端口通讯参数

        DCB dcb;

        BOOL bol = TRUE;


        //dcb.DCBlength = sizeof(dcb);

        bol = GetCommState(hPort, &dcb);

        dcb.BaudRate = device.BawdRate;

        dcb.ByteSize = device.DataBits;

        dcb.StopBits = device.StopBits;

        dcb.Parity = device.Parity;


        bol = SetCommState(hPort, &dcb); //配置串口

        // 清除通讯端口缓存

        PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT);


        // 初始化重叠IO对象

        OVERLAPPED m_OverlappedRead;

        OVERLAPPED m_OverlappedWrite;

        HANDLE m_hStopCommEvent;

        HANDLE m_hDataReady;

        memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED));

        m_OverlappedRead.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

        memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED));

        m_OverlappedWrite.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);


        // 初始化事件对象

        m_hStopCommEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

        m_hDataReady = CreateEvent(NULL, FALSE, FALSE, NULL);


        //初始化打印ESC @

        DWORD iBytesLength;

        char chInitCode[] = "\x0D\x1B\x40";

        if (!WriteFile(hPort, chInitCode, (DWORD)3L, &iBytesLength, NULL))

            return false;

    }


    return true;

}


int   WriteData(string meg)

{

    DWORD dwWrite;

    return WriteFile(hPort, meg.c_str(), (DWORD)meg.length(), &dwWrite, NULL);

}


//打印数据,meg打印字符串,bBold=true粗体,nZoom=2大一号字体, nHAil=2居中对齐,nHAil=3右对齐。部分打印机可能中文字体设置无效,请加上FS !命令设置中文字体。

bool OnWriteData(string meg, bool bBold, bool bDTall, bool bDWide, int nHAil)

{

    char s[120] = "";

    memset(s, 0, 120);


    long nMode = 0;

    DWORD iBytesLength;


    if (bBold)

        nMode += 8;


    if (bDTall)

        nMode += 16;


    if (bDWide)

        nMode += 32;


    if (nMode > 0)

    {

        //sprintf(s, "\x1B\x21%c", nMode);

        sprintf_s(s, sizeof(s), "\x1B\x21%c", nMode);

        if (strlen(s) < 3)

        {

            iBytesLength = 0;

            WriteFile(hPort, s, (DWORD)3L, &iBytesLength, NULL);

        }

        else

            WriteData(s);

    }


    switch (nHAil)

    {

    case 1:

        break;

    case 2:

        strcat_s(s, strlen("\x1B\x61\x01") + 1, "\x1B\x61\x01");

        WriteData(s);

        break;

    case 3:

        strcat_s(s, strlen("\x1B\x61\x02") + 1, "\x1B\x61\x02");

        WriteData(s);

        break;

    default:

        break;

    }


    WriteData(meg);


    iBytesLength = 0;

    strcpy_s(s, strlen("\x1B\x21\x00") + 1, "\x1B\x21\x00");

    WriteFile(hPort, s, (DWORD)3L, &iBytesLength, NULL);


    return true;

};



//获取CreateFile的USB端口号



// 根据GUID获得设备路径

// lpGuid: GUID指针

// pszDevicePath: 设备路径指针的指针,用于返回找到的路径

// 返回: 成功得到的设备路径个数,可能不止1个

int GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)

{

    HDEVINFO hDevInfoSet;

    SP_DEVINFO_DATA spDevInfoData;

    SP_DEVICE_INTERFACE_DATA ifData;

    PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;

    int nCount;

    int nTotle;

    BOOL bResult;


    char* strUSBPrint = "USB 打印支持";


    // 取得一个该GUID相关的设备信息集句柄

    hDevInfoSet = ::SetupDiGetClassDevs(lpGuid,     // class GUID

        NULL,                    // 无关键字

        NULL,                    // 不指定父窗口句柄

        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);    // 目前存在的设备


    // 失败...

    if (hDevInfoSet == INVALID_HANDLE_VALUE)

    {

        return 0;

    }


    // 申请设备接口数据空间

    pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);


    pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);


    nTotle = -1;

    nCount = 0;

    bResult = TRUE;


    // 设备序号=0,1,2... 逐一测试设备接口,到失败为止

    while (bResult)

    {

        nTotle++;

        spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);


        // 枚举符合该GUID的设备接口

        bResult = ::SetupDiEnumDeviceInfo(

            hDevInfoSet,     // 设备信息集句柄

            (ULONG)nTotle,   // 设备信息集里的设备序号

            &spDevInfoData);        // 设备接口信息


        if (bResult)

        {

            DWORD DataT;

            TCHAR buf[MAX_PATH];

            DWORD nSize = 0;


            // get Friendly Name or Device Description

            if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,

                SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize)) {

            }

            else if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,

                SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize)) {

            }

            else {

                lstrcpy(buf, _T("Unknown"));

            }


            //是否是要找的设备类型

            if (strcmp(buf, strUSBPrint) != 0)

                continue;


            ifData.cbSize = sizeof(ifData);


            // 枚舉符合該GUID的設備接口

            bResult = ::SetupDiEnumDeviceInterfaces(

                hDevInfoSet,     // 設備信息集句柄

                NULL,            // 不需額外的設備描述

                lpGuid,          // GUID

                (ULONG)nTotle,   // 設備信息集里的設備序號

                &ifData);        // 設備接口信息


            if (bResult)

            {

                // 取得该设备接口的细节(设备路径)

                bResult = SetupDiGetInterfaceDeviceDetail(

                    hDevInfoSet,    // 设备信息集句柄

                    &ifData,        // 设备接口信息

                    pDetail,        // 设备接口细节(设备路径)

                    INTERFACE_DETAIL_SIZE,    // 输出缓冲区大小

                    NULL,           // 不需计算输出缓冲区大小(直接用设定值)

                    NULL);          // 不需额外的设备描述


                if (bResult)

                {

                    // 复制设备路径到输出缓冲区

                    ::strcpy_s(pszDevicePath[nCount], 256, pDetail->DevicePath);

                    // 调整计数值

                    nCount++;

                }

            }

        }

    }


    // 释放设备接口数据空间

    ::GlobalFree(pDetail);


    // 关闭设备信息集句柄

    ::SetupDiDestroyDeviceInfoList(hDevInfoSet);


    return nCount;

}



C++ win32 USB打印机开发

基于打印驱动

1 : 获得本地打印驱动

struct  PrintInfo

{

    BOOL            m_bisPrintPage;

    string          sDeviceName;

    string          sPortName;

    string          sShareName;

    string          sLoction;

    string          sPaperType;

    int             nWidthMin;

    bool            bisPrint;

    PrintInfo()

    {

      m_bisPrintPage = FALSE;

      sDeviceName = "";

      sPortName = "";

      sShareName = "";

      sLoction = "";

      sPaperType = "";

      nWidthMin = 0;

      bisPrint = FALSE;

    }


};

typedef  vector<PrintInfo> PrintInfo_Ary;

int   GetLocalPrinterDrivers(PrintInfo_Ary &Drivers)

{

    DWORD        Flags =  PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL; //local printers

    DWORD        cbBuf;

    DWORD        pcReturned;

    DWORD        index;

    DWORD        Level = 2;

    CHAR        Name[500];

    LPPRINTER_INFO_2A pPrinterEnum = NULL;


    memset(Name, 0, sizeof(CHAR)* 500);

    ::EnumPrintersA(Flags, Name, Level, NULL, 0, &cbBuf, &pcReturned);

    pPrinterEnum = (LPPRINTER_INFO_2A)LocalAlloc(LPTR, cbBuf + 4);

    if (!pPrinterEnum)

    {

        goto clean_up;

    }


    if (!EnumPrintersA(

        Flags,                            // DWORD Flags, printer object types 

        Name,                            // LPTSTR Name, name of printer object 

        Level,                            // DWORD Level, information level 

        (LPBYTE)pPrinterEnum,            // LPBYTE pPrinterEnum, printer information buffer 

        cbBuf,                            // DWORD cbBuf, size of printer information buffer

        &cbBuf,                            // LPDWORD pcbNeeded, bytes received or required 

        &pcReturned)                    // LPDWORD pcReturned number of printers enumerated 

        )

    {

        goto clean_up;

    }

    if (pcReturned > 0)

    {

        for (index = 0; index < pcReturned; index++)

        {

            PrintInfo DeviceDate;

            if ((pPrinterEnum + index)->pPrinterName != NULL)

                DeviceDate.sDeviceName = (pPrinterEnum + index)->pPrinterName;

            else

                DeviceDate.sDeviceName ="";

            

            if ((pPrinterEnum + index)->pPortName != NULL)

                DeviceDate.sPortName = (pPrinterEnum + index)->pPortName;

            else

                DeviceDate.sPortName = "";

        

            if ((pPrinterEnum + index)->pShareName != NULL)

                DeviceDate.sShareName = (pPrinterEnum + index)->pShareName;

            else

                DeviceDate.sShareName = "";

    

            if ((pPrinterEnum + index)->pLocation != NULL)

                DeviceDate.sLoction = (pPrinterEnum + index)->pLocation;

            else

                DeviceDate.sLoction = "";

            

            if ((pPrinterEnum + index)->pDevMode)

            {

                DeviceDate.nWidthMin = (pPrinterEnum + index)->pDevMode->dmPaperWidth;

                DeviceDate.sPaperType = (char*)((pPrinterEnum + index)->pDevMode->dmFormName);

            }

            //DeviceDate.nWidthMin = (pPrinterEnum + index)->pDevMode->dmPaperWidth;

            //DeviceDate.sPaperType = (char*)((pPrinterEnum + index)->pDevMode->dmFormName);

            DWORD nstuse = (pPrinterEnum + index)->Status;

            DWORD Attributes = (pPrinterEnum + index)->Attributes;

            DeviceDate.m_bisPrintPage = BisConnectedA(nstuse, Attributes);

            Drivers.push_back(DeviceDate);


        }

    }

clean_up:

    LocalFree(LocalHandle(pPrinterEnum));

    return (int)Drivers.size();

}

2: 打开设备进行打印打开一个打印机驱动DriverName 是驱动名称

{

    HDC hdcPrint = CreateDC(NULL, DriverName, NULL, NULL);

    HFONT  Font = CreateFont(32, 0, 0, 0, fontWeight, 0, 0, 0,

                            DEFAULT_CHARSET, OUT_TT_PRECIS,

                            CLIP_TT_ALWAYS, PROOF_QUALITY,VARIABLE_PITCH | FF_MODERN | 0x04,L"宋体");

    //设置打印梯子

    SelectObject(hdcPaint,Font);    

    LPCWSTR Lp = L"task";

    DOCINFO div={sizeof (DOCINFO),Lp};

    //编辑一个文档

    StartDoc(hdcPrint, &m_di);

    //编辑一个文档的一页

    StartPage(hdcPrint);

    RECT rect;

    rect.top = 0;

    rect.bottom = 200;

    rect.left = 0;

    rect.right = 380;

    DrawTextA(hdcPrint, "helleo world",13, &rect, DT_LEFT | DT_TOP | DT_EXPANDTABS | DT_NOPREFIX | DT_EDITCONTROL | DT_WORDBREAK | DT_EXTERNALLEADI    NG | DT_CALCRECT);

    DrawTextA(hdcPrint,"helleo world",13,&rect, DT_LEFT | DT_TOP | DT_EXPANDTABS | DT_NOPREFIX | DT_EDITCONTROL | DT_WORDBREAK | DT_EXTERNALLEADING    );

   //....

   //结束编辑页

   EndPage(hdcPrint);

   //结束整个文本编辑

   EndDoc(hdcPrint);

   CloseHandle(hdcPrint);

}


基于硬件驱动开发

1: 获得打印设备信息

#pragma once


#include <iostream>

#include <fstream>

#include <string>

#include <sstream>

#include <windows.h>

#include <devguid.h>

#include <setupapi.h>

#include <vector>

#pragma comment (lib, "setupapi.lib")

const char DRIVER_NAME_USBPRINT[] = "USB 打印支持";

const char DRIVER_NAME_USBPRINT_EN[] = "USB Printing Support";


struct  deviceinfo {

    std::string  sdeviceid;

    std::string  sdesc;

    std::string  sdevicepath; 

    std::string  sdeviceshow;

    deviceinfo() {

        sdeviceid = "";

        sdesc = "";

        sdevicepath = "";

        sdeviceshow = "";

    }

};


std::vector<deviceinfo > g_printerdevices;

const GUID GUID_DEVINTERFACE_USB_HUB             = { 0xf18a0e88L, 0xc30c, 0x11d0, { 0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8 } };

const GUID GUID_DEVINTERFACE_USB_DEVICE          = { 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };

const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3abf6f2dL, 0x71c4, 0x462a, { 0x8a, 0x92, 0x1e, 0x68, 0x61, 0xe6, 0xaf, 0x27 } };

const GUID GUID_USB_WMI_STD_DATA                 = { 0x4E623B20L, 0xCB14, 0x11D1, { 0xB3, 0x31, 0x00, 0xA0, 0xC9, 0x59, 0xBB, 0xD2 } };

const GUID GUID_USB_WMI_STD_NOTIFICATION         = { 0x4E623B20L, 0xCB14, 0x11D1, { 0xB3, 0x31, 0x00, 0xA0, 0xC9, 0x59, 0xBB, 0xD2 } };

const GUID USBPrinterGUID                        = { 0x4d36e979L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };

//GUID__DEVINTERFACE_USB_DEVICE

int  GetUSBPrintDevices(const GUID guid)

{

    const GUID GUID_DEVINTERFACE_USB_DEVICE  = guid;

    const GUID* InterfaceGuid = &GUID_DEVINTERFACE_USB_DEVICE;


    // that contains all devices of a specified class

    HDEVINFO hDevInfo = SetupDiGetClassDevsA(InterfaceGuid,

                                             NULL, // Enumerator

                                             NULL,

                                             DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);


    if (hDevInfo == INVALID_HANDLE_VALUE)

    {

        return 1;

    }


    SP_DEVINFO_DATA DeviceInfoData;

    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    PSP_DEVINFO_DATA pDeviceInfoData = &DeviceInfoData;


    DWORD MemberIndex;


    bool found_usb_printer_flag = false;


    for (MemberIndex = 0;

         SetupDiEnumDeviceInfo(hDevInfo,

                               MemberIndex,

                               pDeviceInfoData) == TRUE;

         MemberIndex++)

    {

        SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;

        DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

        PSP_DEVICE_INTERFACE_DATA pDeviceInterfaceData = &DeviceInterfaceData;


        DWORD RequiredSize;

        PDWORD pRequiredSize = &RequiredSize;


        DWORD InnerMemberIndex;

        for (InnerMemberIndex = 0; SetupDiEnumDeviceInterfaces(hDevInfo, 

                                         pDeviceInfoData,

                                         InterfaceGuid,

                                         InnerMemberIndex,

                                         pDeviceInterfaceData) == TRUE;

             InnerMemberIndex++)

        {

            

            DWORD DeviceInterfaceDetailDataSize = 0;

            BOOL first_call_result = SetupDiGetDeviceInterfaceDetailA(hDevInfo,

                                                                      pDeviceInterfaceData,

                                                                      NULL, // NULL DeviceInterfaceDetailData pointer

                                                                      0,    // DeviceInterfaceDetailDataSize of zero

                                                                      pRequiredSize,

                                                                      pDeviceInfoData);


            if (first_call_result == TRUE)

            {

                continue;

            }

            else 

            {

                DWORD first_call_error = GetLastError();

                if (first_call_error != ERROR_INSUFFICIENT_BUFFER)

                {

                    continue;

                }

                else

                {


                    CHAR* buffer = new CHAR[RequiredSize];

                    PSP_DEVICE_INTERFACE_DETAIL_DATA_A pDeviceInterfaceDetailData = 

                        (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)buffer;

                    pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);


                    DWORD DeviceInterfaceDetailDataSize = RequiredSize;

                    PDWORD pDeviceInterfaceDetailDataSize = &DeviceInterfaceDetailDataSize;


                    BOOL second_call_result = SetupDiGetDeviceInterfaceDetailA(hDevInfo,

                                                                               pDeviceInterfaceData,

                                                                               pDeviceInterfaceDetailData,

                                                                               DeviceInterfaceDetailDataSize,

                                                                               &RequiredSize,

                                                                               pDeviceInfoData);


                    if (second_call_result == FALSE)

                    {

                        DWORD last_error_number_second_call = GetLastError();

                        CHAR last_error_message_second_call[512];

                        FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0,

                            last_error_number_second_call, 0,

                            last_error_message_second_call,

                            1024, NULL);

    

                    }

                    else

                    {    

                        DWORD dwNumberOfBytesWritten = 0;


                        CHAR szDescription[MAX_PATH];

                        memset(szDescription, 0, MAX_PATH);


                        const GUID* ClassGuid = &(pDeviceInfoData->ClassGuid);

                        SetupDiGetClassDescriptionA(ClassGuid, szDescription, MAX_PATH, &RequiredSize);


                        memset(szDescription, 0, MAX_PATH);

                        SetupDiGetDeviceInstanceIdA(hDevInfo, pDeviceInfoData, szDescription, MAX_PATH, 0);


                        char  szName[64]      = {0};

                        if (SetupDiGetDeviceRegistryProperty(hDevInfo,

                                                    pDeviceInfoData,

                                                    SPDRP_FRIENDLYNAME,

                                                    0L,

                                                    (PBYTE)szName,

                                                    63,

                                                    0))

                        {

                  

                        }

                        else if (SetupDiGetDeviceRegistryProperty(hDevInfo,

                                                                pDeviceInfoData,

                                                                SPDRP_DEVICEDESC,

                                                                0L,

                                                                (PBYTE)szName,

                                                                63,

                                                                0))

                        {

                  

                        };


                        std::string sdrivername = szName;

                        if(sdrivername.find(DRIVER_NAME_USBPRINT) != std::string::npos || sdrivername.find(DRIVER_NAME_USBPRINT_EN) != std::string::npos)

                        {

                            deviceinfo device; 

                            device.sdeviceid = szDescription;

                            device.sdesc = szName;

                            device.sdevicepath =  pDeviceInterfaceDetailData->DevicePath;

                            GetShowNames(device.sdeviceid ,device.sdeviceshow);

                            g_printerdevices.push_back(device);

                        }

                    

                    } // end if second call returned true


                    // now free the buffer

                    delete[] buffer;

                } // end if first call was successful

            } // end if on second call

        } // end iterate through device interfacess

    } // end iterate through device info


    SetupDiDestroyDeviceInfoList(hDevInfo);

    return 0;

}

2. 选取一个设备打印

const char initialize_printer_command[] = {ESCAPE_CODE, AT_CODE, NULL_CODE};

const char ESC_WIDTHANDHEGHIT2[] = {0x1c,0x21,12};

int WiterFileInfo(HANDLE handle,const char* sdata)

{


    DWORD dwInitializePrinterNumberOfBytesToWrite = 0;

    DWORD dwInitializePrinterNumberOfBytesWritten = 0;


    dwInitializePrinterNumberOfBytesToWrite = (DWORD)strlen(sdata);


    BOOL ret = WriteFile( handle,

        sdata,

        dwInitializePrinterNumberOfBytesToWrite,

        &(dwInitializePrinterNumberOfBytesWritten),

        NULL);


    return dwInitializePrinterNumberOfBytesWritten;


}



int  USBPrintData(deviceinfo &driver)

{

    HANDLE handle = CreateFileA(driver.sdevicepath.c_str(),

        GENERIC_WRITE | GENERIC_READ,

        FILE_SHARE_READ | FILE_SHARE_WRITE,

        0,

        OPEN_EXISTING,

        0,

        NULL);

    if (handle == INVALID_HANDLE_VALUE)

    {

        CloseHandle(handle);

        return 0;

    }

    else

    {

        int i = 0;

    }


    DWORD dwInitializePrinterNumberOfBytesToWrite = 0;

    DWORD dwInitializePrinterNumberOfBytesWritten = 0;

       //ESC 指令打印

    WiterFileInfo(handle,initialize_printer_command);

       sprintf(write,"%s两倍大小字体\n",ESC_WIDTHANDHEGHIT2);

       WiterFileInfo(handle,write);

       //空白纸走3行

       WiterFileInfo(handle," \n \n \n");

       CloseHandle(handle);

       return 0;

}

一点ESC指令测试


const char ESC_INIT_RWX[] = {0x1B,0x40};            //初始化;              

const char ESC_LINE_TAB[] = {0x0A};                 //换行

const char ESC_LINE_ADD[] = {0x1B,0x21,0x28};       //加粗

//const char ESC_LINE_H2[] = {0x1D,0x21,0x04};      //倍高 垂直( 三位符(倍高度)  1 2 4 8 1-7 倍)

//const char ESC_LINE_W2[] = {0x1D,0x21,0x20};      //倍高 垂直( 三位符(倍高度)  10 20 30 40 宽度 )

const char ESC_LINE_H1[] = {0x1D,0x21,0x01};        //倍高 垂直( 三位符(倍高度)  1 2 4 8 1-7 倍)

const char ESC_LINE_H2[] = {0x1D,0x21,0x02};        //倍高 垂直( 三位符(倍高度)  1 2 4 8 1-7 倍)

const char ESC_LINE_H3[] = {0x1D,0x21,0x04};        //倍高 垂直( 三位符(倍高度)  1 2 4 8 1-7 倍)


const char ESC_LINE_W1[] = {0x1D,0x21,0x10};        //倍高 垂直( 三位符(倍高度)  10 20 30 40 宽度 )

const char ESC_LINE_W2[] = {0x1D,0x21,0x20};        //倍高 垂直( 三位符(倍高度)  10 20 30 40 宽度 )

const char ESC_LINE_W3[] = {0x1D,0x21,0x30};        //倍高 垂直( 三位符(倍高度)  10 20 30 40 宽度 )


const char ESC_LINE_T1[] = {0x1B,0x21,0x02};        //原始高度

const char ESC_LINE_T2[] = {0x1D,0x21,0x11};        //倍高 垂直( 三位符(倍高度)  10 20 30 40 宽度 )

const char ESC_LINE_T3[] = {0x1D,0x21,0x22};        //倍高 垂直( 三位符(倍高度)  10 20 30 40 宽度 )

const char ESC_LINE_T4[] = {0x1D,0x21,0x34};        //倍高 垂直( 三位符(倍高度)  10 20 30 40 宽度 )

const char ESC_LINE_T5[] = {0x1D,0x21,0x48};        //倍高 垂直( 三位符(倍高度)  10 20 30 40 宽度 )



无驱打印

使用Win32 API打印原始数据(强烈建议)

#include "stdafx.h"

#include <windows.h>

#include <string>

#include <IOSTREAM>

#include <winioctl.h>

#include <setupapi.h>


#pragma comment(lib, "setupapi.lib")


using namespace std;


typedef struct DataInfo

{

    string Port;  //串口端口号

    int BawdRate;//波特率

    int DataBits;  //数据位

    char Parity;  //校验位

    int ReceiveBuffer;  //缓冲区

    int StopBits;//停止位

}PrintDevice;


// SetupDiGetInterfaceDeviceDetail所需要的输出长度,定义足够大

#define INTERFACE_DETAIL_SIZE    (1024)


//设备数量上限,假设16台上限

#define MAX_DEVICE 16




//USB类的GUID

const GUID USB_GUID = {0xa5dcbf10, 0x6530, 0x11d2, {0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed}};


HANDLE hPort=NULL;  //句柄


//封装的打印函数

int WriteData(string meg);

//打印内容

bool OnWriteData(string meg, bool bBold = false, bool bDTall = false, bool bDWide = false, int nHAil = 1);

//链接设备

int InitPort(PrintDevice &device);

//参数初始化

void InitializeDevicePar(PrintDevice &device);

//找设备

int GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath);


int _tmain(int argc, _TCHAR* argv[])

{

//////////////////////////////////////////////////////////////////////////////////////////////////

//遍历USB设备,找到POS打印机路径

    int i, nDevice;

    char* szDevicePath[MAX_DEVICE];        // 设备路径


    // 分配需要的空间

    for (i = 0; i < MAX_DEVICE; i++)

    {

        szDevicePath[i] = new char[256];

    }


    // 取设备路径

    nDevice = GetDevicePath((LPGUID)&USB_GUID, szDevicePath);

//  GUID_CLASS_USB_DEVICE;

//////////////////////////////////////////////////////////////////////////////////////////////////

    i = 0;

    while (i < nDevice)

    {

        PrintDevice device;

        InitializeDevicePar(device);  //初始化打印机参数


        device.Port = szDevicePath[i++];


        printf("device.Port = %s\n",device.Port.c_str());


        InitPort(device);  //初始化打印机端口


        string s;


////////////////////////////打印头信息开始//////////////////////////////////

        OnWriteData("*****Now You See Me*****\n\n",true, true, true);


        OnWriteData("- - - - - - - - - - - - - - - -\n");


        OnWriteData("So You Want?\n",false, true);


        OnWriteData("- - - - - - - - - - - - - - - -\n");


        OnWriteData("这是一个基于ESC_POS打印机的USB无驱动打印Demo\n",true, true, true);


        OnWriteData("我找到了你的电脑上所有的USB打印机\n",true, true, true, 2);


        OnWriteData("然后给所有找到的打印机发送打印命令\n", true, true, true, 3);


        OnWriteData("* * * * * * * * * * * * * * * *\n");


        OnWriteData("OK打印完成\n\n",false, false, true, 2);


        s = "\x1D\x56\x41\x00";

        WriteData(s);


        CloseHandle(hPort);//关闭端口

     }

 // 释放空间

    for (i = 0; i< MAX_DEVICE; i++)

    {

        delete szDevicePath[i];

    }


    return 0;

}


//初始化参数

void InitializeDevicePar(PrintDevice &device)

{

    device.Port="COM4";

    device.BawdRate=9600;

    device.DataBits=8;

    device.StopBits=ONESTOPBIT;

    device.Parity=NOPARITY;  //NONE

    device.ReceiveBuffer=256;

}


//链接打印机

int InitPort(PrintDevice &device)

{

    hPort = CreateFile(device.Port.c_str(), GENERIC_READ | GENERIC_WRITE,

        0, NULL, 

        OPEN_EXISTING,

        FILE_ATTRIBUTE_NORMAL, NULL );


    if (hPort == INVALID_HANDLE_VALUE) 

    {   // 打开端口失败

        return false;

    }

    else 

    { 


        printf("InitPort Hello\r\n");


        //设置端口缓冲

        SetupComm(hPort, 1024, 1024); 


        // 设定通讯端口超时参数

        COMMTIMEOUTS tmouts;

        tmouts.ReadIntervalTimeout = 100;

        tmouts.ReadTotalTimeoutMultiplier = 100;

        tmouts.ReadTotalTimeoutConstant = 100;

        tmouts.WriteTotalTimeoutConstant = 100;

        tmouts.WriteTotalTimeoutMultiplier = 100;

        SetCommTimeouts(hPort, &tmouts);


        //设定通讯端口通讯参数

        DCB dcb;

        BOOL bol = TRUE;


        //dcb.DCBlength = sizeof(dcb);

        bol=GetCommState(hPort, &dcb);

        dcb.BaudRate = device.BawdRate;

        dcb.ByteSize =device.DataBits;

        dcb.StopBits = device.StopBits;

        dcb.Parity = device.Parity;


        bol = SetCommState(hPort, &dcb); //配置串口

        // 清除通讯端口缓存

        PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT);


        // 初始化重叠IO对象

        OVERLAPPED m_OverlappedRead;

        OVERLAPPED m_OverlappedWrite;

        HANDLE m_hStopCommEvent;

        HANDLE m_hDataReady;

        memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED));

        m_OverlappedRead.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

        memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED));

        m_OverlappedWrite.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);


        // 初始化事件对象

        m_hStopCommEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

        m_hDataReady = CreateEvent(NULL, FALSE, FALSE, NULL);


        //初始化打印ESC @

        DWORD iBytesLength;

        char chInitCode[] = "\x0D\x1B\x40";

        if (!WriteFile(hPort, chInitCode, (DWORD)3L, &iBytesLength, NULL))

            return false;

    }


    return true;

}


int   WriteData(string meg)

{

    DWORD dwWrite;

    return WriteFile(hPort, meg.c_str(), (DWORD)meg.length(), &dwWrite, NULL);

}


//打印数据,meg打印字符串,bBold=true粗体,nZoom=2大一号字体, nHAil=2居中对齐,nHAil=3右对齐。部分打印机可能中文字体设置无效,请加上FS !命令设置中文字体。

bool OnWriteData(string meg, bool bBold, bool bDTall, bool bDWide, int nHAil)

{

    char s[120] = "";

    memset(s, 0, 120);


    long nMode = 0;

    DWORD iBytesLength;


    if (bBold)

        nMode += 8;


    if (bDTall)

        nMode += 16;


    if (bDWide)

        nMode += 32;


    if (nMode > 0)

    {

        sprintf(s, "\x1B\x21%c", nMode);


        if (strlen(s) < 3)

        {

            iBytesLength = 0;

            WriteFile(hPort, s, (DWORD)3L, &iBytesLength, NULL);

        }

        else

            WriteData(s);

    }


    switch (nHAil)

    {

    case 1:

        break;

    case 2:

        strcat(s, "\x1B\x61\x01");

        WriteData(s);

        break;

    case 3:

        strcat(s, "\x1B\x61\x02");

        WriteData(s);

        break;

    default:

        break;

    }


    WriteData(meg);


    iBytesLength = 0;

    strcpy(s, "\x1B\x21\x00");

    WriteFile(hPort, s, (DWORD)3L, &iBytesLength, NULL);


    return true;

};


////////////////////////////////////////////////////////////////////////////////////////////////////////

//获取CreateFile的USB端口号

////////////////////////////////////////////////////////////////////////////////////////////////////////


// 根据GUID获得设备路径

// lpGuid: GUID指针

// pszDevicePath: 设备路径指针的指针,用于返回找到的路径

// 返回: 成功得到的设备路径个数,可能不止1个

int GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath)

{

    HDEVINFO hDevInfoSet;

    SP_DEVINFO_DATA spDevInfoData;

    SP_DEVICE_INTERFACE_DATA ifData;

    PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;

    int nCount;

    int nTotle;

    BOOL bResult;


    char* strUSBPrint = "USB 打印支持";


    // 取得一个该GUID相关的设备信息集句柄

    hDevInfoSet = ::SetupDiGetClassDevs(lpGuid,     // class GUID 

        NULL,                    // 无关键字 

        NULL,                    // 不指定父窗口句柄 

        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);    // 目前存在的设备


    // 失败...

    if (hDevInfoSet == INVALID_HANDLE_VALUE)

    {

        return 0;

    }


    // 申请设备接口数据空间

    pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);


    pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);


    nTotle = -1;

    nCount = 0;

    bResult = TRUE;


    // 设备序号=0,1,2... 逐一测试设备接口,到失败为止

    while (bResult)

    {

        nTotle++;

        spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);


        // 枚举符合该GUID的设备接口

        bResult = ::SetupDiEnumDeviceInfo(

            hDevInfoSet,     // 设备信息集句柄

            (ULONG)nTotle,   // 设备信息集里的设备序号

            &spDevInfoData);        // 设备接口信息


        if (bResult)

        {

            DWORD DataT ;

            TCHAR buf[MAX_PATH];

            DWORD nSize = 0;


            // get Friendly Name or Device Description

            if ( SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData, 

                SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize) ) {

            } else if ( SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData, 

                SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize) ) {

            } else {

                lstrcpy(buf, _T("Unknown"));

            }


            //是否是要找的设备类型

            if (strcmp(buf, strUSBPrint) != 0)

                continue;


            ifData.cbSize = sizeof(ifData);


            // 枚舉符合該GUID的設備接口

            bResult = ::SetupDiEnumDeviceInterfaces(

                hDevInfoSet,     // 設備信息集句柄

                NULL,            // 不需額外的設備描述

                lpGuid,          // GUID

                (ULONG)nTotle,   // 設備信息集里的設備序號

                &ifData);        // 設備接口信息


            if (bResult)

            {

                // 取得该设备接口的细节(设备路径)

                bResult = SetupDiGetInterfaceDeviceDetail(

                    hDevInfoSet,    // 设备信息集句柄

                    &ifData,        // 设备接口信息

                    pDetail,        // 设备接口细节(设备路径)

                    INTERFACE_DETAIL_SIZE,    // 输出缓冲区大小

                    NULL,           // 不需计算输出缓冲区大小(直接用设定值)

                    NULL);          // 不需额外的设备描述


                if (bResult)

                {

                    // 复制设备路径到输出缓冲区

                    ::strcpy_s(pszDevicePath[nCount], 256,pDetail->DevicePath);  

                    // 调整计数值

                    nCount++;

                }

            }

        }

    }


    // 释放设备接口数据空间

    ::GlobalFree(pDetail);


    // 关闭设备信息集句柄

    ::SetupDiDestroyDeviceInfoList(hDevInfoSet);


    return nCount;

}


用VC++实现USB接口读写数据的程序 

使用一个GUIDguidHID_1查找并打开一个USB设备

extern "C" int PASCAL SearchUSBDevice()

{

HANDLE hUsb;


int nCount, i, j;//标记同一设备个数

HDEVINFO hDevInfoSet;

BOOL bResult;


PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail =NULL;


memset(m_sysversion, 0, 20);

GetSysVersion(m_sysversion);


// 检索相关GUID的USB设备总设备个数

if (!GetUSBList())

{

return 0;

}

// 取得一个该GUID相关的设备信息集句柄

hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // class GUID 

NULL, // 无关键字 

NULL, // 不指定父窗口句柄 

DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备


// 失败...

if (hDevInfoSet == INVALID_HANDLE_VALUE)

{

return NULL;

}


// 申请设备接口数据空间


nCount = 0;

bResult = TRUE;

for (i=0; i< 34; i++)

{

bDeviceOpen[i] = FALSE;

memset(m_DeviceDesc[i], 0, 256);

}


SP_DEVICE_INTERFACE_DATA ifdata;

// 设备序号=0,1,2... 逐一测试设备接口,到失败为止

while (bResult)

{


ifdata.cbSize = sizeof(ifdata);

// 枚举符合该GUID的设备接口

bResult = ::SetupDiEnumDeviceInterfaces(

hDevInfoSet, // 设备信息集句柄

NULL, // 不需额外的设备描述

(LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // GUID

(ULONG)nCount, // 设备信息集里的设备序号

&ifdata); // 设备接口信息


if (bResult)

{

ULONG predictedLength = 0;

ULONG requiredLength = 0;

// 取得该设备接口的细节(设备路径)

bResult = SetupDiGetInterfaceDeviceDetail(

hDevInfoSet, // 设备信息集句柄

&ifdata, // 设备接口信息

NULL, // 设备接口细节(设备路径)

0, // 输出缓冲区大小

&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)

NULL); // 不需额外的设备描述

// 取得该设备接口的细节(设备路径)

predictedLength=requiredLength;


// if(pDetail)

// {

// pDetail =NULL;

// }

pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, predictedLength);

pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

bResult = SetupDiGetInterfaceDeviceDetail(

hDevInfoSet, // 设备信息集句柄

&ifdata, // 设备接口信息

pDetail, // 设备接口细节(设备路径)

predictedLength, // 输出缓冲区大小

&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)

NULL); // 不需额外的设备描述


if (bResult)

{

// 复制设备路径到输出缓冲区

//::strcpy(pszDevicePath[nCount], pDetail->DevicePath);

if (strcmp(m_sysversion, "winnt")==0)

{

char ch[18];

for(i=0;i<17;i++){

ch[i]=*(pDetail->DevicePath+8+i);

}

ch[17]='\0';

if (strcmp(ch,"vid_0471&pid_0666")==0)//比较版本号,防止意外出错

{


memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ; 

memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ; 


READ_OS.hEvent = CreateEvent( NULL, // no security

TRUE, // explicit reset req

FALSE, // initial event reset

NULL ) ; // no name

if (READ_OS.hEvent == NULL) 

{

break;

}


WRITE_OS.hEvent = CreateEvent( NULL, // no security

TRUE, // explicit reset req

FALSE, // initial event reset

NULL ) ; // no name

if (NULL == WRITE_OS.hEvent)

{

CloseHandle( READ_OS.hEvent );

break;

}


hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,//

GENERIC_READ|GENERIC_WRITE,

FILE_SHARE_READ|FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL/*|

FILE_FLAG_OVERLAPPED*/,

NULL);

if (hUsb != NULL)

{

// 比较定位找到的USB在哪个USB PORT上

char id[30];

memset(id, 0, 30);

i=0;

do

{

id[i]=*(pDetail->DevicePath+26+i);

i++;

}

while(id[i-1]!='#');

id[i-1] = '\0';

for (j=0; j<34; j++)

{

if(strcmp(id, m_USBList[j])==0)

{

sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath);

m_USBPositionMap[nCount] = j+1;

break;

}

}


CloseHandle(hUsb);

nCount++;

// break;

}

}// 比较驱动版本

}// 比较操作系统版本

else

{

memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ; 

memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ; 


READ_OS.hEvent = CreateEvent( NULL, // no security

TRUE, // explicit reset req

FALSE, // initial event reset

NULL ) ; // no name

if (READ_OS.hEvent == NULL) 

{

break;

}


WRITE_OS.hEvent = CreateEvent( NULL, // no security

TRUE, // explicit reset req

FALSE, // initial event reset

NULL ) ; // no name

if (NULL == WRITE_OS.hEvent)

{

CloseHandle( READ_OS.hEvent );

break;

}


hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,//

GENERIC_READ|GENERIC_WRITE,

FILE_SHARE_READ|FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL/*|

FILE_FLAG_OVERLAPPED*/,

NULL);

if (hUsb != NULL)

{

if(strcmp(pDetail->DevicePath, m_USBList[j])==0)

{

sprintf(m_DeviceDesc[j+1], "%s", pDetail->DevicePath);

m_USBPositionMap[nCount] = j+1;

break;

}

CloseHandle(hUsb);

nCount++;

// break;

}

}

}

}

}

// 释放设备接口数据空间

::GlobalFree(pDetail);


// 关闭设备信息集句柄

::SetupDiDestroyDeviceInfoList(hDevInfoSet);


iDeviceCount = nCount;


return nCount;

}


// 写

BOOL Writestr(char *buf,int buflen, int index)

{

BOOL fWriteStat;

DWORD dwErrorFlags;

DWORD dwError;

COMSTAT ComStat;

char szError[ 10 ] ;

DWORD ret;

int len, i, j, packet;

div_t div_result;

BYTE sendpacket[65];

BYTE xorcode="0x00";


if (m_gphdCom[index] == NULL) // no usb device(jk100c)

{

return -1;

}


div_result = div(buflen, 58);

if (div_result.rem == 0)

{

packet = div_result.quot;

}

else

{

packet = div_result.quot+1;

}

for (i=0; i<packet; i++)

{

memset(sendpacket, 0, 65);

if(i==packet-1)

{

// end packet

if (div_result.rem == 0)

{

len = 58;

}

else

{

len = div_result.rem;

}

}

else

{

len = 58;

}

sendpacket[0] = 0x13;

sendpacket[1] = 3+len;

sendpacket[2] = 0x01;

sendpacket[3] = packet*16+i+1;

memcpy(sendpacket+4, buf+(i*58), len);

for(j=0;j<len+3;j++)

{

xorcode^=sendpacket[j+1];

}

sendpacket[len+4] = (char)xorcode;

sendpacket[len+5] = 0x23;

PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);

// Sleep(10);

fWriteStat = WriteFile(m_gphdCom[index], sendpacket, len+6,&ret, NULL);

if (!fWriteStat) 

{

if(GetLastError() == ERROR_IO_PENDING)

{

dwError = GetLastError();

// an error occurred, try to recover

wsprintf( szError, "\n\r <CE-%u>", dwError ) ;

OutputDebugString(szError);

ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;

if (dwErrorFlags >0)

{

wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;

OutputDebugString(szError);

}

}

else

// some other error occurred

ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;

if (dwErrorFlags > 0)

{

wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;

OutputDebugString(szError);

}

return FALSE;

}

}

if (i != packet-1)

{

// should be receive ack

if (ReceivePacketAnswer(index) != 0)

{

return FALSE;

}

}

}


return TRUE;

}


// 读

int Readstr(char *buf,int nMaxLength, int index)

{

BOOL fReadStat ;

COMSTAT ComStat;

DWORD dwErrorFlags;

DWORD dwLength;

DWORD dwError;

char szError[ 10 ];


if (fCOMMOpened==0)

{

return FALSE; //串口未打开

}


// only try to read number of bytes in queue 

ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat) ;

//dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;


dwLength=nMaxLength;

if (dwLength > 0)

{

if (olap==TRUE) 

{

fReadStat = ReadFile(m_gphdCom[index],buf, dwLength, &dwLength,&READ_OS) ;

if (!fReadStat)

{

if (GetLastError() == ERROR_IO_PENDING)

{

OutputDebugString("\n\rIO Pending");

while(!GetOverlappedResult(m_gphdCom[index], &READ_OS, 

&dwLength, TRUE ))

{

dwError = GetLastError();

if(dwError == ERROR_IO_INCOMPLETE) continue;

else

{

// an error occurred, try to recover

ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;

break;

}

}

}

else // end-----if (GetLastError() == ERROR_IO_PENDING)

{

// some other error occurred

dwLength = 0 ;

ClearCommError(m_gphdCom[index], &dwErrorFlags, &ComStat ) ;

if (dwErrorFlags >0)

{

wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;

OutputDebugString(szError);

}

}

} // end-----if (!fReadStat) 

} // end-----if (olap==TRUE) 

else

{

fReadStat = ReadFile( m_gphdCom[index],buf, dwLength, &dwLength, NULL ) ;

if (!fReadStat)

{

dwError = GetLastError();

ClearCommError(m_gphdCom[index],&dwErrorFlags, &ComStat ) ;


if (dwErrorFlags >0)

{

wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;

OutputDebugString(szError);

}

}

PurgeComm(m_gphdCom[index],PURGE_RXCLEAR|PURGE_TXCLEAR);

}

}


return dwLength;

}


Top