#include "StdAfx.h" #include #include "Common_Funcs.h" #include "WindNode.h" #include "AutoFunc.h" #include "Common_def.h" #include "XMLLoader.h" #include "WindFuncs.h" //#include "debug.h" using namespace std; WindowObject::WindowObject(void) { m_SubNodes = new map(); m_ConfigName = new string(); m_ID = new string(); m_Process = new string(); m_ReqTitle = new string(); m_Class = new string(); m_Dict = new string(); m_DictKey = new string(); m_ExistTitle = new string(); ClearObject(); } WindowObject::~WindowObject(void) { ClearObject(); delete m_SubNodes; m_SubNodes = NULL; delete m_ConfigName; m_ConfigName = NULL; delete m_ID; m_ID = NULL; delete m_Process; m_Process = NULL; delete m_ReqTitle; m_ReqTitle = NULL; delete m_Class; m_Class = NULL; delete m_Dict; m_Dict = NULL; delete m_DictKey; m_DictKey = NULL; delete m_ExistTitle; m_ExistTitle = NULL; } void WindowObject::ClearLocateData() { m_ResHwnd = 0; m_ResDictKey.x = -1; m_ResDictKey.y = -1; for (map::iterator iter1 = m_SubNodes->begin(); iter1 != m_SubNodes->end(); iter1++) { iter1->second->ClearLocateData(); } } void WindowObject::ClearObject() { m_Style = NO_WNDTYPE; m_StyleEx = NO_WNDTYPE; m_zOrder = ZORDER_ALLSEARCH; m_Width = 0; m_Height = 0; m_ResHwnd = 0; (*m_ConfigName) = _T(""); (*m_ID) = _T(""); (*m_Process) = _T(""); (*m_ReqTitle) = _T(""); (*m_ExistTitle) = _T(""); (*m_Class) = _T(""); m_GuiID = NO_GUIID; m_pParent = NULL; m_DictRgb = 0; memset(&m_DictArea,0,sizeof(RECT)); m_ResDictKey.x = -1; m_ResDictKey.y = -1; for(map::iterator iter1 = m_SubNodes->begin();iter1 != m_SubNodes->end();iter1++) { //iter1->second->ClearObject(); delete iter1->second; } m_SubNodes->clear(); } BOOL WindowObject::MakeParentTree() { BOOL ret = FALSE; map::iterator iter1 = m_SubNodes->begin(); for(; iter1 != m_SubNodes->end();iter1++) { iter1->second->m_pParent = this; ret = iter1->second->MakeParentTree(); if(ret == FALSE) { return ret; } } return TRUE; } BOOL WindowObject::LoadConfig(const TCHAR * pRFilePath) { BOOL ret = FALSE; XMLLoader loader; ClearObject(); string filepath = pRFilePath; if(loader.LoadFile(filepath)) { ret = loader.GetWindowObject(*this); if(ret) { (*m_ConfigName) = filepath; //make parent if(MakeParentTree() == FALSE) { ret = FALSE; } } } return ret; } WindowObject& WindowObject::operator = (WindNode &node) { (*(m_Process)) = node.m_ProcessName; (*(m_Class)) = node.m_Class; (*m_ReqTitle) = node.m_Name; m_Style = node.m_WndType; m_StyleEx = node.m_WndTypeEx; m_Width = node.m_Width; m_Height = node.m_Height; m_zOrder = node.m_ResZOrder; m_GuiID = node.m_GuiID; m_ResHwnd = node.m_ResHwnd;//res hwnd (*m_Dict) = node.m_Dict; (*m_DictKey) = node.m_DictKey; m_DictRgb = node.m_DictRgb; m_DictArea = node.m_DictArea; m_ResDictKey = node.m_ResDictKey;//res point return *this; } BOOL FilterWindowsByParent(WindowObject *pObj,vector &list1) { //call in when this obj located BOOL ret = FALSE; //no parent if(pObj->m_pParent == NULL) { return TRUE; } //parent exist for(vector::iterator iter1 = list1.begin();iter1 != list1.end();) { //zOrder check if(WindFuncs::GetZOrder(iter1->m_ResHwnd) == (ZORDER_DESKTOP+1)) { iter1 = list1.erase(iter1); continue; } //window check, //realparentHwnd VS parentWindowObject HWND parent = WindFuncs::GetTrueParent(iter1->m_ResHwnd); if(WindFuncs::CheckWindowMatch(parent,(WindNode)*pObj->m_pParent) == FALSE) { iter1 = list1.erase(iter1); continue; } //parent is ok,do check upper layer vector parentlist; pObj->m_pParent->m_ResHwnd = parent; parentlist.push_back((WindNode)*pObj->m_pParent); if(FilterWindowsByParent(pObj->m_pParent,parentlist) == FALSE) { iter1 = list1.erase(iter1); continue; } iter1++; } return (list1.size() > 0); } INT WindowObject::LocateWindow(BOOL Visible) { WindNode node = (*this); vector list1; HWND pParent = NULL; if(m_pParent && m_pParent->m_ResHwnd) { pParent = m_pParent->m_ResHwnd; } WindFuncs::LocateWindows(pParent,node,list1,Visible); if(list1.size() == 0) { return -1;//none exist } //do check parent if(FilterWindowsByParent(this,list1) == FALSE) { return -1;//none exist } //do it again if(FilterWindowsByParent(this,list1) == FALSE) { return -1;//none exist } //if(m_SubNodes->size() == 0) { (*this) = list1[list1.size() - 1]; if(list1.size() > 1) { //multiple result return 0; } //search one - got one return 1; } //DWORD HitIdx = list1.size() - 1; //multiple results && multiple sub nodes //if we go dig deeper,the level2 window might not exist. //just find the sub windows in the level1. //vector list_match; //for(DWORD i = 0;i < list1.size();i++) //{ // // // BOOL match_one = TRUE; // vector list_sub; // // for(map::iterator iter1 = m_SubNodes->begin();iter1 != m_SubNodes->end();iter1++) // { // list_sub.clear(); // if(WindFuncs::LocateWindows(list1[HitIdx].m_ResHwnd,(WindNode)iter1->second,list_sub) == FALSE) // { // match_one = FALSE; // } // else // { // //check one level distance // for(DWORD j = 0;j < list_sub.size();j++) // { // if(list1[HitIdx].m_ResZOrder != (list_sub[j].m_ResZOrder - 1)) // { // match_one = FALSE; // break; // } // } // } // if(match_one == FALSE) // { // break; // } // } // //got one match cur windowObject // if(match_one) // { // list_match.push_back(list1[HitIdx]); // } //} ////got match //if(list_match.size() > 0) //{ // (*this) = list_match[0];//get first one // if(list_match.size() == 1) // { // return 1; // } // return 0; //} //(*this) = list1[list1.size() - 1]; //return 0; } BOOL WindowObject::DoClick(BOOL real) { BOOL ret = MouseMove(real); ret &= ClickLB(real); return ret; } INT WindowObject::WaitHideWindow(TCHAR *pID, HITMETHOD hm, DWORD tmPeriod, BOOL Exp, DWORD moretry) { INT ret = 0; do { DWORD usedTmPeriod = 0; DWORD ConfirmTime = 2000; //Step1:locate Visible window if (pID) { ret = (*this)[pID].WaitLocateWindow(ConfirmTime, TRUE, Exp); } else { ret = WaitLocateWindow(ConfirmTime, TRUE, Exp); } if (ret <= 0) { return 1; } //Step2: operation if (pID) { switch (hm) { case HM_NOTIFY_PARENT: (*this)[pID].NotifyParentHitButton(); break; case HM_HIT: (*this)[pID].DoClick(); break; case HM_CLICK: (*this)[pID].HitMouse(WM_LBUTTONDOWN, 0, 10, 10); Sleep(100); (*this)[pID].HitMouse(WM_LBUTTONUP, 0, 10, 10); break; case HM_REALCLICK: (*this)[pID].DoClick(TRUE); break; default: if (Exp) { throw ExpObject("WaitHideWindow HM type is wrong"); } return -1; break; } } else { switch (hm) { case HM_NOTIFY_PARENT: (*this).NotifyParentHitButton(); break; case HM_HIT: (*this).ClickLB(); break; case HM_CLICK: (*this).HitMouse(WM_LBUTTONDOWN, 0, 10, 10); Sleep(100); (*this).HitMouse(WM_LBUTTONUP, 0, 10, 10); break; case HM_REALCLICK: (*this)[pID].DoClick(TRUE); break; default: if (Exp) { throw ExpObject("WaitHideWindow HM type is wrong"); } return -1; break; } } //Step3:wait invisible do { Sleep(250); usedTmPeriod += 250; if (pID) { ret = (*this)[pID].IsObjectVisible(); } else { ret = IsObjectVisible(); } if (ret <= 0) { return 1; } if (usedTmPeriod > tmPeriod) { break; } } while (usedTmPeriod < tmPeriod); } while (moretry--); if(ret > 0) { if(Exp) { string errMsg = _T("timeout.couldn't hide window::ID--"); errMsg += (*m_ConfigName); errMsg += _T(":"); errMsg += (*m_ID); throw ExpObject(errMsg.c_str()); } return 0; } return 1; } INT WindowObject::IsObjectVisible() { if(m_ResHwnd) { if(IsWindowVisible(m_ResHwnd)) { return 1; } return 0; } return -1; } INT WindowObject::WaitLocateWindow(DWORD tmPeriod,BOOL Visible,BOOL Exp) { INT ret = 0; DWORD usedTmPeriod = 0; do { ret = LocateWindow(Visible); if(ret != -1) { break; } Sleep(50); if(tmPeriod == INFINITE) { continue; } usedTmPeriod += 50; if(usedTmPeriod > tmPeriod) { break; } } while(usedTmPeriod < tmPeriod); //if(ret < 0) //{ // if(Exp) // { // wstring errMsg = L"no window Hwnd. window::ID--"; // errMsg += (*m_ConfigName); // errMsg += L":"; // errMsg += (*m_ID); // throw ExpObject(errMsg.c_str()); // } //} // if(ret < 0) { if(Exp) { string errMsg = _T("timeout.couldn't find window::ID--"); errMsg += (*m_ConfigName); errMsg += ":"; errMsg += (*m_ID); throw ExpObject(errMsg.c_str()); } } return ret; } BOOL WindowObject::SendMessageTo(DWORD msg,DWORD wp,DWORD lp,BOOL sendFlag) { if(sendFlag) { SendMessage(m_ResHwnd,msg,(WPARAM)wp,(LPARAM)lp); } else { if(PostMessage(m_ResHwnd,msg,(WPARAM)wp,(LPARAM)lp) == 0) { DWORD errCode = GetLastError(); //DebugPrint(_T("Failed PostMessage To ID:%s,code:%d\r\n"),m_ID.c_str(),errCode); return FALSE; } } return TRUE; } BOOL WindowObject::MakeFocus(BOOL real) { return InputCmds::MakeFocus(m_ResHwnd,real); } BOOL WindowObject::SetText(TCHAR *pContext,BOOL real) { return InputCmds::SetText(m_ResHwnd,pContext,real); } BOOL WindowObject::NotifyParentHitButton() { return InputCmds::NotifyParentHitButton(m_ResHwnd); } BOOL WindowObject::ClickLB(BOOL real) { return InputCmds::ClickLB(m_ResHwnd, real); } BOOL WindowObject::HitVKey(DWORD vk,BOOL real) { return InputCmds::HitKey(m_ResHwnd,vk,real); } BOOL WindowObject::HitKey(DWORD vk,BOOL real) { return InputCmds::HitKey(m_ResHwnd,vk,real); } BOOL WindowObject::MouseMove(BOOL real) { return InputCmds::MouseMove(m_ResHwnd,real); } BOOL WindowObject::MouseMove(int x,int y,BOOL real) { return InputCmds::MouseMove(m_ResHwnd,x,y,real); } //MsgType including //WM_LBUTTONDOWN //WM_LBUTTONUP //WM_LBUTTONDBLCLK //RIGHT //... //MIDDLE //... //ExKey including below //MK_CONTROL //MK_LBUTTON //MK_MBUTTON //MK_RBUTTON //MK_SHIFT //normal----------------- //InputCmds::HitMouse(curWind,WM_LBUTTONDBLCLK,MK_LBUTTON,10,10); //InputCmds::HitMouse(curWind,WM_LBUTTONUP,0,10,10); //real----------------- //InputCmds::HitMouse(curWind,MOUSEEVENTF_LEFTDOWN,MK_LBUTTON,10,10); //InputCmds::HitMouse(curWind,MOUSEEVENTF_LEFTUP,0,10,10); BOOL WindowObject::HitMouse(DWORD MsgType,DWORD ExKey,int x,int y,BOOL real) { return InputCmds::HitMouse(m_ResHwnd,MsgType,ExKey,x,y,real); } WindowObject &WindowObject::operator [](TCHAR *pID) { string keystr = pID; map::iterator iter1 = m_SubNodes->find(keystr); if(iter1 != m_SubNodes->end()) { return (*(iter1->second)); } string Msgstr = format_string("No such ID:%s", pID); MessageBox(NULL,Msgstr.c_str(),"WTH",MB_OK); WindowObject *pObj = new WindowObject(); return (*pObj); } HWND WindowObject::GetLocatedHwnd() { return m_ResHwnd; } POINT WindowObject::GetLocatedTopLeft() { return m_ResDictKey; } const TCHAR* WindowObject::GetProcessName() { return m_Process->c_str(); } const TCHAR* WindowObject::GetTitle() { TCHAR szTitle[MAX_PATH] = {0}; if(m_ResHwnd) { AttachThreadInput( ::GetWindowThreadProcessId((m_ResHwnd), NULL), //当前焦点窗口的线程ID ::GetCurrentThreadId(), //自己的线程ID TRUE); LRESULT lResult = SendMessage( // returns LRESULT in lResult m_ResHwnd, // handle to destination control (UINT)WM_GETTEXT, // message ID (WPARAM)MAX_PATH, // = (WPARAM) () wParam; (LPARAM)szTitle // = 0; not used, must be zero ); } (*m_ExistTitle) = szTitle; return m_ExistTitle->c_str(); } AUTOFUNC_C_API WindowObject* GetWindowObject(void) { return new WindowObject; } AUTOFUNC_C_API void ReleaseWindowObject(WindowObject* &pObj) { delete pObj; pObj = NULL; }