CPosPrinterWorker.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #pragma once
  2. #include "../print/CPosPrinterData.h"
  3. #include <memory>
  4. #include <mutex>
  5. #include <thread>
  6. //端口的物理类型,用于热插拔后重开句柄时区分配置方式
  7. enum class PrinterPortKind
  8. {
  9. Usb,
  10. Bingkou,
  11. Com
  12. };
  13. //每个物理端口一个发送通道,线程独立、互不阻塞
  14. struct CPortSendChannel
  15. {
  16. HANDLE hPort = NULL;
  17. std::wstring portPath; //重开句柄用的端口路径(usb设备路径 / lpt1 / COMx)
  18. PrinterPortKind portKind = PrinterPortKind::Usb;
  19. std::queue<std::string> queue;
  20. std::mutex mtx;
  21. //不用条件变量:worker 采用短睡轮询(与 HandleShouyinPrinter 等一致),
  22. //避免任何"阻塞等待-唤醒"路径上的崩溃
  23. bool stop = false;
  24. std::thread worker;
  25. };
  26. //这个类采用队列的模式,执行把数据发送给打印机,注意这个类只负责发送,不负责数据内容的组装
  27. class CPosPrinterWorker
  28. {
  29. public:
  30. static CPosPrinterWorker* GetInstance()
  31. {
  32. static CPosPrinterWorker instance;
  33. return &instance;
  34. }
  35. //启动工作线程
  36. void Start();
  37. //结束工作线程
  38. void Stop();
  39. //把打印数据添加到消息队列
  40. void AddShouyinPrinter(std::string data);
  41. void AddBiaoqianPrinter(std::string data);
  42. void AddChufangPrinter(ChufangPrinterContent chufang_data);
  43. //打印机类型或端口设置变更后调用,重建收银打印端口通道
  44. void RefreshShouyinChannels();
  45. //从队列中读数据
  46. void HandleShouyinPrinter();
  47. void HandleBiaoqianPrinter();
  48. void HandleChufangPrinter();
  49. //执行实际的数据往打印机的发送
  50. void SendDataToShouyinPirnter(std::string data);
  51. void SendDataToBiaoqianPirnter(std::string data);
  52. void SendDataToChufangPirnter(ChufangPrinterContent chufang_data);
  53. //获取当前电脑上所有的打印usb设备
  54. std::vector<std::wstring> getUsbDevices();
  55. private:
  56. CPosPrinterWorker();
  57. //自动识别用于收银小票的USB打印机列表
  58. void InitUsb();
  59. //打开某一个指定的usb端口
  60. //nType 1 收银打印 2标签打印
  61. bool InitOneUsb(std::wstring usb_path, int nType);
  62. bool InitBingkou();
  63. void InitCom();
  64. //获取USB打印机的路径,用于收银小票打印机的智能识别,也用于设置中心获取所有打印机
  65. int GetDevicePath(LPGUID lpGuid, std::vector<std::wstring>& usb_devices);
  66. bool WriteWithTimeout(HANDLE hPort, const void* buffer, DWORD bufferSize, DWORD timeoutMs, DWORD& dwWrite);
  67. bool ReadWithTimeout(HANDLE hPort, void* buffer, DWORD bufferSize, DWORD timeoutMs, DWORD& dwRead);
  68. //通道的建立与销毁,在Start和设置变更时调用,不再每张票都开关端口
  69. void StartShouyinChannels();
  70. void StopShouyinChannels();
  71. void ChannelWorker(std::shared_ptr<CPortSendChannel> ch);
  72. //串口/并口/USB各自的句柄打开与配置,复用于通道建立与热插拔重开
  73. HANDLE OpenComPort(const std::wstring& com_path);
  74. bool OpenChannelHandle(std::shared_ptr<CPortSendChannel> ch);
  75. private:
  76. std::queue<std::string> m_shouyin_printer_queue;
  77. std::queue<std::string> m_biaoqian_printer_queue;
  78. std::queue<ChufangPrinterContent> m_chufang_printer_queue;
  79. std::mutex m_shouyin_printer_mutex;
  80. std::mutex m_biaoqian_printer_mutex;
  81. std::mutex m_chufang_printer_mutex;
  82. std::atomic<bool> m_is_work = false;
  83. //收银小票打印的句柄组合
  84. std::vector<HANDLE> m_hShouyinPorts;
  85. //标签小票打印的句柄组合
  86. std::vector<HANDLE> m_hBiaoqianPorts;
  87. //usb打印机的描述集合,用于收银小票打印机的智能识别模式
  88. std::vector<std::wstring> m_usb_devices;
  89. //收银打印的端口通道,句柄常驻打开,每个端口一个发送线程
  90. std::vector<std::shared_ptr<CPortSendChannel>> m_shouyin_channels;
  91. std::mutex m_shouyin_channels_mutex;
  92. };