| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- #pragma once
- #include "../print/CPosPrinterData.h"
- #include <memory>
- #include <mutex>
- #include <thread>
- //端口的物理类型,用于热插拔后重开句柄时区分配置方式
- enum class PrinterPortKind
- {
- Usb,
- Bingkou,
- Com
- };
- //每个物理端口一个发送通道,线程独立、互不阻塞
- struct CPortSendChannel
- {
- HANDLE hPort = NULL;
- std::wstring portPath; //重开句柄用的端口路径(usb设备路径 / lpt1 / COMx)
- PrinterPortKind portKind = PrinterPortKind::Usb;
- std::queue<std::string> queue;
- std::mutex mtx;
- //不用条件变量:worker 采用短睡轮询(与 HandleShouyinPrinter 等一致),
- //避免任何"阻塞等待-唤醒"路径上的崩溃
- bool stop = false;
- std::thread worker;
- };
- //这个类采用队列的模式,执行把数据发送给打印机,注意这个类只负责发送,不负责数据内容的组装
- class CPosPrinterWorker
- {
- public:
- static CPosPrinterWorker* GetInstance()
- {
- static CPosPrinterWorker instance;
- return &instance;
- }
- //启动工作线程
- void Start();
- //结束工作线程
- void Stop();
- //把打印数据添加到消息队列
- void AddShouyinPrinter(std::string data);
- void AddBiaoqianPrinter(std::string data);
- void AddChufangPrinter(ChufangPrinterContent chufang_data);
- //打印机类型或端口设置变更后调用,重建收银打印端口通道
- void RefreshShouyinChannels();
- //从队列中读数据
- void HandleShouyinPrinter();
- void HandleBiaoqianPrinter();
- void HandleChufangPrinter();
- //执行实际的数据往打印机的发送
- void SendDataToShouyinPirnter(std::string data);
- void SendDataToBiaoqianPirnter(std::string data);
- void SendDataToChufangPirnter(ChufangPrinterContent chufang_data);
- //获取当前电脑上所有的打印usb设备
- std::vector<std::wstring> getUsbDevices();
- private:
- CPosPrinterWorker();
- //自动识别用于收银小票的USB打印机列表
- void InitUsb();
- //打开某一个指定的usb端口
- //nType 1 收银打印 2标签打印
- bool InitOneUsb(std::wstring usb_path, int nType);
- bool InitBingkou();
- void InitCom();
- //获取USB打印机的路径,用于收银小票打印机的智能识别,也用于设置中心获取所有打印机
- int GetDevicePath(LPGUID lpGuid, std::vector<std::wstring>& usb_devices);
- bool WriteWithTimeout(HANDLE hPort, const void* buffer, DWORD bufferSize, DWORD timeoutMs, DWORD& dwWrite);
- bool ReadWithTimeout(HANDLE hPort, void* buffer, DWORD bufferSize, DWORD timeoutMs, DWORD& dwRead);
- //通道的建立与销毁,在Start和设置变更时调用,不再每张票都开关端口
- void StartShouyinChannels();
- void StopShouyinChannels();
- void ChannelWorker(std::shared_ptr<CPortSendChannel> ch);
- //串口/并口/USB各自的句柄打开与配置,复用于通道建立与热插拔重开
- HANDLE OpenComPort(const std::wstring& com_path);
- bool OpenChannelHandle(std::shared_ptr<CPortSendChannel> ch);
- private:
- std::queue<std::string> m_shouyin_printer_queue;
- std::queue<std::string> m_biaoqian_printer_queue;
- std::queue<ChufangPrinterContent> m_chufang_printer_queue;
- std::mutex m_shouyin_printer_mutex;
- std::mutex m_biaoqian_printer_mutex;
- std::mutex m_chufang_printer_mutex;
- std::atomic<bool> m_is_work = false;
- //收银小票打印的句柄组合
- std::vector<HANDLE> m_hShouyinPorts;
- //标签小票打印的句柄组合
- std::vector<HANDLE> m_hBiaoqianPorts;
- //usb打印机的描述集合,用于收银小票打印机的智能识别模式
- std::vector<std::wstring> m_usb_devices;
- //收银打印的端口通道,句柄常驻打开,每个端口一个发送线程
- std::vector<std::shared_ptr<CPortSendChannel>> m_shouyin_channels;
- std::mutex m_shouyin_channels_mutex;
- };
|