#NewSearchEngine(depth_start,depth_end,class_name,title,rich_text) #GeneralClipboardSet/Get #MouseVisualSearchFix

dev-linux
Ivan Maslov 5 years ago
parent 6c5b5abd03
commit 81158f10d4

@ -177,7 +177,7 @@
mGlobal.TreeObjectInfoLoad =function (inElementId) {
//Подгрузка массива спецификаций
lSpecificationArray = mGlobal.GUIElement[inElementId].GUISelectorFull
var lHTMLList='<div class="ui relaxed divided list">'
var lHTMLList='<div class="ui relaxed divided list" style="height:350px;overflow:scroll;">'
var lSpecificationArrayNew=[]
for (i=0;i<lSpecificationArray.length;i++) {
lSpecificationArrayNew.push(lSpecificationArray[i])

@ -10,7 +10,9 @@ import os
import select
import zlib
import win32api
import win32clipboard
import time
import traceback
from threading import Timer
mFlagIsDebug=False
@ -35,6 +37,7 @@ def AutomationSearchMouseElement(inElementSpecification,inFlagIsSearchOnline=Tru
lGUISearchElementSelected=None
#Настройка - частота обновления подсвечивания
lTimeSleepSeconds=0.4
lElementFoundedList=[]
#Ветка поиска в режиме реального времени
if inFlagIsSearchOnline:
#Сбросить нажатие Ctrl, если оно было
@ -50,7 +53,9 @@ def AutomationSearchMouseElement(inElementSpecification,inFlagIsSearchOnline=Tru
lElementFounded={}
#Создать карту пикселей и элементов
#####Внимание! Функция GUISearchElementByRootXY не написана
lElementFounded=GUISearchElementByRootXY(PywinautoExtElementGet(inElementSpecification),lX,lY)
lElementFoundedList=GUISearchElementByRootXY(PywinautoExtElementGet(inElementSpecification),lX,lY)
#print(lElementFoundedList)
lElementFounded=lElementFoundedList[-1]["element"]
#Подсветить объект, если он мышь раньше стояла на другом объекте
if lGUISearchElementSelected != lElementFounded:
lGUISearchElementSelected = lElementFounded
@ -64,6 +69,9 @@ def AutomationSearchMouseElement(inElementSpecification,inFlagIsSearchOnline=Tru
time.sleep(lTimeSleepSeconds)
#Ветка поиска по заранее созданной карте
else:
###################################
#Внимание Старая ветка (неправильный результат)
###################################
lBitmap={}
#Создать карту пикселей и элементов
lBitmap=GUISearchBitmapCreate(PywinautoExtElementGet(inElementSpecification),lBitmap)
@ -98,35 +106,42 @@ def AutomationSearchMouseElement(inElementSpecification,inFlagIsSearchOnline=Tru
#Заснуть до следующего цикла
time.sleep(lTimeSleepSeconds)
#Вернуть результат поиска
return lGUISearchElementSelected
return lElementFoundedList
def AutomationSearchMouseElementHierarchy(inElementSpecification,inFlagIsSearchOnline=True):
lItemInfo = None
lItemInfo = []
#Запустить функцию поиска элемента по мыши
lElement = AutomationSearchMouseElement(inElementSpecification,inFlagIsSearchOnline)
lElementList = AutomationSearchMouseElement(inElementSpecification,inFlagIsSearchOnline)
lElement = lElementList[-1]['element']
#Detect backend of the elements
lFlagIsBackendWin32 = True
#Если объект имеется (не None), то выполнить построение иерархии
#pdb.set_trace()
if lElement is not None:
if lElement.backend.name == 'uia':
lFlagIsBackendWin32 = False
#Циклическое создание дерева
while lElement is not None:
#while lElement is not None:
lListIterator=0
lItemInfo2=lItemInfo
for lListItem in lElementList:
lElement = lListItem["element"]
#Продолжать построение иерархии во всех случаях кроме бэк uia & parent() is None
if not lFlagIsBackendWin32 and lElement.parent() is None:
lElement = None
else:
#Получить информацию про объект
lItemInfo2 = ElementInfoExportObject(lElement.element_info)
#Дообогатить информацией об индексе ребенка в родительском объекте
lItemInfo2['ctrl_index']=PywinautoExtElementCtrlIndexGet(lElement)
#Оборачиваем потомка в массив, потому что у родителя по структуре интерфейса может быть больше одного наследников
lItemInfo2['SpecificationChild']=[lItemInfo]
lItemInfo=lItemInfo2
#Переход на родительский объект
lElement = lElement.parent()
#if not lFlagIsBackendWin32 and lElement.parent() is None:
# lElement = None
#else:
#Получить информацию про объект
lItemInfo2.append(ElementInfoExportObject(lElement.element_info))
#Дообогатить информацией об индексе ребенка в родительском объекте
lItemInfo2[-1]['ctrl_index']=lListItem["index"]
#Оборачиваем потомка в массив, потому что у родителя по структуре интерфейса может быть больше одного наследников
lItemInfo2[-1]['SpecificationChild']=[]
lItemInfo2=lItemInfo2[-1]['SpecificationChild']
#Переход на родительский объект
#lElement = lElement.parent()
lListIterator=lListIterator+1
#Вернуть результат
return [lItemInfo]
return lItemInfo
#return [1,2,3,4,5,3]
@ -161,39 +176,104 @@ def PywinautoExtElementCtrlIndexGet(inElement):
lFlagFind=False
#Вернуть результат
return lResult
#Получить элемент через расширенный движок поиска
#Получить список элементов, который удовлетворяет условиям через расширенный движок поиска
#[ {
#"index":<Позиция элемента в родительском объекте>,
#
# "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']<len(lChildrenList):
#Получить дочерний элемент
lChildElement=lChildrenList[inSpecificationList[0]['index']]
#Поступил ctrl_index
if inSpecificationList[0]['index']<len(lElementChildrenList):
#Получить дочерний элемент - точное добавление
lChildrenList.append(lElementChildrenList[inSpecificationList[0]['index']])
else:
raise ValueError('Object has no children with index: ' + str(inSpecificationList[0]['index']))
#Поступил ctrl_index - точное добавление
elif 'ctrl_index' in inSpecificationList[0]:
lChildrenList=inElement.children()
if inSpecificationList[0]['ctrl_index']<len(lChildrenList):
if inSpecificationList[0]['ctrl_index']<len(lElementChildrenList):
#Получить дочерний элемент
lChildElement=lChildrenList[inSpecificationList[0]['ctrl_index']]
#Выполнить рекурсивный вызов, если спецификация больше одного элемента
if len(inSpecificationList)>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!')

Loading…
Cancel
Save