From 81158f10d46fdd5d166d551f97bc5ecd10c326d3 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Sat, 30 Mar 2019 01:28:45 +0300 Subject: [PATCH] #NewSearchEngine(depth_start,depth_end,class_name,title,rich_text) #GeneralClipboardSet/Get #MouseVisualSearchFix --- Index.xhtml | 2 +- winGUI.py | 203 +++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 163 insertions(+), 42 deletions(-) diff --git a/Index.xhtml b/Index.xhtml index 0398f2a0..8d6d1688 100644 --- a/Index.xhtml +++ b/Index.xhtml @@ -177,7 +177,7 @@ mGlobal.TreeObjectInfoLoad =function (inElementId) { //Подгрузка массива спецификаций lSpecificationArray = mGlobal.GUIElement[inElementId].GUISelectorFull - var lHTMLList='
' + var lHTMLList='
' var lSpecificationArrayNew=[] for (i=0;i, -# +# "depth_start" - глубина, с которой начинается поиск (по умолчанию 1) +# "depth_end" - глубина, до которой ведется поиск (по умолчанию 1) +# "class_name" - наименование класса, который требуется искать +# "title" - наименование заголовка +# "rich_text" - наименование rich_text #} ] -def PywinautoExtElementGet (inSpecificationList,inElement=None): - lResult=None - lChildElement=None +def PywinautoExtElementsGet (inSpecificationList,inElement=None): + lResultList=[] + lChildrenList=[] #Получить родительский объект если на вход ничего не поступило if inElement is None: #сформировать спецификацию на получение элемента lRootElementSpecification=[inSpecificationList[0]] - lChildElement=GetControl(lRootElementSpecification) + lChildrenList.append(GetControl(lRootElementSpecification)) + if lChildrenList[0] is not None: + lChildrenList[0] = lChildrenList[0].wrapper_object() #Елемент на вход поступил - выполнить его анализ else: - #Поступил index + #Получить список элементов + lElementChildrenList=inElement.children() + #Поступил index - точное добавление if 'index' in inSpecificationList[0]: - lChildrenList=inElement.children() - if inSpecificationList[0]['index']1 and lChildElement is not None: + lChildrenList.append(lElementChildrenList[inSpecificationList[0]['ctrl_index']]) + else: + raise ValueError('Object has no children with index: ' + str(inSpecificationList[0]['ctrl_index'])) + #Если нет точного обозначения элемента + else: + lFlagGoCheck=True + #Учесть поле depth_start (если указано) + if 'depth_start' in inSpecificationList[0]: + if inSpecificationList[0]["depth_start"]>1: + lFlagGoCheck=False + #pdb.set_trace() + #Циклический обход по детям, на предмет соответствия всем условиям + for lChildrenItem in lElementChildrenList: + #Обработка глубины depth (рекурсивный вызов для всех детей с занижением индекса глубины) + #По умолчанию значение глубины 1 + if 'depth_end' in inSpecificationList[0]: + if inSpecificationList[0]['depth_end']>1: + #Подготовка новой версии спецификации + lChildrenItemNewSpecificationList=inSpecificationList.copy() + lChildrenItemNewSpecificationList[0]=lChildrenItemNewSpecificationList[0].copy() + lChildrenItemNewSpecificationList[0]["depth_end"]=lChildrenItemNewSpecificationList[0]["depth_end"]-1 + if 'depth_start' in lChildrenItemNewSpecificationList[0]: + lChildrenItemNewSpecificationList[0]["depth_start"]=lChildrenItemNewSpecificationList[0]["depth_start"]-1 + #pdb.set_trace() + #Циклический вызов для всех детей со скорректированной спецификацией + lResultList.extend(PywinautoExtElementsGet(lChildrenItemNewSpecificationList,lChildrenItem)) + #Фильтрация + if lFlagGoCheck: + lFlagAddChild=True + #Фильтрация по title + if 'title' in inSpecificationList[0]: + if lChildrenItem.element_info.name != inSpecificationList[0]["title"]: + lFlagAddChild=False + #Фильтрация по rich_text + if 'rich_text' in inSpecificationList[0]: + if lChildrenItem.element_info.rich_text != inSpecificationList[0]["rich_text"]: + lFlagAddChild=False + #Фильтрация по class_name + if 'class_name' in inSpecificationList[0]: + if lChildrenItem.element_info.class_name != inSpecificationList[0]["class_name"]: + lFlagAddChild=False + ##### + #Все проверки пройдены - флаг добавления + if lFlagAddChild: + lChildrenList.append(lChildrenItem) + #Выполнить рекурсивный вызов (уменьшение количества спецификаций), если спецификация больше одного элемента + if len(inSpecificationList)>1 and len(lChildrenList)>0 is not None: #Вызвать рекурсивно функцию получения следующего объекта, если в спецификации есть следующий объект - lResult=PywinautoExtElementGet(inSpecificationList[1:],lChildElement) + for lChildElement in lChildrenList: + lResultList.extend(PywinautoExtElementsGet(inSpecificationList[1:],lChildElement)) else: - lResult=lChildElement + lResultList.extend(lChildrenList) + return lResultList +#Получить элемент через расширенный движок поиска +#[ { +#"index":<Позиция элемента в родительском объекте>, +# +#} ] +def PywinautoExtElementGet (inSpecificationList,inElement=None): + lResult=None + #Получить родительский объект если на вход ничего не поступило + lResultList=PywinautoExtElementsGet(inSpecificationList,inElement) + if len(lResultList)>0: + lResult=lResultList[0] return lResult ################################ #Функция повторяющегося таймера @@ -432,13 +512,18 @@ def GUISearchRun(inSpecificationArray): ############################################################# #Поиск элементов ############################################################# -def GUISearchElementByRootXY(inRootElement,inX,inY): +#inHierarchyList: [{"index":<>,"element":<>}] +# +#Вернуть словарь [{"index":<>,"element":<>}] +#Последний элемент - искомый +def GUISearchElementByRootXY(inRootElement,inX,inY,inHierarchyList=[]): #Инициализация результирующего значения lResultElement = None lResultElementX1 = None lResultElementX2 = None lResultElementY1 = None lResultElementY2 = None + lResultHierarchyList=[{'index':None,'element':None}] #Получить координаты текущего объекта try: lRootElementRectX1=inRootElement.element_info.rectangle.left @@ -452,9 +537,21 @@ def GUISearchElementByRootXY(inRootElement,inX,inY): lResultElementX2 = lRootElementRectX2 lResultElementY1 = lRootElementRectY1 lResultElementY2 = lRootElementRectY2 + #Сформировать результирующий обьъект + lParentHierarchy = inHierarchyList + if len(lParentHierarchy)==0: + lParentHierarchy.append({"index":None,"element":lResultElement}) + else: + lParentHierarchy[-1]["element"] = lResultElement + lResultHierarchyList=lParentHierarchy #Получить список детей и добавить в карту + lChildIterator=0 for lChildElement in inRootElement.children(): - lChildFoundedElement = GUISearchElementByRootXY(lChildElement,inX,inY) + #Сформировать результирующий массив + lChildFoundedHierarchyList = lParentHierarchy.copy() + lChildFoundedHierarchyList.append({'index': lChildIterator}) + lChildFoundedHierarchyList = GUISearchElementByRootXY(lChildElement,inX,inY, lChildFoundedHierarchyList) + lChildFoundedElement = lChildFoundedHierarchyList[-1]["element"] #Установить обнаруженный элемент, если текущий результат пустой if lResultElement is None and lChildFoundedElement is not None: lResultElement = lChildFoundedElement @@ -462,6 +559,7 @@ def GUISearchElementByRootXY(inRootElement,inX,inY): lResultElementX2 = lResultElement.element_info.rectangle.right lResultElementY1 = lResultElement.element_info.rectangle.top lResultElementY2 = lResultElement.element_info.rectangle.bottom + lResultHierarchyList = lChildFoundedHierarchyList #Выполнить сверку lChildFoundedElement и lResultElement если оба имеются elif lResultElement is not None and lChildFoundedElement is not None: #Правила перезатирания карты, если имеется старый объект @@ -488,6 +586,7 @@ def GUISearchElementByRootXY(inRootElement,inX,inY): lResultElementX2 = lChildFoundedElementX2 lResultElementY1 = lChildFoundedElementY1 lResultElementY2 = lChildFoundedElementY2 + lResultHierarchyList = lChildFoundedHierarchyList #Проверка вхождения по типу 2 else: lResultElement = lChildFoundedElement @@ -495,9 +594,11 @@ def GUISearchElementByRootXY(inRootElement,inX,inY): lResultElementX2 = lChildFoundedElementX2 lResultElementY1 = lChildFoundedElementY1 lResultElementY2 = lChildFoundedElementY2 + lResultHierarchyList = lChildFoundedHierarchyList + lChildIterator=lChildIterator+1 except Exception as e: False == False - return lResultElement + return lResultHierarchyList #Техническая функция def GUISearchBitmapCreate (inElement,inBitmapDict={}): @@ -918,6 +1019,26 @@ def draw_outline_new(lWrapperObject,colour='green',thickness=2,fill=win32defines #Аналог подсвечивания + установка фокуса def draw_outline_new_focus(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS_NULL,rect=None): draw_outline_new(lWrapperObject,'green',2,win32defines.BS_NULL,None,True) + + +################ +###GeneralClipboardGet +################ +def GeneralClipboardGet(): + win32clipboard.OpenClipboard() + lResult = win32clipboard.GetClipboardData() + win32clipboard.CloseClipboard() + return lResult +################ +###GeneralClipboardSet +################ +def GeneralClipboardSet(inText): + win32clipboard.OpenClipboard() + win32clipboard.EmptyClipboard() + win32clipboard.SetClipboardText(inText) + win32clipboard.CloseClipboard() + + #run() lText = "Bitness:" + str(struct.calcsize("P") * 8) #for line in sys.stdin: @@ -941,7 +1062,7 @@ if not mFlagIsDebug: ProcessParentWriteObject(lJSONInput) except Exception as e: #Вывод ошибки в родительский поток - ProcessParentWriteObject({'Error':str(e), 'ArgObject':str(lJSONInputString)}) + ProcessParentWriteObject({'Error':str(e) + traceback.format_exc(), 'ArgObject':str(lJSONInputString)}) #ctypes.windll.user32.MessageBoxW(0, str(e), "Your title", 1) else: print('Debug mode is turned on!')