|
|
@@ -1,12 +1,8 @@
|
|
|
#include "../pch/pch.h"
|
|
|
#include "CPosPrinter.h"
|
|
|
|
|
|
-#include <winioctl.h>
|
|
|
-#include <setupapi.h>
|
|
|
-
|
|
|
#include "../tool/CComHelper.h"
|
|
|
-
|
|
|
-using boost::asio::ip::tcp;
|
|
|
+#include "../helper/CBitmapHelper.h"
|
|
|
|
|
|
CPosPrinter::CPosPrinter(): m_socket(m_io)
|
|
|
{
|
|
|
@@ -17,6 +13,10 @@ CPosPrinter::~CPosPrinter()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ *usbType是1表示只查找收银小票打印机,会排除已知的标签打印机
|
|
|
+ *usbType为2表示所有usb打印机都查找,包含标签与非标签
|
|
|
+ **/
|
|
|
void CPosPrinter::InitUsb(int usbType)
|
|
|
{
|
|
|
//设置中文字符
|
|
|
@@ -33,7 +33,7 @@ void CPosPrinter::InitUsb(int usbType)
|
|
|
{
|
|
|
LOG_INFO("准备打开端口 Port = " << m_usb_devices[i].c_str());
|
|
|
|
|
|
- HANDLE hPort = CreateFile(m_usb_devices[i].c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
|
|
+ HANDLE hPort = CreateFile(m_usb_devices[i].c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
|
|
if(hPort == INVALID_HANDLE_VALUE)
|
|
|
{
|
|
|
@@ -76,7 +76,7 @@ void CPosPrinter::InitUsb(int usbType)
|
|
|
|
|
|
void CPosPrinter::InitOneUsb(wstring usb_path)
|
|
|
{
|
|
|
- HANDLE hPort = CreateFile(usb_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
|
|
+ HANDLE hPort = CreateFile(usb_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
|
|
if(hPort == INVALID_HANDLE_VALUE)
|
|
|
{
|
|
|
@@ -235,8 +235,8 @@ void CPosPrinter::InitShouyin()
|
|
|
//开始添加并口的端口
|
|
|
InitBingkou();
|
|
|
|
|
|
- //开始添加串口
|
|
|
- InitCom();
|
|
|
+ //智能识别模式不再自动处理串口,串口的需要人工去选择类型
|
|
|
+ //InitCom();
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -478,10 +478,12 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
|
|
|
}
|
|
|
|
|
|
POS_FeedLine();
|
|
|
+
|
|
|
//订单来源
|
|
|
string from_type = "订单来源:" + CLewaimaiString::UTF8ToANSI(order.m_from_type);
|
|
|
POS_TextOut(from_type);
|
|
|
POS_FeedLine();
|
|
|
+
|
|
|
//订单号
|
|
|
bool setting_printer_dingdanhao_big = false;
|
|
|
|
|
|
@@ -493,6 +495,7 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
|
|
|
string order_num = "订 单 号:" + CLewaimaiString::UTF8ToANSI(order.m_order_num);
|
|
|
POS_TextOut(order_num, false, setting_printer_dingdanhao_big);
|
|
|
POS_FeedLine();
|
|
|
+
|
|
|
//下单时间
|
|
|
bool setting_printer_xiadanshijian_big = false;
|
|
|
|
|
|
@@ -504,6 +507,7 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
|
|
|
string order_date = "下单时间:" + CLewaimaiString::UTF8ToANSI(order.m_order_date);
|
|
|
POS_TextOut(order_date, false, setting_printer_xiadanshijian_big);
|
|
|
POS_FeedLine();
|
|
|
+
|
|
|
//配送时间
|
|
|
bool setting_printer_peisongshijian_big = false;
|
|
|
|
|
|
@@ -551,6 +555,7 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
|
|
|
string phone = "电话:" + CLewaimaiString::UTF8ToANSI(order.m_phone);
|
|
|
POS_TextOut(phone, false, setting_printer_phone_big);
|
|
|
POS_FeedLine();
|
|
|
+
|
|
|
//地址
|
|
|
bool setting_printer_address_big = false;
|
|
|
|
|
|
@@ -682,6 +687,7 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
|
|
|
//结束商品详情打印
|
|
|
POS_TextOut(lines);
|
|
|
POS_FeedLine();
|
|
|
+
|
|
|
//开始打印其他的费用
|
|
|
bool is_other_money = false;
|
|
|
bool setting_printer_price_big = false;
|
|
|
@@ -775,6 +781,7 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
|
|
|
//最后显示总价
|
|
|
POS_TextOut("总计:¥" + CLewaimaiString::DoubleToString(order.m_price, 2), false, setting_printer_price_big, 2);
|
|
|
POS_FeedLine();
|
|
|
+
|
|
|
//显示付款方式
|
|
|
bool setting_printer_pay_big = false;
|
|
|
|
|
|
@@ -791,11 +798,28 @@ void CPosPrinter::PrintWaimaiOrderShouyin(CWaimaiOrder& order)
|
|
|
std::string order_no = order.m_order_no;
|
|
|
order_no = CLewaimaiString::UTF8ToANSI(order_no);
|
|
|
|
|
|
- POS_Reset();
|
|
|
- POS_OutQRCode(order_no);
|
|
|
+ CBitmapHelper helper;
|
|
|
+ helper.LoadImage(L"D:\\800.bmp");
|
|
|
|
|
|
- Gdiplus::Bitmap bmp(L"D:\\aaa.jpg");
|
|
|
- PrintBmp(&bmp);
|
|
|
+ Bitmap* bmp = helper.getBmp();
|
|
|
+
|
|
|
+ //先进行图片预处理
|
|
|
+ unsigned int nWidth = bmp->GetWidth();
|
|
|
+ unsigned int nHeight = bmp->GetHeight();
|
|
|
+
|
|
|
+ //压缩尺寸
|
|
|
+ if (nWidth > 380)
|
|
|
+ {
|
|
|
+ int newWidth = 380;
|
|
|
+ int newHeight = (int)(nHeight / (nWidth / 380.0));
|
|
|
+
|
|
|
+ helper.ScaleBitmap(newWidth, newHeight);;
|
|
|
+ }
|
|
|
+
|
|
|
+ //二值化
|
|
|
+ helper.Image2Values();
|
|
|
+
|
|
|
+ PrintBmp(helper.getBmp());
|
|
|
|
|
|
//走纸几行再切
|
|
|
POS_FeedLine();
|
|
|
@@ -1230,7 +1254,7 @@ int CPosPrinter::WriteBuf(const unsigned char* buf, int len)
|
|
|
{
|
|
|
HANDLE hPort = (*it).hPort;
|
|
|
|
|
|
- if((*it).type == 3)
|
|
|
+ if((*it).type == 1 || (*it).type == 3)
|
|
|
{
|
|
|
//串口,同步写数据
|
|
|
//LOG_INFO("before com writefile handle:" << hPort);
|
|
|
@@ -1952,256 +1976,61 @@ std::vector<std::string> CPosPrinter::HandleBiaoqianFoodname(std::string oldname
|
|
|
return newnameArray;
|
|
|
}
|
|
|
|
|
|
-void ToGray(Bitmap * pOrgBitmap, Bitmap **pDesBitmap)
|
|
|
-{
|
|
|
-
|
|
|
- int width = pOrgBitmap->GetWidth();
|
|
|
- int height = pOrgBitmap->GetHeight();
|
|
|
-
|
|
|
- switch(pOrgBitmap->GetPixelFormat()) //像素格式不同,灰度化处理方式也不同
|
|
|
- {
|
|
|
- case PixelFormat24bppRGB:
|
|
|
- {
|
|
|
- Rect rect(0, 0, width, height);
|
|
|
- BYTE byte;
|
|
|
- BitmapData bitmapData_org, bitmapData_new;
|
|
|
- Bitmap *pGrayImg = new Bitmap(width, height, PixelFormat8bppIndexed); // 建立带索引的位图PixelFormat8bppIndexed,此种格式的位图,一个像素占一个字节
|
|
|
- ColorPalette *pal = (ColorPalette *)malloc(sizeof(ColorPalette) + 256 * sizeof(ARGB));
|
|
|
- pal->Count = 256;
|
|
|
- pal->Flags = 2;
|
|
|
-
|
|
|
- for(int m = 0; m < 256; m++)
|
|
|
- {
|
|
|
- pal->Entries[m] = Color::MakeARGB(255, m, m, m);
|
|
|
- }
|
|
|
-
|
|
|
- pGrayImg->SetPalette(pal);
|
|
|
- free(pal); // 释放掉malloc开辟的空间
|
|
|
- pGrayImg->LockBits(&rect, ImageLockModeWrite, PixelFormat8bppIndexed, &bitmapData_new); //锁定位图,然后对其进行读写内存操作,相关信息保存到BitmapData中
|
|
|
- Status iSucess = pOrgBitmap->LockBits(
|
|
|
- &rect,
|
|
|
- ImageLockModeWrite,
|
|
|
- PixelFormat24bppRGB,
|
|
|
- &bitmapData_org);
|
|
|
-
|
|
|
- BYTE *p = (BYTE*)bitmapData_org.Scan0; //原图rect区域内存位置的起始指针,以BYTE作为单元类型
|
|
|
- BYTE *q = (BYTE*)bitmapData_new.Scan0; //目标位图rect区域的起始指针
|
|
|
- BYTE *pt = p, *qt = q;
|
|
|
- BYTE val;
|
|
|
-
|
|
|
- // 灰度化
|
|
|
- for(int i = 0; i < height; i++)
|
|
|
- {
|
|
|
- pt = p + i * bitmapData_org.Stride; //Stride为rect区域一行所占的字节数
|
|
|
- qt = q + i * bitmapData_new.Stride;
|
|
|
-
|
|
|
- for(int j = 0; j < width; j++)
|
|
|
- {
|
|
|
- val = *(pt) * 0.114 + (*(pt + 1)) * 0.587 + (*(pt + 2)) * 0.299;
|
|
|
-
|
|
|
- if(val > 255)
|
|
|
- {
|
|
|
- val = 255;
|
|
|
- }
|
|
|
-
|
|
|
- if(val < 0)
|
|
|
- {
|
|
|
- val = 0;
|
|
|
- }
|
|
|
-
|
|
|
- *qt = val; //根据红绿蓝求出此像素的灰度值,写入目标位图内存*qt中
|
|
|
- pt += 3; //原图一个像素占3个字节,所以,计算下一个像素灰度值时,指针要挪移3个单元
|
|
|
- qt += 1; //目标位图一个像素占一个字节,所以,设置下一个像素灰度值时,指针只需挪移1个单元
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pOrgBitmap->UnlockBits(&bitmapData_org); //源图像撤销锁定
|
|
|
- pGrayImg->UnlockBits(&bitmapData_new); // 目标图像撤销锁定
|
|
|
- *pDesBitmap = pGrayImg; //将目标图像的地址保存到*pDesBitmap中
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case PixelFormat32bppARGB:
|
|
|
- {
|
|
|
- Rect rect(0, 0, width, height);
|
|
|
- BYTE byte;
|
|
|
- BitmapData bitmapData_org, bitmapData_new;
|
|
|
- Bitmap *pGrayImg = new Bitmap(width, height, PixelFormat8bppIndexed);
|
|
|
- ColorPalette *pal = (ColorPalette *)malloc(sizeof(ColorPalette) + 256 * sizeof(ARGB));
|
|
|
- pal->Count = 256;
|
|
|
- pal->Flags = 0;
|
|
|
-
|
|
|
- for(int m = 0; m < 256; m++)
|
|
|
- {
|
|
|
- pal->Entries[m] = Color::MakeARGB(255, m, m, m);
|
|
|
- }
|
|
|
-
|
|
|
- pGrayImg->SetPalette(pal);
|
|
|
- free(pal); // 释放掉malloc开辟的空间
|
|
|
-
|
|
|
- pGrayImg->LockBits(&rect, ImageLockModeWrite, PixelFormat8bppIndexed, &bitmapData_new);
|
|
|
- Status iSucess = pOrgBitmap->LockBits(
|
|
|
- &rect,
|
|
|
- ImageLockModeWrite,
|
|
|
- PixelFormat32bppARGB,
|
|
|
- &bitmapData_org);
|
|
|
-
|
|
|
- BYTE *p = (BYTE*)bitmapData_org.Scan0;
|
|
|
- BYTE *q = (BYTE*)bitmapData_new.Scan0;
|
|
|
- BYTE *pt = p, *qt = q;
|
|
|
- BYTE val;
|
|
|
-
|
|
|
- // 灰度化
|
|
|
- for(int i = 0; i < height; i++)
|
|
|
- {
|
|
|
- pt = p + i * bitmapData_org.Stride;
|
|
|
- qt = q + i * bitmapData_new.Stride;
|
|
|
-
|
|
|
- for(int j = 0; j < width; j++)
|
|
|
- {
|
|
|
- val = *(pt + 1) * 0.114 + (*(pt + 2)) * 0.587 + (*(pt + 3)) * 0.299;
|
|
|
-
|
|
|
- if(val > 255)
|
|
|
- {
|
|
|
- val = 255;
|
|
|
- }
|
|
|
-
|
|
|
- if(val < 0)
|
|
|
- {
|
|
|
- val = 0;
|
|
|
- }
|
|
|
-
|
|
|
- *qt = val;
|
|
|
- pt += 4;
|
|
|
- qt += 1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pOrgBitmap->UnlockBits(&bitmapData_org);
|
|
|
- pGrayImg->UnlockBits(&bitmapData_new);
|
|
|
- *pDesBitmap = pGrayImg;
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case PixelFormat8bppIndexed: //之所以同为PixelFormat8bppIndexed还转换,
|
|
|
- // 是因为用m_pMemBmp=m_pImage->Clone(rect,m_pImage->GetPixelFormat())
|
|
|
- //克隆的内存位图,读写速度不如直接new Bitmap()生成的位图的读写速度快,不知道是为什么?
|
|
|
- // 所以这里,将Clone的位图再用new Bitmap 转换一下
|
|
|
- {
|
|
|
- Rect rect(0, 0, width, height);
|
|
|
- BYTE byte;
|
|
|
- BitmapData bitmapData_org, bitmapData_new;
|
|
|
- Bitmap *pGrayImg = new Bitmap(width, height, PixelFormat8bppIndexed);
|
|
|
- ColorPalette *pal = (ColorPalette *)malloc(sizeof(ColorPalette) + 256 * sizeof(ARGB));
|
|
|
- pal->Count = 256;
|
|
|
- pal->Flags = 0;
|
|
|
-
|
|
|
- for(int m = 0; m < 256; m++)
|
|
|
- {
|
|
|
- pal->Entries[m] = Color::MakeARGB(255, m, m, m);
|
|
|
- }
|
|
|
-
|
|
|
- pGrayImg->SetPalette(pal);
|
|
|
- free(pal); // 释放掉malloc开辟的空间
|
|
|
-
|
|
|
- pGrayImg->LockBits(&rect, ImageLockModeWrite, PixelFormat8bppIndexed, &bitmapData_new);
|
|
|
- Status iSucess = pOrgBitmap->LockBits(
|
|
|
- &rect,
|
|
|
- ImageLockModeWrite,
|
|
|
- PixelFormat8bppIndexed,
|
|
|
- &bitmapData_org);
|
|
|
-
|
|
|
- BYTE *p = (BYTE*)bitmapData_org.Scan0;
|
|
|
- BYTE *q = (BYTE*)bitmapData_new.Scan0;
|
|
|
- BYTE *pt = p, *qt = q;
|
|
|
- BYTE val;
|
|
|
-
|
|
|
- // 灰度化
|
|
|
- for(int i = 0; i < height; i++)
|
|
|
- {
|
|
|
- pt = p + i * bitmapData_org.Stride;
|
|
|
- qt = q + i * bitmapData_new.Stride;
|
|
|
-
|
|
|
- for(int j = 0; j < width; j++)
|
|
|
- {
|
|
|
- val = *pt;
|
|
|
- *qt = val;
|
|
|
- pt += 1;
|
|
|
- qt += 1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pOrgBitmap->UnlockBits(&bitmapData_org);
|
|
|
- pGrayImg->UnlockBits(&bitmapData_new);
|
|
|
- *pDesBitmap = pGrayImg;
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- *pDesBitmap = pOrgBitmap;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
void CPosPrinter::PrintBmp(Bitmap* bmp)
|
|
|
{
|
|
|
- //设置行间距
|
|
|
+ //设置行间距为0
|
|
|
unsigned char data[3] = { 0x1B, 0x33, 0x00 };
|
|
|
WriteBuf(data, 3);
|
|
|
|
|
|
- memset(data, 0, 3);
|
|
|
-
|
|
|
- Gdiplus::Color pixelColor;
|
|
|
+ //设置图像居中对齐
|
|
|
+ unsigned char data2[3] = { 0x1B, 0x61, 0x01 };
|
|
|
+ WriteBuf(data2, 3);
|
|
|
|
|
|
+ //选择位图模式
|
|
|
unsigned char escBmp[5] = { 0x1B, 0x2A, 0x21, 0x00, 0x00 };
|
|
|
|
|
|
- unsigned int nWidth = bmp->GetWidth();
|
|
|
- unsigned int nHeight = bmp->GetHeight();
|
|
|
+ unsigned int nWidth = bmp->GetWidth();
|
|
|
+ unsigned int nHeight = bmp->GetHeight();
|
|
|
|
|
|
escBmp[3] = (unsigned char)(nWidth % 256);
|
|
|
- escBmp[4] = (unsigned char)(nHeight / 256);
|
|
|
+ escBmp[4] = (unsigned char)(nWidth / 256);
|
|
|
+
|
|
|
+ Gdiplus::Color pixelColor;
|
|
|
|
|
|
//循环图片像素打印图片
|
|
|
- //循环高
|
|
|
- for(int i = 0; i < (nHeight / 24 + 1); i++)
|
|
|
+ for(unsigned int i = 0; i < (nHeight / 24 + 1); i++)
|
|
|
{
|
|
|
//设置模式为位图模式
|
|
|
WriteBuf(escBmp, 5);
|
|
|
|
|
|
+ unsigned char* dataTmp = new unsigned char[nWidth * 3];
|
|
|
+ memset(dataTmp, 0, nWidth * 3);
|
|
|
+
|
|
|
//循环宽
|
|
|
- for(int j = 0; j < nWidth; j++)
|
|
|
+ for(unsigned int j = 0; j < nWidth; j++)
|
|
|
{
|
|
|
- for(int k = 0; k < 24; k++)
|
|
|
+ for(unsigned int k = 0; k < 24; k++)
|
|
|
{
|
|
|
- if(((i * 24) + k) < nHeight) // if within the BMP size
|
|
|
+ //找到有像素的区域,也就是未超出位图高度的区域
|
|
|
+ if(((i * 24) + k) < nHeight)
|
|
|
{
|
|
|
bmp->GetPixel(j, (i * 24) + k, &pixelColor);
|
|
|
unsigned char r = pixelColor.GetR();
|
|
|
|
|
|
if(r == 0)
|
|
|
{
|
|
|
- data[k / 8] += (unsigned char)(128 >> (k % 8));
|
|
|
+ //如果本来是黑色的像素,那么就把对应的数据位设置为1
|
|
|
+ dataTmp[j * 3 + k / 8] += (unsigned char)(128 >> (k % 8));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- data[0] = 0xFF;
|
|
|
- data[1] = 0xFF;
|
|
|
- data[2] = 0xFF;
|
|
|
-
|
|
|
- //一次写入一个data,24个像素
|
|
|
- WriteBuf(data, 3);
|
|
|
-
|
|
|
- memset(data, 0, 3);
|
|
|
}
|
|
|
|
|
|
- //换行,打印第二行
|
|
|
- unsigned char data2[1] = { 0x0A };
|
|
|
- WriteBuf(data2, 1);
|
|
|
- } // data
|
|
|
+ WriteBuf(dataTmp, nWidth * 3);
|
|
|
+ delete[] dataTmp;
|
|
|
+ }
|
|
|
|
|
|
- unsigned char data3[2] = { 0x0A, 0x0A };
|
|
|
- WriteBuf(data3, 2);
|
|
|
+ //还原默认的行间距
|
|
|
+ unsigned char data3[2] = { 0x1B, 0x32};
|
|
|
+ WriteBuf(data3, 2);
|
|
|
}
|