CValueWnd.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635
  1. #include "../pch/pch.h"
  2. #include "CValueWnd.h"
  3. #include "../tool/CComHelper.h"
  4. #include "../tool/CSerialPort.h"
  5. #include "../helper/CBitmapHelper.h"
  6. #include "../network/CMessagePush.h"
  7. #include "CLoginWnd.h"
  8. void CValueWnd::Notify(TNotifyUI& msg)
  9. {
  10. if(msg.sType == _T("click"))
  11. {
  12. if(msg.pSender->GetName() == _T("closebtn"))
  13. {
  14. PostQuitMessage(0);
  15. return;
  16. }
  17. }
  18. }
  19. void CValueWnd::Init()
  20. {
  21. //初始化窗口位置
  22. InitWndPos();
  23. //抢焦点
  24. std::thread(&CValueWnd::TopMostWnd, this).detach();
  25. //注册热键
  26. UpdateRegisterHotKey();
  27. //添加托盘图标
  28. AddTrayIcon();
  29. //登录成功,启动消息和任务处理
  30. m_push = new CMessagePush(m_hWnd);
  31. m_push->Start();
  32. //初始化菜单窗口
  33. pMenu = new CMenuWnd(this);
  34. pMenu->Create(NULL, L"智铺子收银插件菜单", WS_POPUP, WS_EX_TOOLWINDOW);
  35. pMenu->ShowWindow(false);
  36. //定位窗口的初始化
  37. pDingweiWnd = new CDingweiWnd();
  38. pDingweiWnd->Create(NULL, _T("智铺子收银插件窗口定位"), UI_WNDSTYLE_DIALOG, WS_EX_TOOLWINDOW, 0, 0, 0, 0, NULL);
  39. pDingweiWnd->ShowWindow(false);
  40. pDingweiInfoWnd = new CDingweiInfoWnd(this);
  41. pDingweiInfoWnd->Create(NULL, _T("智铺子收银插件窗口定位信息"), UI_WNDSTYLE_DIALOG, WS_EX_TOOLWINDOW, 0, 0, 0, 0, NULL);
  42. pDingweiInfoWnd->ShowWindow(false);
  43. //Ocr窗口初始化
  44. pOcrWnd = new COcrWnd(this);
  45. pOcrWnd->Create(NULL, _T("智铺子收银插件OCR定位"), UI_WNDSTYLE_FRAME, WS_EX_TOOLWINDOW , 0, 0, 0, 0, NULL);
  46. pOcrWnd->ShowWindow(false);
  47. //OCR的数据初始化
  48. if (m_tess.Init("./tessdata", "eng"))
  49. {
  50. LOG_INFO("OCRTesseract: Could not initialize tesseract.");
  51. MessageBox(m_hWnd, L"ocr语言库加载失败", L"错误", MB_OK);
  52. }
  53. m_tess.SetPageSegMode(tesseract::PageSegMode::PSM_SINGLE_LINE);
  54. m_tess.SetVariable("save_best_choices", "T");
  55. //开启键盘输入监听
  56. RegKeyboardRawInput();
  57. //再安装钩子
  58. BOOL ret = InstallHook();
  59. //开始启动监听
  60. RestartWatch();
  61. }
  62. /*
  63. *抢窗口前端,抢焦点
  64. **/
  65. void CValueWnd::TopMostWnd()
  66. {
  67. while (m_is_topmost)
  68. {
  69. ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  70. if (m_is_show_shoukuan && m_shoukuanWnd != NULL)
  71. {
  72. //::SendMessage(m_shoukuanWnd->GetHWND(), WM_SHOUKUAN_UPDATE_FOCUS, NULL, NULL);
  73. }
  74. Sleep(100);
  75. }
  76. m_is_topmost = true;
  77. }
  78. void CValueWnd::StopTopMostWnd()
  79. {
  80. m_is_topmost = false;
  81. while (m_is_topmost == false)
  82. {
  83. Sleep(120);
  84. }
  85. }
  86. void CValueWnd::RestartWatch()
  87. {
  88. std::thread(&CValueWnd::StartWatchWork, this).detach();
  89. }
  90. void CValueWnd::StopWatch()
  91. {
  92. m_isWatchWork = false;
  93. while (m_is_xunichuangkou_working || m_is_chuangkou_working || m_is_orc_working)
  94. {
  95. //等这3个线程全部退出
  96. Sleep(100);
  97. }
  98. }
  99. /*
  100. *根据当前数据库的设置,重启监听
  101. **/
  102. void CValueWnd::StartWatchWork()
  103. {
  104. //先暂停已有的监控
  105. StopWatch();
  106. //然后开始工作
  107. m_isWatchWork = true;
  108. std::string system_setting_jinezhuaqu_setting_type = CSetting::GetParam("system_setting_jinezhuaqu_setting_type");
  109. m_nWatchType = atoi(system_setting_jinezhuaqu_setting_type.c_str());
  110. if(m_nWatchType == 1)
  111. {
  112. //更新监听的端口号
  113. std::string system_setting_jinezhuaqu_setting_chuankou_num = CSetting::GetParam("system_setting_jinezhuaqu_setting_chuankou_num");
  114. if(system_setting_jinezhuaqu_setting_chuankou_num == "")
  115. {
  116. //参数错误
  117. return;
  118. }
  119. std::wstring ws_system_setting_jinezhuaqu_setting_chuankou_num = CLewaimaiString::UTF8ToUnicode(system_setting_jinezhuaqu_setting_chuankou_num);
  120. //设置窗口句柄
  121. ::SetHwnd(m_hWnd);
  122. //设置串口端口号
  123. std::transform(system_setting_jinezhuaqu_setting_chuankou_num.begin(), system_setting_jinezhuaqu_setting_chuankou_num.end(), system_setting_jinezhuaqu_setting_chuankou_num.begin(), ::toupper);
  124. std::transform(ws_system_setting_jinezhuaqu_setting_chuankou_num.begin(), ws_system_setting_jinezhuaqu_setting_chuankou_num.end(), ws_system_setting_jinezhuaqu_setting_chuankou_num.begin(), ::toupper);
  125. ::SetComNum(system_setting_jinezhuaqu_setting_chuankou_num.c_str(), ws_system_setting_jinezhuaqu_setting_chuankou_num.c_str(), system_setting_jinezhuaqu_setting_chuankou_num.size());
  126. }
  127. else if(m_nWatchType == 2)
  128. {
  129. //虚拟串口的模式
  130. std::thread(&CValueWnd::ReadXunichuankouValue, this).detach();
  131. }
  132. else if(m_nWatchType == 3)
  133. {
  134. //窗口模式
  135. m_watchWnd = NULL;
  136. std::thread(&CValueWnd::WatchWnd, this).detach();
  137. }
  138. else if (m_nWatchType == 4)
  139. {
  140. std::thread(&CValueWnd::StartOcrWork, this).detach();
  141. }
  142. }
  143. /*
  144. *读取客显金额的线程,一旦m_nWatchType不为2,那么就直接退出这个线程,下次设置的时候再开启
  145. **/
  146. void CValueWnd::ReadXunichuankouValue()
  147. {
  148. //读取虚拟串口的模式
  149. std::string system_setting_jinezhuaqu_setting_xunichuankou_num_2 = CSetting::GetParam("system_setting_jinezhuaqu_setting_xunichuankou_num_2");
  150. std::string system_setting_jinezhuaqu_setting_xunichuankou_botelv = CSetting::GetParam("system_setting_jinezhuaqu_setting_xunichuankou_botelv");
  151. CSerialPort serial(CLewaimaiString::UTF8ToUnicode(system_setting_jinezhuaqu_setting_xunichuankou_num_2), atoi(system_setting_jinezhuaqu_setting_xunichuankou_botelv.c_str()));
  152. bool ret = serial.openComm();
  153. if(!ret)
  154. {
  155. LOG_INFO("open com failed!");
  156. return;
  157. }
  158. m_is_xunichuangkou_working = true;
  159. char a[1024] = { 0 };
  160. //检查监控模式和波特率,如果变了就关闭掉
  161. while(m_nWatchType == 2 && m_isWatchWork)
  162. {
  163. memset(a, 0, 1024);
  164. //开始读取串口的数据
  165. DWORD nReaded = 0;
  166. serial.readFromComm(a, 1024, &nReaded);
  167. if(nReaded > 0)
  168. {
  169. UpdateKexian(a, nReaded);
  170. }
  171. Sleep(200);
  172. }
  173. serial.closeComm();
  174. m_is_xunichuangkou_working = false;
  175. }
  176. void CValueWnd::WatchWnd()
  177. {
  178. m_is_chuangkou_working = true;
  179. std::string system_setting_jinezhuaqu_setting_chuangkou_process_name = CSetting::GetParam("system_setting_jinezhuaqu_setting_chuangkou_process_name");
  180. std::string system_setting_jinezhuaqu_setting_chuangkou_title = CSetting::GetParam("system_setting_jinezhuaqu_setting_chuangkou_title");
  181. std::string system_setting_jinezhuaqu_setting_chuangkou_zorder = CSetting::GetParam("system_setting_jinezhuaqu_setting_chuangkou_zorder");
  182. //如果模式变了,或者参数变了,就退出(因为会重新启动一个新的监控)
  183. while(m_nWatchType == 3 && m_isWatchWork)
  184. {
  185. if(m_watchWnd != NULL)
  186. {
  187. std::wstring value;
  188. TCHAR szTitle[MAX_PATH] = { 0 };
  189. LPWSTR lpWindowName = szTitle;
  190. int ret = ::SendMessageW(m_watchWnd, WM_GETTEXT, (WPARAM)(MAX_PATH), (LPARAM)lpWindowName);
  191. if(ret == 0)
  192. {
  193. //说明m_watchWnd已经失效了
  194. value = L"0.00";
  195. m_watchWnd = NULL;
  196. }
  197. else
  198. {
  199. value = lpWindowName;
  200. //先对获取到的值做一下处理,删除掉人民币符号
  201. CLewaimaiString::Replace(value, L"¥", L"");
  202. }
  203. if(value != m_watchValue)
  204. {
  205. //保存下来窗口获取到的值
  206. m_watchValue = value;
  207. SendMessage(WM_WATCH_WND_UPDATE, NULL, NULL);
  208. }
  209. }
  210. else
  211. {
  212. //获得进程名字
  213. std::wstring processName = CLewaimaiString::UTF8ToUnicode(system_setting_jinezhuaqu_setting_chuangkou_process_name);
  214. //根据进程名字,找到对应的主窗口
  215. HWND mainWnd = GetWndHwnd(processName.c_str(), system_setting_jinezhuaqu_setting_chuangkou_title);
  216. if(mainWnd == NULL)
  217. {
  218. //说明这个进程还没有启动
  219. m_watchWnd = NULL;
  220. }
  221. else
  222. {
  223. //根据Z序查找目标窗口
  224. ValueWnd newWnd;
  225. newWnd.wndTitle = system_setting_jinezhuaqu_setting_chuangkou_title;
  226. newWnd.TopWnd = mainWnd;
  227. newWnd.z_order = atoi(system_setting_jinezhuaqu_setting_chuangkou_zorder.c_str());
  228. newWnd.processName = processName;
  229. newWnd.selfWnd = NULL;
  230. g_zorder = 0;
  231. EnumChildWindows(mainWnd, EnumMainwndChildProc, (LPARAM)(&newWnd));
  232. if(newWnd.selfWnd != NULL)
  233. {
  234. //找到了
  235. m_watchWnd = newWnd.selfWnd;
  236. }
  237. }
  238. }
  239. Sleep(200);
  240. }
  241. m_is_chuangkou_working = false;
  242. }
  243. void CValueWnd::StartOcrWork()
  244. {
  245. m_is_orc_working = true;
  246. int system_setting_jinezhuaqu_setting_ocr_left = atoi(CSetting::GetParam("system_setting_jinezhuaqu_setting_ocr_left").c_str());
  247. int system_setting_jinezhuaqu_setting_ocr_top = atoi(CSetting::GetParam("system_setting_jinezhuaqu_setting_ocr_top").c_str());
  248. int system_setting_jinezhuaqu_setting_ocr_right = atoi(CSetting::GetParam("system_setting_jinezhuaqu_setting_ocr_right").c_str());
  249. int system_setting_jinezhuaqu_setting_ocr_bottom = atoi(CSetting::GetParam("system_setting_jinezhuaqu_setting_ocr_bottom").c_str());
  250. //如果模式变了,或者参数变了,就退出(因为会重新启动一个新的监控)
  251. while (m_nWatchType == 4 && m_isWatchWork)
  252. {
  253. RECT rect;
  254. rect.left = system_setting_jinezhuaqu_setting_ocr_left;
  255. rect.top = system_setting_jinezhuaqu_setting_ocr_top;
  256. rect.right = system_setting_jinezhuaqu_setting_ocr_right;
  257. rect.bottom = system_setting_jinezhuaqu_setting_ocr_bottom;
  258. if (IsRectEmpty(&rect))
  259. {
  260. }
  261. else
  262. {
  263. CBitmapHelper helper;
  264. std::string ocr_result;
  265. bool ret = helper.OcrRect(m_tess, &rect, ocr_result);
  266. if (ret)
  267. {
  268. if (!atof(ocr_result.c_str()))
  269. {
  270. //识别结果不是有效的数字
  271. CLabelUI* valueLabel = static_cast<CLabelUI*>(m_pm.FindControl(_T("value")));
  272. valueLabel->SetText(L"0.00");
  273. }
  274. else
  275. {
  276. std::string format_value = CLewaimaiString::DoubleToString(atof(ocr_result.c_str()), 2);
  277. std::wstring ws_ocr_result = CLewaimaiString::UTF8ToUnicode(format_value);
  278. m_watchValue = ws_ocr_result;
  279. CLabelUI* valueLabel = static_cast<CLabelUI*>(m_pm.FindControl(_T("value")));
  280. valueLabel->SetText(ws_ocr_result.c_str());
  281. }
  282. }
  283. }
  284. Sleep(200);
  285. }
  286. m_is_orc_working = false;
  287. }
  288. LRESULT CValueWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  289. {
  290. LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
  291. styleValue &= ~WS_CAPTION;
  292. ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
  293. // 把自己的窗口句柄与窗口绘制管理器挂接在一起
  294. m_pm.Init(m_hWnd);
  295. m_pm.AddPreMessageFilter(this);
  296. CDialogBuilder builder;
  297. CControlUI* pRoot = builder.Create(_T("value.xml"), (UINT)0, NULL, &m_pm);
  298. ASSERT(pRoot && "Failed to parse XML");
  299. // 把这些控件绘制到本窗口上
  300. m_pm.AttachDialog(pRoot);
  301. // 把自己加入到CPaintManagerUI的m_aNotifiers数组中,用于处理Notify函数
  302. m_pm.AddNotifier(this);
  303. //进行一些初始化工作
  304. Init();
  305. return 0;
  306. }
  307. LRESULT CValueWnd::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  308. {
  309. bHandled = FALSE;
  310. return 0;
  311. }
  312. /*
  313. *这个是窗口被销毁的时候调用的
  314. **/
  315. LRESULT CValueWnd::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  316. {
  317. bHandled = FALSE;
  318. return 0;
  319. }
  320. LRESULT CValueWnd::OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  321. {
  322. if(::IsIconic(*this))
  323. {
  324. bHandled = FALSE;
  325. }
  326. return (wParam == 0) ? TRUE : FALSE;
  327. }
  328. LRESULT CValueWnd::OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  329. {
  330. return 0;
  331. }
  332. LRESULT CValueWnd::OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  333. {
  334. return 0;
  335. }
  336. LRESULT CValueWnd::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  337. {
  338. POINT pt;
  339. pt.x = GET_X_LPARAM(lParam);
  340. pt.y = GET_Y_LPARAM(lParam);
  341. ::ScreenToClient(*this, &pt);
  342. RECT rcClient;
  343. ::GetClientRect(*this, &rcClient);
  344. RECT rcCaption = m_pm.GetCaptionRect();
  345. if(pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
  346. && pt.y >= rcCaption.top && pt.y < rcCaption.bottom)
  347. {
  348. CControlUI* pControl = static_cast<CControlUI*>(m_pm.FindControl(pt));
  349. if(pControl && _tcscmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0)
  350. {
  351. return HTCAPTION;
  352. }
  353. }
  354. return HTCLIENT;
  355. }
  356. LRESULT CValueWnd::OnInput(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  357. {
  358. UINT dwSize = 0;
  359. GetRawInputData((HRAWINPUT)lParam, (UINT)RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));//取数据,第一次调用函数将获取需要的字节大小
  360. LPBYTE lpbBuffer = new BYTE[dwSize];//分配指定的缓冲区大小
  361. GetRawInputData((HRAWINPUT)lParam, (UINT)RID_INPUT, (LPVOID)lpbBuffer, (PUINT)&dwSize, (UINT)sizeof(RAWINPUTHEADER));//第二次调用获取原始输入数据,读入lpbBuffer
  362. RAWINPUT * raw = (RAWINPUT *)lpbBuffer;
  363. if (raw->header.dwType == RIM_TYPEKEYBOARD)//这里可以截获所有键盘信息,如需区分不同的键盘输入信息,可以通过设备句柄判断。
  364. {
  365. if (raw->data.keyboard.Message == WM_KEYDOWN)
  366. {
  367. }
  368. else if (raw->data.keyboard.Message == WM_KEYUP)
  369. {
  370. char keytext[10] = { 0 };
  371. BYTE state[256] = { 0 };
  372. //通过虚拟键盘码得到名字
  373. ToAscii(raw->data.keyboard.VKey, raw->data.keyboard.MakeCode, state, (LPWORD)keytext, 0);
  374. string a = keytext;
  375. if (raw->data.keyboard.VKey >= 48 && raw->data.keyboard.VKey <= 57)
  376. {
  377. //只考虑数字
  378. if (m_is_start_catch == false)
  379. {
  380. m_is_start_catch = true;
  381. m_catch_string = "";
  382. char keytext[10] = { 0 };
  383. BYTE state[256] = { 0 };
  384. //通过虚拟键盘码得到名字
  385. ToAscii(raw->data.keyboard.VKey, raw->data.keyboard.MakeCode, state, (LPWORD)keytext, 0);
  386. m_catch_string += string(keytext);
  387. m_last_catch_clock = clock();
  388. }
  389. else
  390. {
  391. //已经是在抓取过程中了
  392. clock_t now = clock();
  393. double total_t = (double)(now - m_last_catch_clock) / CLOCKS_PER_SEC;
  394. if (total_t > 0.05)
  395. {
  396. //如果超过了50ms,说明是人工输入的了,就重置所有状态
  397. m_is_start_catch = false;
  398. m_catch_string = "";
  399. }
  400. else
  401. {
  402. char keytext[10] = { 0 };
  403. BYTE state[256] = { 0 };
  404. //通过虚拟键盘码得到名字
  405. ToAscii(raw->data.keyboard.VKey, raw->data.keyboard.MakeCode, state, (LPWORD)keytext, 0);
  406. m_catch_string += string(keytext);
  407. m_last_catch_clock = clock();
  408. }
  409. }
  410. }
  411. else if (raw->data.keyboard.VKey == 13)
  412. {
  413. //enter
  414. std::string last = m_catch_string;
  415. bool is_fukuanma = false;
  416. //判断是不是正常的付款码格式
  417. if (last.find("10") == 0 \
  418. || last.find("11") == 0 \
  419. || last.find("12") == 0 \
  420. || last.find("13") == 0 \
  421. || last.find("14") == 0 \
  422. || last.find("15") == 0)
  423. {
  424. //微信付款码
  425. is_fukuanma = true;
  426. }
  427. else if (last.find("25") == 0 \
  428. || last.find("26") == 0 \
  429. || last.find("27") == 0 \
  430. || last.find("28") == 0 \
  431. || last.find("29") == 0 \
  432. || last.find("30") == 0)
  433. {
  434. //支付宝付款码
  435. is_fukuanma = true;
  436. }
  437. if (is_fukuanma)
  438. {
  439. //得到一个合适的付款码
  440. if (m_is_show_shoukuan == false)
  441. {
  442. ShowShoukuan();
  443. }
  444. }
  445. //不管是不是正常的付款码,收到enter后,这里都清空重来
  446. m_is_start_catch = false;
  447. m_catch_string = "";
  448. }
  449. else
  450. {
  451. //这种直接忽略,重新开始
  452. m_is_start_catch = false;
  453. m_catch_string = "";
  454. }
  455. }
  456. }
  457. delete[] lpbBuffer;
  458. bHandled = true;
  459. return 0;
  460. }
  461. LRESULT CValueWnd::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  462. {
  463. pMenu->ShowWindow(false);
  464. bHandled = FALSE;
  465. return 0;
  466. }
  467. LRESULT CValueWnd::OnRButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  468. {
  469. RECT rect;
  470. GetWindowRect(m_hWnd, &rect);
  471. ::SetWindowPos(pMenu->GetHWND(), HWND_NOTOPMOST, rect.left, rect.bottom - 3, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
  472. pMenu->ShowWindow(true);
  473. //右击后点别地可以清除“右击出来的菜单”
  474. SetForegroundWindow(pMenu->GetHWND());
  475. bHandled = FALSE;
  476. return 0;
  477. }
  478. LRESULT CValueWnd::OnKexianUpdate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  479. {
  480. //如果当前不是串口模式,直接忽略
  481. if(m_nWatchType != 1)
  482. {
  483. bHandled = TRUE;
  484. return true;
  485. }
  486. //收到了客显数据消息,读取客显数据
  487. char data[MAX_DATA_LENGTH] = { 0 };
  488. int data_length = 0;
  489. HookGetData(data, &data_length);
  490. if(data_length == 0)
  491. {
  492. bHandled = TRUE;
  493. return true;
  494. }
  495. UpdateKexian(data, data_length);
  496. bHandled = TRUE;
  497. return true;
  498. }
  499. LRESULT CValueWnd::OnWatchWndUpdate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  500. {
  501. CLabelUI* valueLabel = static_cast<CLabelUI*>(m_pm.FindControl(_T("value")));
  502. std::string utf8_watch_value = CLewaimaiString::UnicodeToUTF8(m_watchValue);
  503. std::string money_show = CLewaimaiString::DoubleToString(atof(utf8_watch_value.c_str()), 2);
  504. valueLabel->SetText(CLewaimaiString::UTF8ToUnicode(money_show).c_str());
  505. return TRUE;
  506. }
  507. LRESULT CValueWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  508. {
  509. LRESULT lRes = 0;
  510. BOOL bHandled = TRUE;
  511. switch(uMsg)
  512. {
  513. case WM_CREATE:
  514. lRes = OnCreate(uMsg, wParam, lParam, bHandled);
  515. break;
  516. case WM_CLOSE:
  517. lRes = OnClose(uMsg, wParam, lParam, bHandled);
  518. break;
  519. case WM_DESTROY:
  520. lRes = OnDestroy(uMsg, wParam, lParam, bHandled);
  521. break;
  522. case WM_NCACTIVATE:
  523. lRes = OnNcActivate(uMsg, wParam, lParam, bHandled);
  524. break;
  525. case WM_NCLBUTTONDOWN:
  526. lRes = OnLButtonDown(uMsg, wParam, lParam, bHandled);
  527. break;
  528. case WM_NCRBUTTONDOWN:
  529. lRes = OnRButtonDown(uMsg, wParam, lParam, bHandled);
  530. break;
  531. case WM_NCCALCSIZE:
  532. lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled);
  533. break;
  534. case WM_NCPAINT:
  535. lRes = OnNcPaint(uMsg, wParam, lParam, bHandled);
  536. break;
  537. case WM_NCHITTEST:
  538. lRes = OnNcHitTest(uMsg, wParam, lParam, bHandled);
  539. break;
  540. case WM_SHOWTASK:
  541. lRes = OnTrayIcon(uMsg, wParam, lParam, bHandled);
  542. break;
  543. case WM_HOOK_MESSAGE:
  544. lRes = OnKexianUpdate(uMsg, wParam, lParam, bHandled);
  545. break;
  546. case WM_WATCH_WND_UPDATE:
  547. lRes = OnWatchWndUpdate(uMsg, wParam, lParam, bHandled);
  548. break;
  549. case WM_HOTKEY:
  550. lRes = OnHotKey(uMsg, wParam, lParam, bHandled);
  551. break;
  552. case WM_INPUT:
  553. lRes = OnInput(uMsg, wParam, lParam, bHandled);
  554. break;
  555. default:
  556. bHandled = FALSE;
  557. }
  558. if(bHandled)
  559. {
  560. return lRes;
  561. }
  562. if(m_pm.MessageHandler(uMsg, wParam, lParam, lRes))
  563. {
  564. return lRes;
  565. }
  566. return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
  567. }
  568. LRESULT CValueWnd::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
  569. {
  570. return false;
  571. }
  572. void CValueWnd::ShowShoukuan()
  573. {
  574. if (m_is_show_shoukuan == true)
  575. {
  576. return;
  577. }
  578. pMenu->ShowWindow(false);
  579. CShoukuanWnd* pShoukuanWnd = new CShoukuanWnd;
  580. if (pShoukuanWnd != NULL)
  581. {
  582. pShoukuanWnd->setValueWnd(this);
  583. pShoukuanWnd->Create(NULL, _T(""), UI_WNDSTYLE_DIALOG, WS_EX_TOOLWINDOW);
  584. pShoukuanWnd->SetIcon(IDI_ICON_DUILIB);
  585. pShoukuanWnd->CenterWindow();
  586. m_is_show_shoukuan = true;
  587. m_shoukuanWnd = pShoukuanWnd;
  588. //只要金额不为0,就初始化
  589. std::string utf8_watch_value = CLewaimaiString::UnicodeToUTF8(m_watchValue);
  590. if (atof(utf8_watch_value.c_str()) > 0.001)
  591. {
  592. std::string format_string = CLewaimaiString::DoubleToString(atof(utf8_watch_value.c_str()), 2);
  593. m_watchValue = CLewaimaiString::UTF8ToUnicode(format_string);
  594. pShoukuanWnd->InitMoney(m_watchValue);
  595. }
  596. if (m_is_start_catch && m_catch_string.length() == 18)
  597. {
  598. pShoukuanWnd->InitFukuanma(m_catch_string);
  599. }
  600. pShoukuanWnd->ShowWindow(true);
  601. }
  602. }
  603. void CValueWnd::CloseShoukuan(bool isSuccess)
  604. {
  605. m_is_show_shoukuan = false;
  606. m_shoukuanWnd->Close();
  607. m_shoukuanWnd = NULL;
  608. if (isSuccess)
  609. {
  610. //开始执行自动清台
  611. CCheckBoxUI* zidongqingtai_setting_work = static_cast<CCheckBoxUI*>(m_pm.FindControl(L"zidongqingtai_setting_work"));
  612. std::string zidongqingtai_is_work = CSetting::GetParam("zidongqingtai_is_work");
  613. if (zidongqingtai_is_work == "0")
  614. {
  615. return;
  616. }
  617. std::thread(&CValueWnd::HandleZidongqingtai, this).detach();
  618. }
  619. }
  620. void CValueWnd::HandleZidongqingtai()
  621. {
  622. std::string zidongqingtai_time = CSetting::GetParam("zidongqingtai_time");
  623. int time = atoi(zidongqingtai_time.c_str());
  624. std::string zidongqingtai_num = CSetting::GetParam("zidongqingtai_num");
  625. int num = atoi(zidongqingtai_num.c_str());
  626. std::string zidongqingtai_huitian = CSetting::GetParam("zidongqingtai_huitian");
  627. int huitian = atoi(zidongqingtai_huitian.c_str());
  628. UINT zidongqingtai_kuaijiejian_1_mod = (UINT)atoi(CSetting::GetParam("zidongqingtai_kuaijiejian_1_mod").c_str());
  629. UINT zidongqingtai_kuaijiejian_1_vk = (UINT)atoi(CSetting::GetParam("zidongqingtai_kuaijiejian_1_vk").c_str());
  630. UINT zidongqingtai_kuaijiejian_2_mod = (UINT)atoi(CSetting::GetParam("zidongqingtai_kuaijiejian_2_mod").c_str());
  631. UINT zidongqingtai_kuaijiejian_2_vk = (UINT)atoi(CSetting::GetParam("zidongqingtai_kuaijiejian_2_vk").c_str());
  632. UINT zidongqingtai_kuaijiejian_3_mod = (UINT)atoi(CSetting::GetParam("zidongqingtai_kuaijiejian_3_mod").c_str());
  633. UINT zidongqingtai_kuaijiejian_3_vk = (UINT)atoi(CSetting::GetParam("zidongqingtai_kuaijiejian_3_vk").c_str());
  634. if (num >= 1)
  635. {
  636. //开始执行第一步
  637. Sleep(time);
  638. if (zidongqingtai_kuaijiejian_1_mod > 0)
  639. {
  640. CSystem::RunHotKey(zidongqingtai_kuaijiejian_1_mod, zidongqingtai_kuaijiejian_1_vk);
  641. }
  642. if (huitian == 1)
  643. {
  644. //这里开始执行回填
  645. }
  646. }
  647. if (num >= 2)
  648. {
  649. //需要执行第二步
  650. Sleep(time);
  651. if (zidongqingtai_kuaijiejian_2_mod > 0)
  652. {
  653. CSystem::RunHotKey(zidongqingtai_kuaijiejian_2_mod, zidongqingtai_kuaijiejian_2_vk);
  654. }
  655. }
  656. if (num >= 3)
  657. {
  658. //需要执行第二步
  659. Sleep(time);
  660. if (zidongqingtai_kuaijiejian_3_mod > 0)
  661. {
  662. CSystem::RunHotKey(zidongqingtai_kuaijiejian_3_mod, zidongqingtai_kuaijiejian_3_vk);
  663. }
  664. }
  665. }
  666. void CValueWnd::ShowTuikuan()
  667. {
  668. if (m_is_show_tuikuan == true)
  669. {
  670. return;
  671. }
  672. pMenu->ShowWindow(false);
  673. CTuikuanWnd* pTuikuanWnd = new CTuikuanWnd;
  674. if (pTuikuanWnd != NULL)
  675. {
  676. pTuikuanWnd->setValueWnd(this);
  677. pTuikuanWnd->Create(NULL, _T(""), UI_WNDSTYLE_DIALOG, WS_EX_TOOLWINDOW);
  678. pTuikuanWnd->SetIcon(IDI_ICON_DUILIB);
  679. pTuikuanWnd->CenterWindow();
  680. m_is_show_tuikuan = true;
  681. m_tuikuanWnd = pTuikuanWnd;
  682. //只要金额不为0,就初始化
  683. std::string utf8_watch_value = CLewaimaiString::UnicodeToUTF8(m_watchValue);
  684. if (false)
  685. {
  686. std::string format_string = CLewaimaiString::DoubleToString(atof(utf8_watch_value.c_str()), 2);
  687. m_watchValue = CLewaimaiString::UTF8ToUnicode(format_string);
  688. pTuikuanWnd->InitMoney(m_watchValue);
  689. }
  690. pTuikuanWnd->ShowWindow();
  691. }
  692. }
  693. void CValueWnd::CloseTuikuan()
  694. {
  695. m_is_show_tuikuan = false;
  696. m_tuikuanWnd->Close();
  697. m_tuikuanWnd = NULL;
  698. }
  699. void CValueWnd::AddTrayIcon()
  700. {
  701. memset(&m_trayIcon, 0, sizeof(NOTIFYICONDATA));
  702. m_trayIcon.cbSize = sizeof(NOTIFYICONDATA);
  703. m_trayIcon.hIcon = ::LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON_DUILIB));
  704. m_trayIcon.hWnd = m_hWnd;
  705. lstrcpy(m_trayIcon.szTip, _T("智铺子收银插件"));
  706. m_trayIcon.uCallbackMessage = WM_SHOWTASK;
  707. m_trayIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
  708. Shell_NotifyIcon(NIM_ADD, &m_trayIcon);
  709. }
  710. LRESULT CValueWnd::OnTrayIcon(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  711. {
  712. //如果在图标中单击左键则还原
  713. if(lParam == WM_LBUTTONDOWN)
  714. {
  715. ShowTrayMenu();
  716. }
  717. //如果在图标中单击右键则弹出声明式菜单
  718. else if(lParam == WM_RBUTTONDOWN)
  719. {
  720. ShowTrayMenu();
  721. }
  722. bHandled = true;
  723. return 0;
  724. }
  725. LRESULT CValueWnd::OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  726. {
  727. UINT fuModifiers = (UINT)LOWORD(lParam);
  728. UINT uVirtKey = (UINT)HIWORD(lParam);
  729. if (m_is_show_setting)
  730. {
  731. //如果当前在设置页面,就不处理快捷键消息,避免影响快捷键的重新设置
  732. bHandled = FALSE;
  733. return 0;
  734. }
  735. //判断响应了什么热键
  736. if (wParam == WM_MYHOTKEY_SHOUKUAN)
  737. {
  738. if (m_is_show_shoukuan == false)
  739. {
  740. ShowShoukuan();
  741. }
  742. else
  743. {
  744. CloseShoukuan();
  745. }
  746. }
  747. else if (wParam == WM_MYHOTKEY_TUIKUAN)
  748. {
  749. if (m_is_show_tuikuan == false)
  750. {
  751. ShowTuikuan();
  752. }
  753. else
  754. {
  755. CloseTuikuan();
  756. }
  757. }
  758. else if (wParam == WM_MYHOTKEY_JIAOYIJILU)
  759. {
  760. if (m_is_show_jiaoyijilu == false)
  761. {
  762. ShowJiaoyijilu();
  763. }
  764. else
  765. {
  766. CloseJiaoyijilu();
  767. }
  768. }
  769. else if (wParam == WM_MYHOTKEY_JIAOYIHUIZONG)
  770. {
  771. if (m_is_show_jiaoyihuizong == false)
  772. {
  773. ShowJiaoyihuizong();
  774. }
  775. else
  776. {
  777. CloseJiaoyihuizong();
  778. }
  779. }
  780. else if (wParam == WM_MYHOTKEY_JIAOBAN)
  781. {
  782. if (m_is_show_jiaoban == false)
  783. {
  784. ShowJiaoban();
  785. }
  786. else
  787. {
  788. CloseJiaoban();
  789. }
  790. }
  791. else if (wParam == WM_MYHOTKEY_SHEZHI)
  792. {
  793. if (m_is_show_setting == false)
  794. {
  795. ShowSystemSetting();
  796. }
  797. else
  798. {
  799. CloseSystemSetting();
  800. }
  801. }
  802. bHandled = TRUE;
  803. return 0;
  804. }
  805. void CValueWnd::ShowSystemSetting()
  806. {
  807. //先隐藏目录
  808. pMenu->ShowWindow(false);
  809. //然后判断和显示系统设置
  810. if (m_is_show_setting == true)
  811. {
  812. return;
  813. }
  814. CSystemSettingWnd* pSystemSettingFrame = new CSystemSettingWnd(this);
  815. m_settingWnd = pSystemSettingFrame;
  816. if (pSystemSettingFrame != NULL)
  817. {
  818. m_is_show_setting = true;
  819. pSystemSettingFrame->Create(NULL, _T(""), UI_WNDSTYLE_DIALOG, WS_EX_TOOLWINDOW);
  820. pSystemSettingFrame->SetIcon(IDI_ICON_DUILIB);
  821. pSystemSettingFrame->CenterWindow();
  822. pSystemSettingFrame->ShowWindow(true);
  823. }
  824. }
  825. void CValueWnd::CloseSystemSetting()
  826. {
  827. m_is_show_setting = false;
  828. m_settingWnd->Close();
  829. m_settingWnd = NULL;
  830. }
  831. void CValueWnd::ShowJiaoyijilu()
  832. {
  833. //先隐藏目录
  834. pMenu->ShowWindow(false);
  835. //然后判断和显示系统设置
  836. if (m_is_show_jiaoyijilu == true)
  837. {
  838. return;
  839. }
  840. CJiaoyijiluWnd* pJiaoyijiluFrame = new CJiaoyijiluWnd(this);
  841. m_jiaoyijiluWnd = pJiaoyijiluFrame;
  842. if (pJiaoyijiluFrame != NULL)
  843. {
  844. m_is_show_jiaoyijilu = true;
  845. pJiaoyijiluFrame->Create(NULL, _T(""), UI_WNDSTYLE_DIALOG, WS_EX_TOOLWINDOW);
  846. pJiaoyijiluFrame->SetIcon(IDI_ICON_DUILIB);
  847. pJiaoyijiluFrame->CenterWindow();
  848. pJiaoyijiluFrame->ShowWindow(true);
  849. }
  850. }
  851. void CValueWnd::CloseJiaoyijilu()
  852. {
  853. m_is_show_jiaoyijilu = false;
  854. m_jiaoyijiluWnd->Close();
  855. m_jiaoyijiluWnd = NULL;
  856. }
  857. void CValueWnd::ShowJiaoyihuizong()
  858. {
  859. //先隐藏目录
  860. pMenu->ShowWindow(false);
  861. //然后判断和显示系统设置
  862. if (m_is_show_jiaoyihuizong == true)
  863. {
  864. return;
  865. }
  866. CJiaoyihuizongWnd* pjiaoyihuizongFrame = new CJiaoyihuizongWnd(this);
  867. m_jiaoyihuizongWnd = pjiaoyihuizongFrame;
  868. if (pjiaoyihuizongFrame != NULL)
  869. {
  870. m_is_show_jiaoyihuizong = true;
  871. pjiaoyihuizongFrame->Create(NULL, _T(""), UI_WNDSTYLE_DIALOG, WS_EX_TOOLWINDOW);
  872. pjiaoyihuizongFrame->SetIcon(IDI_ICON_DUILIB);
  873. pjiaoyihuizongFrame->CenterWindow();
  874. pjiaoyihuizongFrame->ShowWindow(true);
  875. }
  876. }
  877. void CValueWnd::CloseJiaoyihuizong()
  878. {
  879. m_is_show_jiaoyihuizong = false;
  880. m_jiaoyihuizongWnd->Close();
  881. m_jiaoyihuizongWnd = NULL;
  882. }
  883. void CValueWnd::ShowJiaoban()
  884. {
  885. //先隐藏目录
  886. pMenu->ShowWindow(false);
  887. //然后判断和显示系统设置
  888. if (m_is_show_jiaoban == true)
  889. {
  890. return;
  891. }
  892. CJiaobanWnd* pjiaobanFrame = new CJiaobanWnd(this);
  893. m_jiaobanWnd = pjiaobanFrame;
  894. if (pjiaobanFrame != NULL)
  895. {
  896. m_is_show_jiaoban = true;
  897. pjiaobanFrame->setValueWnd(this);
  898. pjiaobanFrame->Create(NULL, _T(""), UI_WNDSTYLE_DIALOG, WS_EX_TOOLWINDOW);
  899. pjiaobanFrame->SetIcon(IDI_ICON_DUILIB);
  900. pjiaobanFrame->CenterWindow();
  901. pjiaobanFrame->ShowWindow(true);
  902. }
  903. }
  904. void CValueWnd::CloseJiaoban()
  905. {
  906. m_is_show_jiaoban = false;
  907. m_jiaobanWnd->Close();
  908. m_jiaobanWnd = NULL;
  909. }
  910. /*
  911. *执行退出前的清理工作,暂停所有工作线程,清理对象
  912. *返回true表示清理成功,返回false表示清理失败
  913. **/
  914. bool CValueWnd::Clear()
  915. {
  916. if (m_is_show_shoukuan || m_is_show_tuikuan)
  917. {
  918. //如果收款和退款窗口都没关闭,不允许进行清理
  919. return false;
  920. }
  921. //清理窗口
  922. if (m_is_show_jiaoyijilu)
  923. {
  924. CloseJiaoyijilu();
  925. }
  926. if (m_is_show_jiaoyihuizong)
  927. {
  928. CloseJiaoyihuizong();
  929. }
  930. if (m_is_show_jiaoban)
  931. {
  932. CloseJiaoban();
  933. }
  934. if (m_is_show_setting)
  935. {
  936. CloseSystemSetting();
  937. }
  938. //清理抢焦点的
  939. StopTopMostWnd();
  940. //取消注册的快捷键
  941. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_SHOUKUAN);
  942. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_TUIKUAN);
  943. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_JIAOYIJILU);
  944. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_JIAOYIHUIZONG);
  945. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_JIAOBAN);
  946. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_SHEZHI);
  947. //删除右下角的托盘
  948. Shell_NotifyIcon(NIM_DELETE, &m_trayIcon);
  949. //注意这里不能delete,这个对象会delete自己
  950. m_push->Stop();
  951. pMenu->Close();
  952. pDingweiWnd->Close();
  953. pDingweiInfoWnd->Close();
  954. pOcrWnd->Close();
  955. //注销Hook
  956. UninstallHook();
  957. //暂停数据监控
  958. StopWatch();
  959. this->Close();
  960. return true;
  961. }
  962. void CValueWnd::Logout()
  963. {
  964. if (!this->Clear())
  965. {
  966. return;
  967. }
  968. //退出登录,取消自动登录
  969. CSetting::SetParam("setting_is_auto_login", "0", true);
  970. //创建登录窗口
  971. CLoginWnd* pLogin = new CLoginWnd();
  972. if (pLogin == NULL)
  973. {
  974. return;
  975. }
  976. pLogin->Create(NULL, _T("智铺子收银插件登录"), UI_WNDSTYLE_DIALOG, WS_EX_TOOLWINDOW, 0, 0, 0, 0, NULL);
  977. pLogin->SetIcon(IDI_ICON_DUILIB);
  978. pLogin->CenterWindow();
  979. pLogin->ShowWindow(true);
  980. }
  981. void CValueWnd::QuitApp()
  982. {
  983. if (!this->Clear())
  984. {
  985. return;
  986. }
  987. //直接退出整个程序
  988. PostQuitMessage(0);
  989. }
  990. void CValueWnd::UpdateKexian(const char* data, int length)
  991. {
  992. std::string new_data = data;
  993. //清屏命令
  994. std::string clear_command = "\f";
  995. //4个信号灯全灭
  996. std::string quanmie_command = "\x1bs0";
  997. //初始化命令
  998. std::string init_command = "\x1b\x40";
  999. //实际读取金额用到的命令
  1000. std::string show_command = "\x1bQA";
  1001. std::string show_command_2 = "QA";
  1002. std::string type_command = "\x1bs";
  1003. if(new_data == clear_command || new_data == quanmie_command || new_data == init_command)
  1004. {
  1005. //清屏命令,或者是熄灭灯的命令
  1006. return;
  1007. }
  1008. int nShowType;
  1009. if(new_data.find(show_command) == new_data.npos)
  1010. {
  1011. //没有\x1bQA,继续找有没有QA(比如思迅)
  1012. if (new_data.find(show_command_2) == new_data.npos)
  1013. {
  1014. //完全没QA
  1015. return;
  1016. }
  1017. else
  1018. {
  1019. nShowType = 2;
  1020. }
  1021. }
  1022. else
  1023. {
  1024. nShowType = 1;
  1025. }
  1026. std::string money;
  1027. int nPos;
  1028. if (nShowType == 1)
  1029. {
  1030. nPos = new_data.find(show_command);;
  1031. }
  1032. else
  1033. {
  1034. nPos = new_data.find(show_command_2);
  1035. }
  1036. int nTypePos = new_data.find(type_command, nPos + 1);
  1037. if(nTypePos == new_data.npos)
  1038. {
  1039. //没有类型信息,有些收银机(比如思迅天店)就是不传类型信息,这种只有传什么显示什么了
  1040. int nTabPos = new_data.find("\r", nPos + 1);
  1041. if(nTabPos == new_data.npos)
  1042. {
  1043. //制表符也没有
  1044. return;
  1045. }
  1046. if (nShowType == 1)
  1047. {
  1048. money = new_data.substr(nPos + 3, nTabPos - nPos - 3);
  1049. }
  1050. else
  1051. {
  1052. money = new_data.substr(nPos + 2, nTabPos - nPos - 2);
  1053. }
  1054. CLabelUI* valueLabel = static_cast<CLabelUI*>(m_pm.FindControl(_T("value")));
  1055. std::string money_show = CLewaimaiString::DoubleToString(atof(money.c_str()), 2);
  1056. m_watchValue = CLewaimaiString::UTF8ToUnicode(money_show);
  1057. valueLabel->SetText(CLewaimaiString::UTF8ToUnicode(money_show).c_str());
  1058. }
  1059. else
  1060. {
  1061. std::string value_type = new_data.substr(nTypePos + 2, 1);
  1062. money = new_data.substr(nPos + 3, nTypePos - nPos - 3 - 1);
  1063. if(value_type == "2")
  1064. {
  1065. //这个表示是总计的,那么就要刷新金额显示
  1066. CLabelUI* valueLabel = static_cast<CLabelUI*>(m_pm.FindControl(_T("value")));
  1067. std::string money_show = CLewaimaiString::DoubleToString(atof(money.c_str()), 2);
  1068. m_watchValue = CLewaimaiString::UTF8ToUnicode(money_show);
  1069. valueLabel->SetText(CLewaimaiString::UTF8ToUnicode(money_show).c_str());
  1070. }
  1071. else
  1072. {
  1073. //这种情况传输的是一些找零、单价之类的信息,不更新客显金额
  1074. }
  1075. }
  1076. return;
  1077. }
  1078. void CValueWnd::InitWndPos()
  1079. {
  1080. ASSERT(::IsWindow(m_hWnd));
  1081. ASSERT((GetWindowStyle(m_hWnd)&WS_CHILD) == 0);
  1082. RECT rcDlg = { 0 };
  1083. ::GetWindowRect(m_hWnd, &rcDlg);
  1084. int DlgWidth = rcDlg.right - rcDlg.left;
  1085. int DlgHeight = rcDlg.bottom - rcDlg.top;
  1086. RECT rcArea = { 0 };
  1087. ::GetWindowRect(::GetDesktopWindow(), &rcArea);
  1088. int xLeft = rcArea.right - DlgWidth - 60;
  1089. int yTop = 100;
  1090. if(xLeft < rcArea.left)
  1091. {
  1092. xLeft = rcArea.left;
  1093. }
  1094. else if(xLeft + DlgWidth > rcArea.right)
  1095. {
  1096. xLeft = rcArea.right - DlgWidth;
  1097. }
  1098. if(yTop < rcArea.top)
  1099. {
  1100. yTop = rcArea.top;
  1101. }
  1102. else if(yTop + DlgHeight > rcArea.bottom)
  1103. {
  1104. yTop = rcArea.bottom - DlgHeight;
  1105. }
  1106. ::SetWindowPos(m_hWnd, HWND_TOPMOST, xLeft, yTop, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
  1107. }
  1108. void CValueWnd::ShowTrayMenu()
  1109. {
  1110. //获取鼠标坐标
  1111. POINT pt;
  1112. GetCursorPos(&pt);
  1113. CRect rect;
  1114. GetWindowRect(pMenu->GetHWND(), &rect);
  1115. int height = rect.bottom - rect.top;
  1116. //显示目录
  1117. ::SetWindowPos(pMenu->GetHWND(), HWND_NOTOPMOST, pt.x, pt.y - 15 - height, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
  1118. pMenu->ShowWindow(true);
  1119. SetFocus(pMenu->GetHWND());
  1120. //右击后点别地可以清除“右击出来的菜单”
  1121. SetForegroundWindow(pMenu->GetHWND());
  1122. }
  1123. void CValueWnd::StartDingweiWnd()
  1124. {
  1125. m_settingWnd->ShowWindow(false);
  1126. m_is_dingwei_wnd = true;
  1127. std::thread(&CValueWnd::StartDingweiWork, this).detach();
  1128. }
  1129. void CValueWnd::ConfirmDingweiWnd(std::wstring value, HWND hWnd)
  1130. {
  1131. m_is_dingwei_wnd = false;
  1132. m_settingWnd->SetDingweiWnd(value, hWnd);
  1133. }
  1134. void CValueWnd::CancalDingweiWnd()
  1135. {
  1136. m_is_dingwei_wnd = false;
  1137. }
  1138. void CValueWnd::StartDingweiWork()
  1139. {
  1140. while (m_is_dingwei_wnd)
  1141. {
  1142. //这个时候,是开始定位窗口了
  1143. POINT pt;
  1144. GetCursorPos(&pt);
  1145. //将屏幕坐标保存起来
  1146. POINT ptScreen = pt;
  1147. //转换成桌面坐标
  1148. HWND hDeskHandle = GetDesktopWindow();
  1149. ScreenToClient(hDeskHandle, &pt);
  1150. HWND hParent = hDeskHandle;
  1151. HWND hChild = ChildWindowFromPointEx(hParent, pt, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT | CWP_SKIPDISABLED);
  1152. if (hChild == pDingweiInfoWnd->GetHWND())
  1153. {
  1154. //这里表示是移动信息窗口了,这里就不要执行后面的刷新操作了
  1155. }
  1156. else
  1157. {
  1158. while (hChild != NULL && hChild != hParent)
  1159. {
  1160. //说明还有更下级的子窗口
  1161. hParent = hChild;
  1162. pt = ptScreen;
  1163. ScreenToClient(hParent, &pt);
  1164. hChild = ChildWindowFromPointEx(hParent, pt, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT);
  1165. }
  1166. HWND hWnd = hParent;
  1167. RECT rect;
  1168. GetWindowRect(hWnd, &rect);
  1169. //在这个窗口上,画一个边框
  1170. pDingweiWnd->ShowWindow(true);
  1171. ::SetWindowPos(pDingweiWnd->GetHWND(), HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE);
  1172. //显示定位信息
  1173. TCHAR szTitle[MAX_PATH] = { 0 };
  1174. LPWSTR lpWindowName = szTitle;
  1175. ::SendMessageW(hWnd, WM_GETTEXT, (WPARAM)(MAX_PATH), (LPARAM)lpWindowName);
  1176. //设置信息窗口的内容
  1177. pDingweiInfoWnd->UpdateInfo(lpWindowName, hWnd);
  1178. pDingweiInfoWnd->ShowWindow(true);
  1179. int nWidth = rect.right - rect.left;
  1180. if (nWidth < 380)
  1181. {
  1182. nWidth = 380;
  1183. }
  1184. ::SetWindowPos(pDingweiInfoWnd->GetHWND(), HWND_TOPMOST, rect.left, rect.bottom, nWidth, 36, SWP_NOACTIVATE);
  1185. }
  1186. Sleep(100);
  1187. }
  1188. m_settingWnd->ShowWindow(true);
  1189. pDingweiWnd->ShowWindow(false);
  1190. pDingweiInfoWnd->ShowWindow(false);
  1191. }
  1192. void CValueWnd::StartOcrWnd()
  1193. {
  1194. m_settingWnd->ShowWindow(false);
  1195. m_is_orc_wnd = true;
  1196. pOcrWnd->ShowWindow(true);
  1197. //先默认居中
  1198. ::SetWindowPos(pOcrWnd->GetHWND(), HWND_TOPMOST, 0, 0, 320, 80, SWP_NOMOVE | SWP_NOACTIVATE);
  1199. pOcrWnd->CenterWindow();
  1200. }
  1201. void CValueWnd::ConfirmOcrWnd(RECT rect)
  1202. {
  1203. m_is_orc_wnd = false;
  1204. pOcrWnd->ShowWindow(false);
  1205. //保存截屏的结果
  1206. m_settingWnd->SetOcrWnd(rect);
  1207. //显示设置窗口
  1208. m_settingWnd->ShowWindow(true);
  1209. }
  1210. void CValueWnd::CancelOcr()
  1211. {
  1212. m_is_orc_wnd = false;
  1213. pOcrWnd->ShowWindow(false);
  1214. //显示设置窗口
  1215. m_settingWnd->ShowWindow(true);
  1216. }
  1217. tesseract::TessBaseAPI& CValueWnd::GetTess()
  1218. {
  1219. return m_tess;
  1220. }
  1221. void CValueWnd::UpdateRegisterHotKey()
  1222. {
  1223. //收款
  1224. UINT shoukuan_mod = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_shoukuan_mod").c_str());
  1225. UINT shoukuan_vk = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_shoukuan_vk").c_str());
  1226. //先卸载旧的,再注册新的
  1227. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_SHOUKUAN);
  1228. RegisterHotKey(m_hWnd, WM_MYHOTKEY_SHOUKUAN, shoukuan_mod, shoukuan_vk);
  1229. //退款
  1230. UINT tuikuan_mod = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_tuikuan_mod").c_str());
  1231. UINT tuikuan_vk = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_tuikuan_vk").c_str());
  1232. //先卸载旧的,再注册新的
  1233. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_TUIKUAN);
  1234. RegisterHotKey(m_hWnd, WM_MYHOTKEY_TUIKUAN, tuikuan_mod, tuikuan_vk);
  1235. //交易记录
  1236. UINT jiaoyijilu_mod = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_jiaoyijilu_mod").c_str());
  1237. UINT jiaoyijilu_vk = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_jiaoyijilu_vk").c_str());
  1238. //先卸载旧的,再注册新的
  1239. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_JIAOYIJILU);
  1240. RegisterHotKey(m_hWnd, WM_MYHOTKEY_JIAOYIJILU, jiaoyijilu_mod, jiaoyijilu_vk);
  1241. //交易汇总
  1242. UINT jiaoyihuizong_mod = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_jiaoyihuizong_mod").c_str());
  1243. UINT jiaoyihuizong_vk = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_jiaoyihuizong_vk").c_str());
  1244. //先卸载旧的,再注册新的
  1245. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_JIAOYIHUIZONG);
  1246. RegisterHotKey(m_hWnd, WM_MYHOTKEY_JIAOYIHUIZONG, jiaoyihuizong_mod, jiaoyihuizong_vk);
  1247. //交班
  1248. UINT jiaoban_mod = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_jiaoban_mod").c_str());
  1249. UINT jiaoban_vk = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_jiaoban_vk").c_str());
  1250. //先卸载旧的,再注册新的
  1251. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_JIAOBAN);
  1252. RegisterHotKey(m_hWnd, WM_MYHOTKEY_JIAOBAN, jiaoban_mod, jiaoban_vk);
  1253. //设置
  1254. UINT shezhi_mod = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_shezhi_mod").c_str());
  1255. UINT shezhi_vk = (UINT)atoi(CSetting::GetParam("system_setting_kuaijiejian_shezhi_vk").c_str());
  1256. //先卸载旧的,再注册新的
  1257. UnregisterHotKey(m_hWnd, WM_MYHOTKEY_SHEZHI);
  1258. RegisterHotKey(m_hWnd, WM_MYHOTKEY_SHEZHI, shezhi_mod, shezhi_vk);
  1259. }
  1260. //全局监听键盘输入
  1261. void CValueWnd::RegKeyboardRawInput()
  1262. {
  1263. RAWINPUTDEVICE rawInputDevice[1];
  1264. rawInputDevice[0].usUsagePage = 0x01;//设备类
  1265. rawInputDevice[0].usUsage = 0x06;//设备类内的具体设备
  1266. rawInputDevice[0].dwFlags = RIDEV_INPUTSINK;//意味着即使窗口失去焦点位置,仍然会一直接收输入消息
  1267. rawInputDevice[0].hwndTarget = m_hWnd;
  1268. if (RegisterRawInputDevices(rawInputDevice, 1, sizeof(rawInputDevice[0])) == FALSE)
  1269. {
  1270. printf("RegisterRawInputDevices failed");
  1271. }
  1272. }
  1273. void CValueWnd::PrintTest()
  1274. {
  1275. m_push->AddPrinter("", 3);
  1276. }
  1277. void CValueWnd::PrintZhifu(std::string out_trade_no)
  1278. {
  1279. m_push->AddPrinter(out_trade_no, 1);
  1280. }
  1281. void CValueWnd::PrintTuikuan(std::string out_trade_no)
  1282. {
  1283. m_push->AddPrinter(out_trade_no, 2);
  1284. }
  1285. void CValueWnd::PrintJiaoban(CJiaobanMessage& message)
  1286. {
  1287. m_push->AddPrinter(message);
  1288. }