CValueWnd.cpp 34 KB

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