WindowObject.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. #include "StdAfx.h"
  2. #include <vector>
  3. #include "Common_Funcs.h"
  4. #include "WindNode.h"
  5. #include "AutoFunc.h"
  6. #include "Common_def.h"
  7. #include "XMLLoader.h"
  8. #include "WindFuncs.h"
  9. //#include "debug.h"
  10. using namespace std;
  11. WindowObject::WindowObject(void)
  12. {
  13. m_SubNodes = new map<string, WindowObject*>();
  14. m_ConfigName = new string();
  15. m_ID = new string();
  16. m_Process = new string();
  17. m_ReqTitle = new string();
  18. m_Class = new string();
  19. m_Dict = new string();
  20. m_DictKey = new string();
  21. m_ExistTitle = new string();
  22. ClearObject();
  23. }
  24. WindowObject::~WindowObject(void)
  25. {
  26. ClearObject();
  27. delete m_SubNodes;
  28. m_SubNodes = NULL;
  29. delete m_ConfigName;
  30. m_ConfigName = NULL;
  31. delete m_ID;
  32. m_ID = NULL;
  33. delete m_Process;
  34. m_Process = NULL;
  35. delete m_ReqTitle;
  36. m_ReqTitle = NULL;
  37. delete m_Class;
  38. m_Class = NULL;
  39. delete m_Dict;
  40. m_Dict = NULL;
  41. delete m_DictKey;
  42. m_DictKey = NULL;
  43. delete m_ExistTitle;
  44. m_ExistTitle = NULL;
  45. }
  46. void WindowObject::ClearLocateData()
  47. {
  48. m_ResHwnd = 0;
  49. m_ResDictKey.x = -1;
  50. m_ResDictKey.y = -1;
  51. for (map<string, WindowObject*>::iterator iter1 = m_SubNodes->begin(); iter1 != m_SubNodes->end(); iter1++)
  52. {
  53. iter1->second->ClearLocateData();
  54. }
  55. }
  56. void WindowObject::ClearObject()
  57. {
  58. m_Style = NO_WNDTYPE;
  59. m_StyleEx = NO_WNDTYPE;
  60. m_zOrder = ZORDER_ALLSEARCH;
  61. m_Width = 0;
  62. m_Height = 0;
  63. m_ResHwnd = 0;
  64. (*m_ConfigName) = _T("");
  65. (*m_ID) = _T("");
  66. (*m_Process) = _T("");
  67. (*m_ReqTitle) = _T("");
  68. (*m_ExistTitle) = _T("");
  69. (*m_Class) = _T("");
  70. m_GuiID = NO_GUIID;
  71. m_pParent = NULL;
  72. m_DictRgb = 0;
  73. memset(&m_DictArea,0,sizeof(RECT));
  74. m_ResDictKey.x = -1;
  75. m_ResDictKey.y = -1;
  76. for(map<string,WindowObject*>::iterator iter1 = m_SubNodes->begin();iter1 != m_SubNodes->end();iter1++)
  77. {
  78. //iter1->second->ClearObject();
  79. delete iter1->second;
  80. }
  81. m_SubNodes->clear();
  82. }
  83. BOOL WindowObject::MakeParentTree()
  84. {
  85. BOOL ret = FALSE;
  86. map<string, WindowObject*>::iterator iter1 = m_SubNodes->begin();
  87. for(; iter1 != m_SubNodes->end();iter1++)
  88. {
  89. iter1->second->m_pParent = this;
  90. ret = iter1->second->MakeParentTree();
  91. if(ret == FALSE)
  92. {
  93. return ret;
  94. }
  95. }
  96. return TRUE;
  97. }
  98. BOOL WindowObject::LoadConfig(const TCHAR * pRFilePath)
  99. {
  100. BOOL ret = FALSE;
  101. XMLLoader loader;
  102. ClearObject();
  103. string filepath = pRFilePath;
  104. if(loader.LoadFile(filepath))
  105. {
  106. ret = loader.GetWindowObject(*this);
  107. if(ret)
  108. {
  109. (*m_ConfigName) = filepath;
  110. //make parent
  111. if(MakeParentTree() == FALSE)
  112. {
  113. ret = FALSE;
  114. }
  115. }
  116. }
  117. return ret;
  118. }
  119. WindowObject& WindowObject::operator = (WindNode &node)
  120. {
  121. (*(m_Process)) = node.m_ProcessName;
  122. (*(m_Class)) = node.m_Class;
  123. (*m_ReqTitle) = node.m_Name;
  124. m_Style = node.m_WndType;
  125. m_StyleEx = node.m_WndTypeEx;
  126. m_Width = node.m_Width;
  127. m_Height = node.m_Height;
  128. m_zOrder = node.m_ResZOrder;
  129. m_GuiID = node.m_GuiID;
  130. m_ResHwnd = node.m_ResHwnd;//res hwnd
  131. (*m_Dict) = node.m_Dict;
  132. (*m_DictKey) = node.m_DictKey;
  133. m_DictRgb = node.m_DictRgb;
  134. m_DictArea = node.m_DictArea;
  135. m_ResDictKey = node.m_ResDictKey;//res point
  136. return *this;
  137. }
  138. BOOL FilterWindowsByParent(WindowObject *pObj,vector<WindNode> &list1)
  139. {
  140. //call in when this obj located
  141. BOOL ret = FALSE;
  142. //no parent
  143. if(pObj->m_pParent == NULL)
  144. {
  145. return TRUE;
  146. }
  147. //parent exist
  148. for(vector<WindNode>::iterator iter1 = list1.begin();iter1 != list1.end();)
  149. {
  150. //zOrder check
  151. if(WindFuncs::GetZOrder(iter1->m_ResHwnd) == (ZORDER_DESKTOP+1))
  152. {
  153. iter1 = list1.erase(iter1);
  154. continue;
  155. }
  156. //window check,
  157. //realparentHwnd VS parentWindowObject
  158. HWND parent = WindFuncs::GetTrueParent(iter1->m_ResHwnd);
  159. if(WindFuncs::CheckWindowMatch(parent,(WindNode)*pObj->m_pParent) == FALSE)
  160. {
  161. iter1 = list1.erase(iter1);
  162. continue;
  163. }
  164. //parent is ok,do check upper layer
  165. vector<WindNode> parentlist;
  166. pObj->m_pParent->m_ResHwnd = parent;
  167. parentlist.push_back((WindNode)*pObj->m_pParent);
  168. if(FilterWindowsByParent(pObj->m_pParent,parentlist) == FALSE)
  169. {
  170. iter1 = list1.erase(iter1);
  171. continue;
  172. }
  173. iter1++;
  174. }
  175. return (list1.size() > 0);
  176. }
  177. INT WindowObject::LocateWindow(BOOL Visible)
  178. {
  179. WindNode node = (*this);
  180. vector<WindNode> list1;
  181. HWND pParent = NULL;
  182. if(m_pParent && m_pParent->m_ResHwnd)
  183. {
  184. pParent = m_pParent->m_ResHwnd;
  185. }
  186. WindFuncs::LocateWindows(pParent,node,list1,Visible);
  187. if(list1.size() == 0)
  188. {
  189. return -1;//none exist
  190. }
  191. //do check parent
  192. if(FilterWindowsByParent(this,list1) == FALSE)
  193. {
  194. return -1;//none exist
  195. }
  196. //do it again
  197. if(FilterWindowsByParent(this,list1) == FALSE)
  198. {
  199. return -1;//none exist
  200. }
  201. //if(m_SubNodes->size() == 0)
  202. {
  203. (*this) = list1[list1.size() - 1];
  204. if(list1.size() > 1)
  205. {
  206. //multiple result
  207. return 0;
  208. }
  209. //search one - got one
  210. return 1;
  211. }
  212. //DWORD HitIdx = list1.size() - 1;
  213. //multiple results && multiple sub nodes
  214. //if we go dig deeper,the level2 window might not exist.
  215. //just find the sub windows in the level1.
  216. //vector<WindNode> list_match;
  217. //for(DWORD i = 0;i < list1.size();i++)
  218. //{
  219. // //
  220. // BOOL match_one = TRUE;
  221. // vector<WindNode> list_sub;
  222. //
  223. // for(map<wstring,WindowObject>::iterator iter1 = m_SubNodes->begin();iter1 != m_SubNodes->end();iter1++)
  224. // {
  225. // list_sub.clear();
  226. // if(WindFuncs::LocateWindows(list1[HitIdx].m_ResHwnd,(WindNode)iter1->second,list_sub) == FALSE)
  227. // {
  228. // match_one = FALSE;
  229. // }
  230. // else
  231. // {
  232. // //check one level distance
  233. // for(DWORD j = 0;j < list_sub.size();j++)
  234. // {
  235. // if(list1[HitIdx].m_ResZOrder != (list_sub[j].m_ResZOrder - 1))
  236. // {
  237. // match_one = FALSE;
  238. // break;
  239. // }
  240. // }
  241. // }
  242. // if(match_one == FALSE)
  243. // {
  244. // break;
  245. // }
  246. // }
  247. // //got one match cur windowObject
  248. // if(match_one)
  249. // {
  250. // list_match.push_back(list1[HitIdx]);
  251. // }
  252. //}
  253. ////got match
  254. //if(list_match.size() > 0)
  255. //{
  256. // (*this) = list_match[0];//get first one
  257. // if(list_match.size() == 1)
  258. // {
  259. // return 1;
  260. // }
  261. // return 0;
  262. //}
  263. //(*this) = list1[list1.size() - 1];
  264. //return 0;
  265. }
  266. BOOL WindowObject::DoClick(BOOL real)
  267. {
  268. BOOL ret = MouseMove(real);
  269. ret &= ClickLB(real);
  270. return ret;
  271. }
  272. INT WindowObject::WaitHideWindow(TCHAR *pID, HITMETHOD hm, DWORD tmPeriod, BOOL Exp, DWORD moretry)
  273. {
  274. INT ret = 0;
  275. do
  276. {
  277. DWORD usedTmPeriod = 0;
  278. DWORD ConfirmTime = 2000;
  279. //Step1:locate Visible window
  280. if (pID)
  281. {
  282. ret = (*this)[pID].WaitLocateWindow(ConfirmTime, TRUE, Exp);
  283. }
  284. else
  285. {
  286. ret = WaitLocateWindow(ConfirmTime, TRUE, Exp);
  287. }
  288. if (ret <= 0)
  289. {
  290. return 1;
  291. }
  292. //Step2: operation
  293. if (pID)
  294. {
  295. switch (hm)
  296. {
  297. case HM_NOTIFY_PARENT:
  298. (*this)[pID].NotifyParentHitButton();
  299. break;
  300. case HM_HIT:
  301. (*this)[pID].DoClick();
  302. break;
  303. case HM_CLICK:
  304. (*this)[pID].HitMouse(WM_LBUTTONDOWN, 0, 10, 10);
  305. Sleep(100);
  306. (*this)[pID].HitMouse(WM_LBUTTONUP, 0, 10, 10);
  307. break;
  308. case HM_REALCLICK:
  309. (*this)[pID].DoClick(TRUE);
  310. break;
  311. default:
  312. if (Exp)
  313. {
  314. throw ExpObject("WaitHideWindow HM type is wrong");
  315. }
  316. return -1;
  317. break;
  318. }
  319. }
  320. else
  321. {
  322. switch (hm)
  323. {
  324. case HM_NOTIFY_PARENT:
  325. (*this).NotifyParentHitButton();
  326. break;
  327. case HM_HIT:
  328. (*this).ClickLB();
  329. break;
  330. case HM_CLICK:
  331. (*this).HitMouse(WM_LBUTTONDOWN, 0, 10, 10);
  332. Sleep(100);
  333. (*this).HitMouse(WM_LBUTTONUP, 0, 10, 10);
  334. break;
  335. case HM_REALCLICK:
  336. (*this)[pID].DoClick(TRUE);
  337. break;
  338. default:
  339. if (Exp)
  340. {
  341. throw ExpObject("WaitHideWindow HM type is wrong");
  342. }
  343. return -1;
  344. break;
  345. }
  346. }
  347. //Step3:wait invisible
  348. do
  349. {
  350. Sleep(250);
  351. usedTmPeriod += 250;
  352. if (pID)
  353. {
  354. ret = (*this)[pID].IsObjectVisible();
  355. }
  356. else
  357. {
  358. ret = IsObjectVisible();
  359. }
  360. if (ret <= 0)
  361. {
  362. return 1;
  363. }
  364. if (usedTmPeriod > tmPeriod)
  365. {
  366. break;
  367. }
  368. } while (usedTmPeriod < tmPeriod);
  369. } while (moretry--);
  370. if(ret > 0)
  371. {
  372. if(Exp)
  373. {
  374. string errMsg = _T("timeout.couldn't hide window::ID--");
  375. errMsg += (*m_ConfigName);
  376. errMsg += _T(":");
  377. errMsg += (*m_ID);
  378. throw ExpObject(errMsg.c_str());
  379. }
  380. return 0;
  381. }
  382. return 1;
  383. }
  384. INT WindowObject::IsObjectVisible()
  385. {
  386. if(m_ResHwnd)
  387. {
  388. if(IsWindowVisible(m_ResHwnd))
  389. {
  390. return 1;
  391. }
  392. return 0;
  393. }
  394. return -1;
  395. }
  396. INT WindowObject::WaitLocateWindow(DWORD tmPeriod,BOOL Visible,BOOL Exp)
  397. {
  398. INT ret = 0;
  399. DWORD usedTmPeriod = 0;
  400. do
  401. {
  402. ret = LocateWindow(Visible);
  403. if(ret != -1)
  404. {
  405. break;
  406. }
  407. Sleep(50);
  408. if(tmPeriod == INFINITE)
  409. {
  410. continue;
  411. }
  412. usedTmPeriod += 50;
  413. if(usedTmPeriod > tmPeriod)
  414. {
  415. break;
  416. }
  417. }
  418. while(usedTmPeriod < tmPeriod);
  419. //if(ret < 0)
  420. //{
  421. // if(Exp)
  422. // {
  423. // wstring errMsg = L"no window Hwnd. window::ID--";
  424. // errMsg += (*m_ConfigName);
  425. // errMsg += L":";
  426. // errMsg += (*m_ID);
  427. // throw ExpObject(errMsg.c_str());
  428. // }
  429. //}
  430. //
  431. if(ret < 0)
  432. {
  433. if(Exp)
  434. {
  435. string errMsg = _T("timeout.couldn't find window::ID--");
  436. errMsg += (*m_ConfigName);
  437. errMsg += ":";
  438. errMsg += (*m_ID);
  439. throw ExpObject(errMsg.c_str());
  440. }
  441. }
  442. return ret;
  443. }
  444. BOOL WindowObject::SendMessageTo(DWORD msg,DWORD wp,DWORD lp,BOOL sendFlag)
  445. {
  446. if(sendFlag)
  447. {
  448. SendMessage(m_ResHwnd,msg,(WPARAM)wp,(LPARAM)lp);
  449. }
  450. else
  451. {
  452. if(PostMessage(m_ResHwnd,msg,(WPARAM)wp,(LPARAM)lp) == 0)
  453. {
  454. DWORD errCode = GetLastError();
  455. //DebugPrint(_T("Failed PostMessage To ID:%s,code:%d\r\n"),m_ID.c_str(),errCode);
  456. return FALSE;
  457. }
  458. }
  459. return TRUE;
  460. }
  461. BOOL WindowObject::MakeFocus(BOOL real)
  462. {
  463. return InputCmds::MakeFocus(m_ResHwnd,real);
  464. }
  465. BOOL WindowObject::SetText(TCHAR *pContext,BOOL real)
  466. {
  467. return InputCmds::SetText(m_ResHwnd,pContext,real);
  468. }
  469. BOOL WindowObject::NotifyParentHitButton()
  470. {
  471. return InputCmds::NotifyParentHitButton(m_ResHwnd);
  472. }
  473. BOOL WindowObject::ClickLB(BOOL real)
  474. {
  475. return InputCmds::ClickLB(m_ResHwnd, real);
  476. }
  477. BOOL WindowObject::HitVKey(DWORD vk,BOOL real)
  478. {
  479. return InputCmds::HitKey(m_ResHwnd,vk,real);
  480. }
  481. BOOL WindowObject::HitKey(DWORD vk,BOOL real)
  482. {
  483. return InputCmds::HitKey(m_ResHwnd,vk,real);
  484. }
  485. BOOL WindowObject::MouseMove(BOOL real)
  486. {
  487. return InputCmds::MouseMove(m_ResHwnd,real);
  488. }
  489. BOOL WindowObject::MouseMove(int x,int y,BOOL real)
  490. {
  491. return InputCmds::MouseMove(m_ResHwnd,x,y,real);
  492. }
  493. //MsgType including
  494. //WM_LBUTTONDOWN
  495. //WM_LBUTTONUP
  496. //WM_LBUTTONDBLCLK
  497. //RIGHT
  498. //...
  499. //MIDDLE
  500. //...
  501. //ExKey including below
  502. //MK_CONTROL
  503. //MK_LBUTTON
  504. //MK_MBUTTON
  505. //MK_RBUTTON
  506. //MK_SHIFT
  507. //normal-----------------
  508. //InputCmds::HitMouse(curWind,WM_LBUTTONDBLCLK,MK_LBUTTON,10,10);
  509. //InputCmds::HitMouse(curWind,WM_LBUTTONUP,0,10,10);
  510. //real-----------------
  511. //InputCmds::HitMouse(curWind,MOUSEEVENTF_LEFTDOWN,MK_LBUTTON,10,10);
  512. //InputCmds::HitMouse(curWind,MOUSEEVENTF_LEFTUP,0,10,10);
  513. BOOL WindowObject::HitMouse(DWORD MsgType,DWORD ExKey,int x,int y,BOOL real)
  514. {
  515. return InputCmds::HitMouse(m_ResHwnd,MsgType,ExKey,x,y,real);
  516. }
  517. WindowObject &WindowObject::operator [](TCHAR *pID)
  518. {
  519. string keystr = pID;
  520. map<string,WindowObject*>::iterator iter1 = m_SubNodes->find(keystr);
  521. if(iter1 != m_SubNodes->end())
  522. {
  523. return (*(iter1->second));
  524. }
  525. string Msgstr = format_string("No such ID:%s", pID);
  526. MessageBox(NULL,Msgstr.c_str(),"WTH",MB_OK);
  527. WindowObject *pObj = new WindowObject();
  528. return (*pObj);
  529. }
  530. HWND WindowObject::GetLocatedHwnd()
  531. {
  532. return m_ResHwnd;
  533. }
  534. POINT WindowObject::GetLocatedTopLeft()
  535. {
  536. return m_ResDictKey;
  537. }
  538. const TCHAR* WindowObject::GetProcessName()
  539. {
  540. return m_Process->c_str();
  541. }
  542. const TCHAR* WindowObject::GetTitle()
  543. {
  544. TCHAR szTitle[MAX_PATH] = {0};
  545. if(m_ResHwnd)
  546. {
  547. AttachThreadInput(
  548. ::GetWindowThreadProcessId((m_ResHwnd), NULL), //当前焦点窗口的线程ID
  549. ::GetCurrentThreadId(), //自己的线程ID
  550. TRUE);
  551. LRESULT lResult = SendMessage( // returns LRESULT in lResult
  552. m_ResHwnd, // handle to destination control
  553. (UINT)WM_GETTEXT, // message ID
  554. (WPARAM)MAX_PATH, // = (WPARAM) () wParam;
  555. (LPARAM)szTitle // = 0; not used, must be zero
  556. );
  557. }
  558. (*m_ExistTitle) = szTitle;
  559. return m_ExistTitle->c_str();
  560. }
  561. AUTOFUNC_C_API WindowObject* GetWindowObject(void)
  562. {
  563. return new WindowObject;
  564. }
  565. AUTOFUNC_C_API void ReleaseWindowObject(WindowObject* &pObj)
  566. {
  567. delete pObj;
  568. pObj = NULL;
  569. }