IRControlWnd.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. // 这段 MFC 示例源代码演示如何使用 MFC Microsoft Office Fluent 用户界面
  2. // (“Fluent UI”)。该示例仅供参考,
  3. // 用以补充《Microsoft 基础类参考》和
  4. // MFC C++ 库软件随附的相关电子文档。
  5. // 复制、使用或分发 Fluent UI 的许可条款是单独提供的。
  6. // 若要了解有关 Fluent UI 许可计划的详细信息,请访问
  7. // https://go.microsoft.com/fwlink/?LinkId=238214.
  8. //
  9. // 版权所有(C) Microsoft Corporation
  10. // 保留所有权利。
  11. #include "stdafx.h"
  12. #include "framework.h"
  13. #include "IRControlWnd.h"
  14. #include "Resource.h"
  15. #include "MainFrm.h"
  16. #include "SATHelper.h"
  17. #include <filehelper.h>
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #define new DEBUG_NEW
  22. #endif
  23. extern CMainFrame* g_pMainFrame;
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CResourceViewBar
  26. unsigned char TwoHexChar2Char(char ch1, char ch2)
  27. {
  28. char Numb1;
  29. char Numb2;
  30. if (ch1 >= 'A')
  31. Numb1 = (toupper(ch1) - '0' - 7) * 16;
  32. else
  33. Numb1 = (ch1 - '0') * 16;
  34. if (ch2 >= 'A')
  35. Numb2 = (toupper(ch2) - '0' - 7);
  36. else
  37. Numb2 = (ch2 - '0');
  38. return (Numb1 + Numb2);
  39. }
  40. COLORREF HexColor2RGB(std::string strHexColor)
  41. {
  42. DWORD r = TwoHexChar2Char(strHexColor[0], strHexColor[1]);
  43. DWORD g = TwoHexChar2Char(strHexColor[2], strHexColor[3]);
  44. DWORD b = TwoHexChar2Char(strHexColor[4], strHexColor[5]);
  45. return RGB(r, g, b);
  46. }
  47. CIRControlWnd::CIRControlWnd() noexcept
  48. {
  49. m_nComboHeight = 0;
  50. m_bSendKey = FALSE;
  51. }
  52. CIRControlWnd::~CIRControlWnd()
  53. {
  54. RedRat::UnloadLibrary();
  55. for (std::vector<BtnInfo>::iterator it = m_vtBtnInfo.begin(); it != m_vtBtnInfo.end(); it++)
  56. {
  57. if (it->pBTN)
  58. //it->pBTN->DestroyWindow();
  59. delete it->pBTN;
  60. it->pBTN = NULL;
  61. }
  62. m_vtBtnInfo.clear();
  63. }
  64. // 重启进程按钮id;
  65. #define ID_BUTTON_RESTART_PROC 1
  66. // 复制框控件id;
  67. #define ID_CHECKBOX_SIGNAL_TYPE 2
  68. // 下拉框控件id;
  69. #define ID_COMBOBOX_SIGNAL_FILE 3
  70. BEGIN_MESSAGE_MAP(CIRControlWnd, CDockablePane)
  71. ON_WM_CREATE()
  72. ON_WM_SIZE()
  73. ON_COMMAND(ID_EXPAND_ALL, OnExpandAllProperties)
  74. ON_UPDATE_COMMAND_UI(ID_EXPAND_ALL, OnUpdateExpandAllProperties)
  75. ON_COMMAND(ID_SORTPROPERTIES, OnSortProperties)
  76. ON_UPDATE_COMMAND_UI(ID_SORTPROPERTIES, OnUpdateSortProperties)
  77. ON_COMMAND(ID_PROPERTIES1, OnProperties1)
  78. ON_UPDATE_COMMAND_UI(ID_PROPERTIES1, OnUpdateProperties1)
  79. ON_COMMAND(ID_PROPERTIES2, OnProperties2)
  80. ON_UPDATE_COMMAND_UI(ID_PROPERTIES2, OnUpdateProperties2)
  81. ON_WM_SETFOCUS()
  82. ON_WM_SETTINGCHANGE()
  83. ON_WM_PAINT()
  84. ON_MESSAGE(WM_IR_SHOT_IMG, OnIRShotImg)
  85. ON_CBN_SELCHANGE(ID_COMBOBOX_SIGNAL_FILE, &CIRControlWnd::OnCbnSelchangeSignal)
  86. // 信号按钮;
  87. ON_COMMAND_RANGE(BTNID, BTNID + 100, OnSignalBtnClick)
  88. ON_UPDATE_COMMAND_UI_RANGE(BTNID, BTNID + 100, OnUpdateSignalBtn)
  89. // checkbox
  90. ON_UPDATE_COMMAND_UI(ID_CHECKBOX_SIGNAL_TYPE, OnUpdateCheckBox)
  91. ON_COMMAND(ID_CHECKBOX_SIGNAL_TYPE, OnCheckBoxClicked)
  92. // 重启按钮;
  93. ON_UPDATE_COMMAND_UI(ID_BUTTON_RESTART_PROC, OnUpdateBtnRestartProc)
  94. ON_COMMAND(ID_BUTTON_RESTART_PROC, OnBtnRestartProcClicked)
  95. //ON_UPDATE_COMMAND_UI(ID_BUTTON_RESTART_PROC, OnUpdateReStartBtn)
  96. END_MESSAGE_MAP()
  97. /////////////////////////////////////////////////////////////////////////////
  98. // CResourceViewBar 消息处理程序
  99. void CIRControlWnd::AdjustLayout()
  100. {
  101. if (GetSafeHwnd() == nullptr || (AfxGetMainWnd() != nullptr && AfxGetMainWnd()->IsIconic()))
  102. {
  103. return;
  104. }
  105. CRect rectClient;
  106. GetClientRect(rectClient);
  107. m_btnRestart.SetWindowPos(nullptr, rectClient.left + 5, rectClient.top + 5, 120, m_nComboHeight, SWP_NOACTIVATE | SWP_NOZORDER);
  108. m_wndSignalCheck.SetWindowPos(nullptr, rectClient.left + 130, rectClient.top + 5, 120, m_nComboHeight, SWP_NOACTIVATE | SWP_NOZORDER);
  109. m_wndSignalCombo.SetWindowPos(nullptr, rectClient.left + 5, rectClient.top + m_nComboHeight + 10, 245, m_nComboHeight + 210, SWP_NOACTIVATE | SWP_NOZORDER);
  110. #if __PANE_DLG__
  111. m_dlgIRControl.SetWindowPos(nullptr, rectClient.left, rectClient.top + m_nComboHeight + 50, rectClient.Width(), rectClient.Height(), SWP_NOACTIVATE);
  112. #endif
  113. }
  114. int CIRControlWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
  115. {
  116. if (CDockablePane::OnCreate(lpCreateStruct) == -1)
  117. return -1;
  118. CRect rectDummy;
  119. rectDummy.SetRectEmpty();
  120. // 创建组合:
  121. const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_BORDER | CBS_SORT | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
  122. if (!m_btnRestart.Create(_T("重启遥控器服务进程"), WS_CHILD | WS_VISIBLE, rectDummy, this, ID_BUTTON_RESTART_PROC))
  123. {
  124. TRACE0("未能创建遥控器组合 \n");
  125. return -1; // 未能创建
  126. }
  127. if (!m_wndSignalCheck.Create(_T("通用遥控器选择"), WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, rectDummy, this, ID_CHECKBOX_SIGNAL_TYPE))
  128. {
  129. TRACE0("未能创建信号集下拉框 \n");
  130. return -1; // 未能创建
  131. }
  132. m_wndSignalCheck.SetCheck(Global::g_Config.bGenerics ? BST_CHECKED : BST_UNCHECKED);
  133. m_wndSignalCheck.m_bHighlightChecked = TRUE;
  134. // CMFCButton只能用图标来显示check;
  135. m_wndSignalCheck.SetImage(IDB_UNCHECKED);
  136. m_wndSignalCheck.SetCheckedImage(IDB_CHECKED);
  137. m_wndSignalCheck.m_bTransparent = FALSE;
  138. m_wndSignalCheck.m_bDrawFocus = FALSE;
  139. m_wndSignalCheck.m_nFlatStyle = CMFCButton::BUTTONSTYLE_FLAT;
  140. m_wndSignalCheck.SizeToContent();
  141. if (!m_wndSignalCombo.Create(dwViewStyle| WS_VSCROLL| WS_HSCROLL, rectDummy, this, ID_COMBOBOX_SIGNAL_FILE))
  142. {
  143. TRACE0("未能创建信号集下拉框 \n");
  144. return -1; // 未能创建
  145. }
  146. LoadSignals();
  147. CRect rectCombo;
  148. m_wndSignalCombo.GetClientRect(&rectCombo);
  149. m_nComboHeight = rectCombo.Height();
  150. #if __PANE_DLG__
  151. if (!m_dlgIRControl.Create(IDD_DLG_IRCONTROL, this))
  152. {
  153. TRACE0("未能创建遥控器主窗口 \n");
  154. return -1; // 未能创建
  155. }
  156. m_dlgIRControl.ShowWindow(SW_SHOW);
  157. #else
  158. Loadlayout(m_vtBtnInfo);
  159. #endif
  160. // 设置最小窗体;
  161. SetMinSize((530, 300));
  162. // 校正布局;
  163. AdjustLayout();
  164. //////////////////////////////////////////////////////////////////////////
  165. // 启动红老鼠;
  166. if (!RedRat::LoadLibrary())
  167. {
  168. AfxMessageBox("加载遥控dll失败,请检测dll是否正常!");
  169. }
  170. StartIRDevice(FALSE);
  171. if (Global::g_Config.enableTW)
  172. {
  173. std::string signaldir = Global::g_Config.twSignaldir;
  174. std::string signalpath = signaldir + "\\";
  175. signalpath.append(Global::g_Config.twUseSignal + ".xml");
  176. TW::OpenDevice(Global::g_Config.twPort, 115200, 8, 0, 0);
  177. TW::LoadXml(signalpath.c_str());
  178. }
  179. std::thread t([](CIRControlWnd *pWnd) {
  180. //while (true)
  181. while( IsWindow(pWnd->m_hWnd) )
  182. {
  183. if (g_pMainFrame->m_bShotIR && pWnd->m_bSendKey)
  184. {
  185. pWnd->m_bSendKey = FALSE;
  186. Sleep(200);
  187. CUB530View* pView = (CUB530View*)g_pMainFrame->m_pUB530View->GetActiveView();
  188. if (pView)
  189. {
  190. pView->OnCutJpg();
  191. }
  192. }
  193. Sleep(20);
  194. }
  195. },this);
  196. t.detach();
  197. return 0;
  198. }
  199. void CIRControlWnd::OnSize(UINT nType, int cx, int cy)
  200. {
  201. CDockablePane::OnSize(nType, cx, cy);
  202. TRACE2("坐标:%d,%d\n", cx, cy);
  203. AdjustLayout();
  204. }
  205. void CIRControlWnd::OnExpandAllProperties()
  206. {
  207. //m_wndPropList.ExpandAll();
  208. }
  209. void CIRControlWnd::OnUpdateExpandAllProperties(CCmdUI* /* pCmdUI */)
  210. {
  211. }
  212. void CIRControlWnd::OnSortProperties()
  213. {
  214. //m_wndPropList.SetAlphabeticMode(!m_wndPropList.IsAlphabeticMode());
  215. }
  216. void CIRControlWnd::OnUpdateSortProperties(CCmdUI* pCmdUI)
  217. {
  218. //pCmdUI->SetCheck(m_wndPropList.IsAlphabeticMode());
  219. }
  220. void CIRControlWnd::OnProperties1()
  221. {
  222. // TODO: 在此处添加命令处理程序代码
  223. }
  224. void CIRControlWnd::OnUpdateProperties1(CCmdUI* /*pCmdUI*/)
  225. {
  226. // TODO: 在此处添加命令更新 UI 处理程序代码
  227. }
  228. void CIRControlWnd::OnProperties2()
  229. {
  230. // TODO: 在此处添加命令处理程序代码
  231. }
  232. void CIRControlWnd::OnUpdateProperties2(CCmdUI* /*pCmdUI*/)
  233. {
  234. // TODO: 在此处添加命令更新 UI 处理程序代码
  235. }
  236. void CIRControlWnd::OnSetFocus(CWnd* pOldWnd)
  237. {
  238. CDockablePane::OnSetFocus(pOldWnd);
  239. }
  240. void CIRControlWnd::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
  241. {
  242. CDockablePane::OnSettingChange(uFlags, lpszSection);
  243. //SetPropListFont();
  244. }
  245. void CIRControlWnd::OnCbnSelchangeSignal()
  246. {
  247. CString strSignal;
  248. int nCurSel = m_wndSignalCombo.GetCurSel();
  249. if (nCurSel != CB_ERR)
  250. {
  251. std::string signalpath;
  252. m_wndSignalCombo.GetLBText(nCurSel, strSignal);
  253. // 保存到配置文件中;
  254. if (Global::g_Config.enableTW)
  255. {
  256. Global::g_Config.twUseSignal = strSignal.GetString();
  257. WritePrivateProfileString("TestWizard", "useSignal", strSignal.GetString(), Global::g_szConfig);
  258. }
  259. else {
  260. Global::g_Config.use_signal = strSignal.GetString();
  261. WritePrivateProfileString("ir-device", "use-signal", strSignal.GetString(), Global::g_szConfig);
  262. }
  263. }
  264. DisableSignalBtn();
  265. ReLoadSignalXml();
  266. }
  267. void CIRControlWnd::SetPropListFont()
  268. {
  269. ::DeleteObject(m_fntPropList.Detach());
  270. LOGFONT lf;
  271. afxGlobalData.fontRegular.GetLogFont(&lf);
  272. NONCLIENTMETRICS info;
  273. info.cbSize = sizeof(info);
  274. afxGlobalData.GetNonClientMetrics(info);
  275. lf.lfHeight = info.lfMenuFont.lfHeight;
  276. lf.lfWeight = info.lfMenuFont.lfWeight;
  277. lf.lfItalic = info.lfMenuFont.lfItalic;
  278. m_fntPropList.CreateFontIndirect(&lf);
  279. //m_wndObjectCombo.SetFont(&m_fntPropList);
  280. }
  281. void CIRControlWnd::StartIRDevice(BOOL bReStart)
  282. {
  283. std::thread t([&](BOOL _bReStart_) {
  284. // 结束进程;
  285. if (_bReStart_ && RedRat::g_CloseApp)
  286. RedRat::g_CloseApp();
  287. // 默认加载配置的信号集文件;
  288. std::string signale = Global::g_Config.bGenerics ? Global::g_Config.signaldir + "\\general\\" : Global::g_Config.signaldir + "\\product\\";
  289. signale.append(Global::g_Config.use_signal + ".xml");
  290. if (!PathFileExists(signale.c_str()))
  291. {
  292. m_wndSignalCombo.SetCurSel(-1);
  293. signale = ".\\default.xml";
  294. }
  295. else
  296. {
  297. m_wndSignalCombo.SelectString(0, Global::g_Config.use_signal.c_str());
  298. }
  299. if ( !RedRat::g_IsAppRunning(Global::g_Config.redratpath.c_str()) )
  300. {
  301. if (RedRat::g_StartIRApp(Global::g_Config.redratpath.c_str(), signale.c_str(), 40000))
  302. {
  303. TRACE("启动红老鼠进程启动成功\r");
  304. }
  305. else
  306. {
  307. TRACE("启动红老鼠进程启动失败\r");
  308. AfxMessageBox("启动红老鼠进程启动失败!");
  309. return 0;
  310. }
  311. }
  312. BOOL bRet = FALSE;
  313. // 连接服务器;
  314. for (int i = 0; i < 5; i++)
  315. {
  316. if ((bRet = RedRat::g_Connect(_T("127.0.0.1"), 40000)))
  317. break;
  318. Sleep(1000);
  319. }
  320. if (!bRet)
  321. AfxMessageBox("连接红老鼠服务端失败,请重启设备!");
  322. // 更新按钮状态;
  323. UpdateSignalBtnStatus();
  324. // 获取设备列表,以逗号分隔;
  325. std::string devices = RedRat::g_getDeviceNames();
  326. if (devices.size() == 0)
  327. {
  328. AfxMessageBox("当前无红老鼠设备连接!");
  329. }
  330. return 1;
  331. }, bReStart);
  332. t.detach();
  333. }
  334. void CIRControlWnd::ReLoadSignalXml()
  335. {
  336. if (Global::g_Config.enableTW)
  337. {
  338. std::string signaldir = Global::g_Config.twSignaldir;
  339. std::string signalpath = signaldir + "\\";
  340. signalpath.append(Global::g_Config.twUseSignal + ".xml");
  341. if (!PathFileExists(signalpath.c_str()))
  342. {
  343. AfxMessageBox(_T("该信号文件不存在!"));
  344. // 设置默认的;
  345. CString strSignal;
  346. m_wndSignalCombo.SetCurSel(0);
  347. m_wndSignalCombo.GetLBText(0, strSignal);
  348. signalpath = signaldir;
  349. signalpath.append(strSignal.GetString());
  350. signalpath.append(".xml");
  351. // 保存到配置文件中;
  352. Global::g_Config.twUseSignal = strSignal.GetString();
  353. WritePrivateProfileString("TestWizard", "useSignal", strSignal.GetString(), Global::g_szConfig);
  354. }
  355. else // 切换通用类型时用到;
  356. {
  357. m_wndSignalCombo.SelectString(0, Global::g_Config.twUseSignal.c_str());
  358. }
  359. // 加载指定目录的xml信号集文件;
  360. if (0 != TW::LoadXml(signalpath.c_str()))
  361. {
  362. TRACE("加载信号集文件失败\r");
  363. }
  364. else
  365. {
  366. TRACE("加载信号集文件成功\r");
  367. UpdateSignalBtnStatus();
  368. }
  369. }
  370. else {
  371. std::string signaldir, signalpath;
  372. if (Global::g_Config.bGenerics)
  373. {
  374. signaldir = Global::g_Config.signaldir + "\\general\\";
  375. }
  376. else
  377. {
  378. signaldir = Global::g_Config.signaldir + "\\product\\";
  379. }
  380. signalpath = signaldir;
  381. signalpath.append(Global::g_Config.use_signal + ".xml");
  382. if (!PathFileExists(signalpath.c_str()))
  383. {
  384. AfxMessageBox(_T("该信号文件不存在!"));
  385. // 设置默认的;
  386. CString strSignal;
  387. m_wndSignalCombo.SetCurSel(0);
  388. m_wndSignalCombo.GetLBText(0, strSignal);
  389. signalpath = signaldir;
  390. signalpath.append(strSignal.GetString());
  391. signalpath.append(".xml");
  392. // 保存到配置文件中;
  393. Global::g_Config.use_signal = strSignal.GetString();
  394. WritePrivateProfileString("ir-device", "use-signal", strSignal.GetString(), Global::g_szConfig);
  395. }
  396. else // 切换通用类型时用到;
  397. {
  398. m_wndSignalCombo.SelectString(0, Global::g_Config.use_signal.c_str());
  399. }
  400. // 加载指定目录的xml信号集文件;
  401. if (!RedRat::g_loadSignalDataSet(signalpath.c_str()))
  402. {
  403. TRACE("加载信号集文件失败\r");
  404. }
  405. else
  406. {
  407. TRACE("加载信号集文件成功\r");
  408. UpdateSignalBtnStatus();
  409. }
  410. }
  411. }
  412. void CIRControlWnd::LoadSignals()
  413. {
  414. if (Global::g_Config.enableTW)
  415. {
  416. filehelper fh;
  417. fh.getfiles_findout_subfolder(Global::g_Config.twSignaldir.c_str(), NULL, &m_vtsignal_tw);
  418. m_wndSignalCombo.ResetContent();
  419. for (auto it : m_vtsignal_tw)
  420. {
  421. m_wndSignalCombo.AddString(fh.getfilename(it).c_str());
  422. }
  423. }
  424. else
  425. {
  426. filehelper fh;
  427. fh.getfiles_findout_subfolder((Global::g_Config.signaldir + "\\general\\").c_str(), NULL, &m_vtsignal_gen);
  428. fh.getfiles_findout_subfolder((Global::g_Config.signaldir + "\\product\\").c_str(), NULL, &m_vtsignal_pro);
  429. // 添加到combobox中;
  430. if (Global::g_Config.bGenerics)
  431. {
  432. m_wndSignalCombo.ResetContent();
  433. for (auto it : m_vtsignal_gen)
  434. {
  435. m_wndSignalCombo.AddString(fh.getfilename(it).c_str());
  436. }
  437. }
  438. else
  439. {
  440. m_wndSignalCombo.ResetContent();
  441. for (auto it : m_vtsignal_pro)
  442. {
  443. m_wndSignalCombo.AddString(fh.getfilename(it).c_str());
  444. }
  445. }
  446. }
  447. AutoSetDroppedWidth();
  448. }
  449. void CIRControlWnd::Loadlayout(std::vector<BtnInfo>& vt)
  450. {
  451. // 解析xml;
  452. std::string path;
  453. path.append(Global::g_szCurModuleDir);
  454. path.append("layout.xml");
  455. tinyxml2::XMLDocument doc;
  456. if (tinyxml2::XML_SUCCESS != doc.LoadFile(path.c_str()))
  457. {
  458. return;
  459. }
  460. vt.clear();
  461. std::string data;
  462. tinyxml2::XMLElement* pXmlRoot = NULL;
  463. if ((pXmlRoot = doc.RootElement()) != NULL)
  464. {
  465. if (_tcsicmp(pXmlRoot->Value(), "ButtonList") == 0)
  466. {
  467. // 子项;
  468. tinyxml2::XMLElement* pXmlElent = pXmlRoot->FirstChildElement();
  469. while (pXmlElent)
  470. {
  471. BtnInfo btninfo;
  472. if (_tcsicmp(pXmlElent->Value(), _T("ITEM")) == 0)
  473. {
  474. tinyxml2::XMLElement* pItem = pXmlElent->FirstChildElement();
  475. while (pItem)
  476. {
  477. if (_tcsicmp(pItem->Value(), _T("NAME")) == 0)
  478. {
  479. btninfo.name = pItem->GetText();
  480. }
  481. else if (_tcsicmp(pItem->Value(), _T("WIDTH")) == 0)
  482. {
  483. data = pItem->GetText();
  484. btninfo.width = _ttol(data.c_str());
  485. }
  486. else if (_tcsicmp(pItem->Value(), _T("HEIGHT")) == 0)
  487. {
  488. data = pItem->GetText();
  489. btninfo.height = _ttol(data.c_str());
  490. }
  491. else if (_tcsicmp(pItem->Value(), _T("COLOR")) == 0)
  492. {
  493. data = pItem->GetText();
  494. btninfo.color = HexColor2RGB(data);
  495. }
  496. btninfo.pBTN = new CMFCButton();
  497. pItem = pItem->NextSiblingElement();
  498. }
  499. }
  500. vt.push_back(btninfo);
  501. pXmlElent = pXmlElent->NextSiblingElement();
  502. }
  503. }
  504. }
  505. int sx = 0, sy = m_nComboHeight*2+15;
  506. int i = 0, id = 10000;
  507. DWORD dwStyle = WS_CHILD | WS_VISIBLE;
  508. for (std::vector<BtnInfo>::iterator it = vt.begin(); it != vt.end(); it++)
  509. {
  510. if (i != 0 && i % 4 == 0)
  511. {//换行;
  512. sy += it->height + 5;
  513. }
  514. sx = (i % 4) * it->width + (i % 4 + 1) * 5;
  515. it->pBTN->Create(it->name.c_str(), dwStyle, CRect(sx, sy, sx + it->width, sy + it->height), this, BTNID + i);
  516. // 设置透明false以显示背景色
  517. it->pBTN->m_bTransparent = FALSE;
  518. it->pBTN->m_bDontUseWinXPTheme = TRUE;
  519. // 设置背景色;
  520. it->pBTN->SetFaceColor(it->color, TRUE);
  521. // 消除单击时黑色内圈;
  522. it->pBTN->m_bDrawFocus = FALSE;
  523. // 设置按钮扁平样式;
  524. it->pBTN->m_nFlatStyle = CMFCButton::FlatStyle::BUTTONSTYLE_FLAT;
  525. // 设置鼠标形状;
  526. it->pBTN->SetMouseCursorHand();
  527. // 存入map中;
  528. m_map_btn.insert(std::pair<UINT, BtnInfo&>(BTNID+i, *it));
  529. i++;
  530. }
  531. }
  532. // 如果CDockablePane无控件,改变大小时背景会刷新失败;
  533. // 所以要重载onpaint;
  534. void CIRControlWnd::OnPaint()
  535. {
  536. CPaintDC dc(this); // device context for painting
  537. // TODO: 在此处添加消息处理程序代码
  538. // 不为绘图消息调用 CDockablePane::OnPaint();
  539. CRect rc;
  540. GetClientRect(rc);
  541. CBrush brush;
  542. brush.CreateSolidBrush(0xFFEFD5);
  543. dc.FillRect(&rc, &brush);
  544. }
  545. void CIRControlWnd::OnSignalBtnClick(UINT uId) // 发送遥控信号;
  546. {
  547. CWnd* pWnd = GetFocus();
  548. int id = pWnd->GetDlgCtrlID();
  549. if (id >= BTNID && id <= BTNID + 100)
  550. {
  551. CString text;
  552. pWnd->GetWindowText(text);
  553. if (Global::g_Config.enableTW)
  554. {
  555. TW::SendKey(text.GetString());
  556. Sleep(1000);
  557. }
  558. else {
  559. // 发送单信号;
  560. if (RedRat::g_sendSignal(text.GetString(), 1, 20))
  561. {
  562. m_bSendKey = TRUE;
  563. TRACE("发送单信号成功\n");
  564. }
  565. else
  566. {
  567. TRACE("发送单信号失败\n");
  568. }
  569. }
  570. }
  571. }
  572. void CIRControlWnd::OnUpdateSignalBtn(CCmdUI* pCmdUI)
  573. {
  574. pCmdUI->Enable(m_map_btn.find(pCmdUI->m_nID)->second.bEnable);
  575. }
  576. void CIRControlWnd::OnUpdateCheckBox(CCmdUI* pCmdUI)
  577. {
  578. pCmdUI->Enable(!Global::g_Config.enableTW);
  579. }
  580. void CIRControlWnd::OnCheckBoxClicked()
  581. {
  582. if (Global::g_Config.enableTW)
  583. {
  584. }
  585. else {
  586. Global::g_Config.bGenerics = m_wndSignalCheck.IsChecked();
  587. // 保存到配置文件中;
  588. WritePrivateProfileString("ir-device", "generics", Global::g_Config.bGenerics ? "1" : "0", Global::g_szConfig);
  589. // 添加到combobox中;
  590. if (Global::g_Config.bGenerics)
  591. {
  592. m_wndSignalCombo.ResetContent();
  593. for (auto it : m_vtsignal_gen)
  594. {
  595. m_wndSignalCombo.AddString(filehelper::getfilename(it).c_str());
  596. }
  597. }
  598. else
  599. {
  600. m_wndSignalCombo.ResetContent();
  601. for (auto it : m_vtsignal_pro)
  602. {
  603. m_wndSignalCombo.AddString(filehelper::getfilename(it).c_str());
  604. }
  605. }
  606. AutoSetDroppedWidth();
  607. DisableSignalBtn();
  608. ReLoadSignalXml();
  609. }
  610. }
  611. void CIRControlWnd::OnUpdateBtnRestartProc(CCmdUI* pCmdUI)
  612. {
  613. pCmdUI->Enable(!Global::g_Config.enableTW);
  614. }
  615. void CIRControlWnd::OnBtnRestartProcClicked() // 重启红老鼠;
  616. {
  617. DisableSignalBtn();
  618. StartIRDevice();
  619. }
  620. void CIRControlWnd::UpdateSignalBtnStatus()
  621. {
  622. std::string data;
  623. if (Global::g_Config.enableTW)
  624. {
  625. if (TW::GetSignalsName)
  626. data = TW::GetSignalsName();
  627. }
  628. else{
  629. // 获取信号集;
  630. if (RedRat::g_getSignalsName){
  631. // 获取信号数据集,以\n分隔;
  632. data = RedRat::g_getSignalsName();
  633. }
  634. }
  635. CString signals = data.append(1, '\n').c_str();
  636. signals.MakeUpper();
  637. for (std::vector<BtnInfo>::iterator it = m_vtBtnInfo.begin(); it != m_vtBtnInfo.end(); it++)
  638. {
  639. if (signals.Find((it->name + '\n').c_str()) == -1)
  640. {
  641. it->bEnable = false;
  642. }
  643. else
  644. {
  645. it->bEnable = true;
  646. }
  647. }
  648. }
  649. void CIRControlWnd::AutoSetDroppedWidth()
  650. {
  651. return AddHScroll();
  652. // Set the height of every item so the item
  653. // is completely visible.
  654. CString str;
  655. CSize sz;
  656. int dx = 0;
  657. CDC* pDC = m_wndSignalCombo.GetDC();
  658. for (int i = 0; i < m_wndSignalCombo.GetCount(); i++)
  659. {
  660. m_wndSignalCombo.GetLBText(i, str);
  661. sz = pDC->GetTextExtent(str);
  662. // Only want to set the item height if the current height
  663. // is not big enough.
  664. if (m_wndSignalCombo.GetItemHeight(i) < sz.cy)
  665. m_wndSignalCombo.SetItemHeight(i, sz.cy);
  666. // Only want to set the item width if the current width
  667. // is not big enough.
  668. if (m_wndSignalCombo.GetDroppedWidth() < sz.cx)
  669. {
  670. m_wndSignalCombo.SetDroppedWidth(sz.cx + 50);
  671. }
  672. }
  673. m_wndSignalCombo.ReleaseDC(pDC);
  674. }
  675. void CIRControlWnd::AddHScroll()
  676. {
  677. // Find the longest string in the combo box.
  678. CString str;
  679. CSize sz;
  680. int dx = 0;
  681. TEXTMETRIC tm = { 0 };
  682. CDC* pDC = m_wndSignalCombo.GetDC();
  683. CFont* pFont = m_wndSignalCombo.GetFont();
  684. // Select the listbox font, save the old font
  685. CFont* pOldFont = pDC->SelectObject(pFont);
  686. // Get the text metrics for avg char width
  687. pDC->GetTextMetrics(&tm);
  688. for (int i = 0; i < m_wndSignalCombo.GetCount(); i++)
  689. {
  690. m_wndSignalCombo.GetLBText(i, str);
  691. sz = pDC->GetTextExtent(str);
  692. // Add the avg width to prevent clipping
  693. sz.cx += tm.tmAveCharWidth;
  694. if (sz.cx > dx)
  695. dx = sz.cx;
  696. }
  697. // Select the old font back into the DC
  698. pDC->SelectObject(pOldFont);
  699. m_wndSignalCombo.ReleaseDC(pDC);
  700. // Set the horizontal extent so every character of all strings can
  701. // be scrolled to.
  702. m_wndSignalCombo.SetHorizontalExtent(dx);
  703. }
  704. LRESULT CIRControlWnd::OnIRShotImg(WPARAM wparam, LPARAM lparam)
  705. {
  706. return LRESULT();
  707. }