C++调用USB小票打印机 第一种办法 无驱动
这种办法是抄于CSDN的,可以无驱动打印,但是有缺点的就是如果电脑连接了多台USB打印机,这种办法不行
//链接打印机
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;
}
posted on 2021-01-08 14:54 redmondfans 阅读(940) 评论(0) 编辑 收藏 举报