#GUISearchModeOnline #Customization #HelpLinks #DebugFix

dev-linux
Ivan Maslov 6 years ago
parent c12ed2cacc
commit 2066821eb8

@ -124,7 +124,7 @@
<i class="angle double right icon" '+lIconTestOnClick+'></i>\
<i class="angle double up icon" '+lIconUpOnClick+'></i>\
<div class="content">\
<div class="header" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>'+inItem.name+'</div>\
<div class="header" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>'+inItem.title+'</div>\
<div class="description" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>process_id:'+inItem.process_id+'; handle:'+inItem.handle+'; class_name: '+inItem.class_name+'; RECT:L'+inItem.rectangle.left+' T'+inItem.rectangle.top+' R'+inItem.rectangle.right+' B'+inItem.rectangle.bottom+'</div>\
'+lSubListHTML+'\
</div>\
@ -158,7 +158,7 @@
<i class="angle double right icon" '+lIconSelectOnClick+'></i>\
<i class="angle double right icon" '+lIconTestOnClick+'></i>\
<div class="content">\
<div class="header" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>'+lResponseJSON.outputObject[i].name+'</div>\
<div class="header" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>'+lResponseJSON.outputObject[i].title+'</div>\
<div class="description" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>process_id:'+lResponseJSON.outputObject[i].process_id+'; handle:'+lSubItemHandleId+'; class_name: '+lResponseJSON.outputObject[i].class_name+'; RECT:L'+lResponseJSON.outputObject[i].rectangle.left+' T'+lResponseJSON.outputObject[i].rectangle.top+' R'+lResponseJSON.outputObject[i].rectangle.right+' B'+lResponseJSON.outputObject[i].rectangle.bottom+'</div>\
</div>\
</div>'
@ -197,7 +197,26 @@
$(".rpa-hierarchy").html(lHTMLList)
$(".rpa-object-tree .item").css("background-color","");
$("#"+inElementId).css("background-color","RGB(128,128,128)");
$(".rpa-gui-selector")[0].value=(JSON.stringify(lSpecificationArray))
///Создать урезанную версию селектора
lTextAreaSpecificationArray=Array.from(lSpecificationArray);
for (var i = 0; i< lTextAreaSpecificationArray.length; i++) {
Object.assign(lTextAreaSpecificationArray[i],lTextAreaSpecificationArray[i]);
///Очистить ненужные ключи для выборки
delete lTextAreaSpecificationArray[i]['rich_text']
delete lTextAreaSpecificationArray[i]['process_id']
delete lTextAreaSpecificationArray[i]['rectangle']
delete lTextAreaSpecificationArray[i]['control_id']
delete lTextAreaSpecificationArray[i]['process']
delete lTextAreaSpecificationArray[i]['name']
delete lTextAreaSpecificationArray[i]['handle']
delete lTextAreaSpecificationArray[i]['control_type']
delete lTextAreaSpecificationArray[i]['runtime_id']
if (i!=0) {
delete lTextAreaSpecificationArray[i]['title']
delete lTextAreaSpecificationArray[i]['class_name']
}
}
$(".rpa-gui-selector")[0].value=(JSON.stringify(lTextAreaSpecificationArray))
}
mGlobal.ElementPropertyListLoad=function(inElementId) {
//Подгрузка массива спецификаций
@ -270,7 +289,7 @@
$.ajax({
type: "POST",
url: 'GUIAction',
data: '{"functionName":"ElementDrawOutlineNew","argsArray":['+lSpecificationArray+']}',
data: '{"functionName":"ElementDrawOutlineNewFocus","argsArray":['+lSpecificationArray+']}',
success:
function(lData,l2,l3)
{
@ -463,7 +482,7 @@
<i class="angle double up icon" '+lIconUpOnClick+'></i>\
<div class="content">\
<div class="description" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>\
<b>'+lResponseJSON.outputObject[i].name+'</b>\
<b>'+lResponseJSON.outputObject[i].title+'</b>\
process_id:'+lResponseJSON.outputObject[i].process_id+'; handle:'+lSubItemHandleId+'; class_name: '+lResponseJSON.outputObject[i].class_name+'; RECT:L'+lResponseJSON.outputObject[i].rectangle.left+' T'+lResponseJSON.outputObject[i].rectangle.top+' R'+lResponseJSON.outputObject[i].rectangle.right+' B'+lResponseJSON.outputObject[i].rectangle.bottom+'</div>\
</div>\
</div>'
@ -543,9 +562,9 @@
<div class="two wide column">
<h1 class="ui header inverted">OpenRPA</h1>
</div>
<div class="thirteen wide column">
<div class="twelve wide column">
</div>
<div class="one wide column">
<div class="two wide column">
<h5>by UnicodeLabs</h5>
</div>
@ -587,7 +606,7 @@
<div class="row">
<div class="eight wide column">
<div class="ui tiny header">Edit GUI selector</div>
<textarea style="width:100%" class="rpa-gui-selector" rows="6" cols="60"></textarea>
<textarea style="width:100%; font-size:12pt" class="rpa-gui-selector" rows="6" cols="60"></textarea>
<button class="large ui blue button rpa-action-highlight" onclick="mGlobal.ElementHighlightNewGUISelectorString($('.rpa-gui-selector')[0].value);">Highlight element</button>
</div>
<div class="eight wide column">
@ -639,35 +658,35 @@
<div class="ui center aligned container">
<div class="ui stackable inverted divided grid">
<div class="three wide column">
<h4 class="ui inverted header">Group 1</h4>
<h4 class="ui inverted header">Pywinauto</h4>
<div class="ui inverted link list">
<a href="#" class="item">Link One</a>
<a href="#" class="item">Link Two</a>
<a href="#" class="item">Link Three</a>
<a href="#" class="item">Link Four</a>
<a href="https://pywinauto.readthedocs.io/en/latest/code/pywinauto.findwindows.html" class="item" target="_blank">Specification manual</a>
<a href="https://pywinauto.readthedocs.io/en/latest/code/code.html#main-user-modules" class="item" target="_blank">Classes manual</a>
<a href="https://pywinauto.readthedocs.io/en/latest/code/code.html#main-user-modules" class="item" target="_blank">How to use manual</a>
<a href="https://pywinauto.readthedocs.io/en/latest/code/pywinauto.base_wrapper.html" class="item" target="_blank">Base wrapper manual</a>
</div>
</div>
<div class="three wide column">
<h4 class="ui inverted header">Group 2</h4>
<h4 class="ui inverted header">Semantic UI</h4>
<div class="ui inverted link list">
<a href="#" class="item">Link One</a>
<a href="#" class="item">Link Two</a>
<a href="#" class="item">Link Three</a>
<a href="#" class="item">Link Four</a>
<a href="https://semantic-ui.com/usage/theming.html" class="item" target="_blank">Color manual</a>
<a href="https://semantic-ui.com/elements/input.html" class="item" target="_blank">Input manual</a>
<a href="https://semantic-ui.com/elements/icon.html" class="item" target="_blank">Icon list</a>
<a href="https://semantic-ui.com/elements/button.html" class="item" target="_blank">Button manual</a>
</div>
</div>
<div class="three wide column">
<h4 class="ui inverted header">Group 3</h4>
<h4 class="ui inverted header">GitLab</h4>
<div class="ui inverted link list">
<a href="#" class="item">Link One</a>
<a href="#" class="item">Link Two</a>
<a href="#" class="item">Link Three</a>
<a href="#" class="item">Link Four</a>
<a href="https://gitlab.com/UnicodeLabs/OpenRPA" class="item" target="_blank">OpenRPA repository</a>
<a href="https://gitlab.com/UnicodeLabs" class="item" target="_blank">UnicodeLabs</a>
<a href="#" class="item">Link -</a>
<a href="#" class="item">Link -</a>
</div>
</div>
<div class="seven wide column">
<h4 class="ui inverted header">OpenRPA</h4>
<p>Open source Robotic Process Automation software by the Unicode Labs (Ivan Maslov). Under the MIT license.</p>
<p>Open source Robotic Process Automation software by the Unicode Labs (Created by Ivan Maslov). Under the MIT license.</p>
</div>
</div>
<div class="ui inverted section divider"></div>

@ -16,6 +16,8 @@ from threading import Timer
mFlagIsDebug=False
mPywinautoApplication=pywinauto.Application(backend="win32")
mPywinautoActiveBackend="win32"
#mPywinautoActiveBackend="uia"
#mPywinautoApplication=pywinauto.Application(backend="uia")
#####
@ -29,57 +31,85 @@ mPywinautoApplication=pywinauto.Application(backend="win32")
#inElementSpecificationList = [ [{lvl_0},{lvl_1},{lvl_2}],... ]
#result = pywinauto element wrapper instance or None
def AutomationSearchMouseElement(inElementSpecification):
lBitmap={}
def AutomationSearchMouseElement(inElementSpecification,inFlagIsSearchOnline=True):
lGUISearchElementSelected=None
#Создать карту пикселей и элементов
lBitmap=GUISearchBitmapCreate(GetControl(inElementSpecification),lBitmap)
#Выдать сообщение, что поиск готов к использованию
#print("GUISearch: Ready for search!")
###########
#Версия с задержкой (без таймеров, событий в отдельных потоках)
###########
#Сбросить нажатие Ctrl, если оно было
bool(win32api.GetAsyncKeyState(17))
#Настройка - частота обновления подсвечивания
lTimeSleepSeconds=0.7
lFlagLoop = True
while lFlagLoop:
#Проверить, нажата ли клавиша Ctrl (код 17)
lFlagKeyPressedCtrl=bool(win32api.GetAsyncKeyState(17))
#Подсветить объект, если мышка наведена над тем объектом, который не подсвечивался в прошлый раз
if not lFlagKeyPressedCtrl:
#Получить координаты мыши
(lX,lY) = win32api.GetCursorPos()
#Подсветить объект, если мышь над ним
if (lX,lY) in lBitmap:
if lGUISearchElementSelected != lBitmap[lX,lY]:
lGUISearchElementSelected = lBitmap[lX,lY]
#Классическая функция отрисовки (из pywinauto)
#lBitmap[lX,lY].draw_outline()
lTimeSleepSeconds=0.4
#Ветка поиска в режиме реального времени
if inFlagIsSearchOnline:
#Сбросить нажатие Ctrl, если оно было
bool(win32api.GetAsyncKeyState(17))
lFlagLoop = True
while lFlagLoop:
#Проверить, нажата ли клавиша Ctrl (код 17)
lFlagKeyPressedCtrl=bool(win32api.GetAsyncKeyState(17))
#Подсветить объект, если мышка наведена над тем объектом, который не подсвечивался в прошлый раз
if not lFlagKeyPressedCtrl:
#Получить координаты мыши
(lX,lY) = win32api.GetCursorPos()
lElementFounded={}
#Создать карту пикселей и элементов
#####Внимание! Функция GUISearchElementByRootXY не написана
lElementFounded=GUISearchElementByRootXY(GetControl(inElementSpecification),lX,lY)
#Подсветить объект, если он мышь раньше стояла на другом объекте
if lGUISearchElementSelected != lElementFounded:
lGUISearchElementSelected = lElementFounded
#Доработанная функция отрисовки
draw_outline_new(lBitmap[lX,lY])
if lElementFounded is not None:
draw_outline_new(lElementFounded)
else:
lGUISearchElementSelected = None
else:
#Была нажата клавиша Ctrl - выйти из цикла
lFlagLoop=False;
#Заснуть до следующего цикла
time.sleep(lTimeSleepSeconds)
#Была нажата клавиша Ctrl - выйти из цикла
lFlagLoop=False;
#Заснуть до следующего цикла
time.sleep(lTimeSleepSeconds)
#Ветка поиска по заранее созданной карте
else:
lBitmap={}
#Создать карту пикселей и элементов
lBitmap=GUISearchBitmapCreate(GetControl(inElementSpecification),lBitmap)
#Выдать сообщение, что поиск готов к использованию
#print("GUISearch: Ready for search!")
###########
#Версия с задержкой (без таймеров, событий в отдельных потоках)
###########
#Сбросить нажатие Ctrl, если оно было
bool(win32api.GetAsyncKeyState(17))
lFlagLoop = True
while lFlagLoop:
#Проверить, нажата ли клавиша Ctrl (код 17)
lFlagKeyPressedCtrl=bool(win32api.GetAsyncKeyState(17))
#Подсветить объект, если мышка наведена над тем объектом, который не подсвечивался в прошлый раз
if not lFlagKeyPressedCtrl:
#Получить координаты мыши
(lX,lY) = win32api.GetCursorPos()
#Подсветить объект, если мышь над ним
if (lX,lY) in lBitmap:
if lGUISearchElementSelected != lBitmap[lX,lY]:
lGUISearchElementSelected = lBitmap[lX,lY]
#Классическая функция отрисовки (из pywinauto)
#lBitmap[lX,lY].draw_outline()
#Доработанная функция отрисовки
draw_outline_new(lBitmap[lX,lY])
else:
lGUISearchElementSelected = None
else:
#Была нажата клавиша Ctrl - выйти из цикла
lFlagLoop=False;
#Заснуть до следующего цикла
time.sleep(lTimeSleepSeconds)
#Вернуть результат поиска
return lGUISearchElementSelected
def AutomationSearchMouseElementHierarchy(inElementSpecification):
def AutomationSearchMouseElementHierarchy(inElementSpecification,inFlagIsSearchOnline=True):
lItemInfo = None
#Запустить функцию поиска элемента по мыши
lElement = AutomationSearchMouseElement(inElementSpecification)
lElement = AutomationSearchMouseElement(inElementSpecification,inFlagIsSearchOnline)
#Detect backend of the elements
lFlagIsBackendWin32 = True
if lElement.backend.name == 'uia':
lFlagIsBackendWin32 = False
#Если объект имеется (не None), то выполнить построение иерархии
if lElement is not None:
if lElement.backend.name == 'uia':
lFlagIsBackendWin32 = False
#Циклическое создание дерева
while lElement is not None:
#Продолжать построение иерархии во всех случаях кроме бэк uia & parent() is None
@ -197,9 +227,9 @@ def ProcessParentWriteString(lString):
#print(b"Result: "+lByteString)
#lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a'
#lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0"
lt=open("logSendByteStringWithoutN.log","wb")
lt.write(lByteString)
lt.close()
#lt=open("logSendByteStringWithoutN.log","wb")
#lt.write(lByteString)
#lt.close()
############################
sys.stdout.buffer.write(lByteString+bytes("\n","utf-8"))
sys.stdout.flush();
@ -226,7 +256,7 @@ def GetControl(inControlSpecificationArray):
lResultList=[];
if len(inControlSpecificationArray) > 0:
#Выполнить подключение к объекту
lRPAApplication = pywinauto.Application()
lRPAApplication = pywinauto.Application(backend=mPywinautoActiveBackend)
#Проверка разрядности
lRPAApplication.connect(**inControlSpecificationArray[0])
#lTempObject=lRPAApplication.window(**inControlSpecificationArray[0])
@ -243,7 +273,17 @@ def GetControl(inControlSpecificationArray):
def ElementActionGetList (inControlSpecificationArray):
#Получить объект
lObject=GetControl(inControlSpecificationArray)
return dir(lObject.wrapper_object())
lActionList=dir(lObject.wrapper_object())
lResult=dir(lObject.wrapper_object())
#Выполнить чистку списка от неактуальных методов
for lActionItem in lActionList:
#Удалить те, которые начинаются на _
if lActionItem[0]=='_':
lResult.remove(lActionItem)
#Удалить те, которые начинаются с символа верхнего регистра
if lActionItem[0].isupper():
lResult.remove(lActionItem)
return lResult
#Выполнить действие над элементом
def ElementRunAction(inControlSpecificationArray,inActionName,inArgumentList=[],inkwArgumentObject={}):
#Определить объект
@ -308,7 +348,7 @@ def GUISearchRun(inSpecificationArray):
#Создать карту пикселей и элементов
lBitmap=GUISearchBitmapCreate(GetControl(inSpecificationArray),lBitmap)
#Выдать сообщение, что поиск готов к использованию
print("GUISearch: Ready for search!")
#print("GUISearch: Ready for search!")
#mBitmap=lBitmap
# Collect events until released
#Версия с Events (занимает поток, чтобы использовать общие переменные)
@ -351,6 +391,78 @@ def GUISearchRun(inSpecificationArray):
time.sleep(lTimeSleepSeconds)
#Вернуть результат поиска
return lGUISearchElementSelected
#############################################################
#Поиск элементов
#############################################################
def GUISearchElementByRootXY(inRootElement,inX,inY):
#Инициализация результирующего значения
lResultElement = None
lResultElementX1 = None
lResultElementX2 = None
lResultElementY1 = None
lResultElementY2 = None
#Получить координаты текущего объекта
try:
lRootElementRectX1=inRootElement.element_info.rectangle.left
lRootElementRectX2=inRootElement.element_info.rectangle.right
lRootElementRectY1=inRootElement.element_info.rectangle.top
lRootElementRectY2=inRootElement.element_info.rectangle.bottom
#Добавить объект в результирующий, если координаты попадают в него
if inX>=lRootElementRectX1 and inX<=lRootElementRectX2 and inY>=lRootElementRectY1 and inY<=lRootElementRectY2:
lResultElement = inRootElement
lResultElementX1 = lRootElementRectX1
lResultElementX2 = lRootElementRectX2
lResultElementY1 = lRootElementRectY1
lResultElementY2 = lRootElementRectY2
#Получить список детей и добавить в карту
for lChildElement in inRootElement.children():
lChildFoundedElement = GUISearchElementByRootXY(lChildElement,inX,inY)
#Установить обнаруженный элемент, если текущий результат пустой
if lResultElement is None and lChildFoundedElement is not None:
lResultElement = lChildFoundedElement
lResultElementX1 = lResultElement.element_info.rectangle.left
lResultElementX2 = lResultElement.element_info.rectangle.right
lResultElementY1 = lResultElement.element_info.rectangle.top
lResultElementY2 = lResultElement.element_info.rectangle.bottom
#Выполнить сверку lChildFoundedElement и lResultElement если оба имеются
elif lResultElement is not None and lChildFoundedElement is not None:
#Правила перезатирания карты, если имеется старый объект
#[Накладываемый объект] - НО - ElementNew
#[Имеющийся объект] - ИО - ElementOld
#3 типа вхождения объектов
#тип 1 - [имеющийся объект] полностью входит в [накладываемый объект] (ИО X1 Y1 >= НО X1 Y1; ИО X2 Y2 <= НО X2 Y2) - не вносить НО в bitmap в эти диапазоны
#тип 2 - [имеющийся объект] полностью выходит за пределы [накладываемого объекта] (ИО X1 Y1 < НО X1 Y1; ИО X2 Y2 > НО X2 Y2) - вносить НО в bitmap
#тип 3 - [имеющийся объект] частично входит в [накладываемый объект] (все остальные случаи)- вносить НО в bitmap
#Получить координаты ИО
lChildFoundedElementInfo = lChildFoundedElement.element_info
#lElementNew = inElement
lChildFoundedElementX1 = lChildFoundedElementInfo.rectangle.left
lChildFoundedElementX2 = lChildFoundedElementInfo.rectangle.right
lChildFoundedElementY1 = lChildFoundedElementInfo.rectangle.top
lChildFoundedElementY2 = lChildFoundedElementInfo.rectangle.bottom
#Проверка вхождения по типу 1
if (lResultElementX1>=lChildFoundedElementX1) and (lResultElementY1>=lChildFoundedElementY1) and (lResultElementX2<=lChildFoundedElementX2) and (lResultElementY2<=lChildFoundedElementY2):
False == True
#Проверка вхождения по типу 3
elif (lResultElementX1<lChildFoundedElementX1) and (lResultElementY1<lChildFoundedElementY1) and (lResultElementX2>lChildFoundedElementX2) and (lResultElementY2>lChildFoundedElementY2):
lResultElement = lChildFoundedElement
lResultElementX1 = lChildFoundedElementX1
lResultElementX2 = lChildFoundedElementX2
lResultElementY1 = lChildFoundedElementY1
lResultElementY2 = lChildFoundedElementY2
#Проверка вхождения по типу 2
else:
lResultElement = lChildFoundedElement
lResultElementX1 = lChildFoundedElementX1
lResultElementX2 = lChildFoundedElementX2
lResultElementY1 = lChildFoundedElementY1
lResultElementY2 = lChildFoundedElementY2
except Exception as e:
False == False
return lResultElement
#Техническая функция
def GUISearchBitmapCreate (inElement,inBitmapDict={}):
#Добавить в карту информацию о текущем объекте
inBitmapDict=GUISearchBitmapElementFill(inElement,inBitmapDict)
@ -362,6 +474,7 @@ def GUISearchBitmapCreate (inElement,inBitmapDict={}):
#GUISearchBitmapElementFill
def GUISearchBitmapElementFill (inElement,inBitmapDict):
lElementInfo=inElement.element_info
#pdb.set_trace()
#Получить параметры прямоугольника
lElementRectX1 = 0
lElementRectX2 = 0
@ -373,22 +486,64 @@ def GUISearchBitmapElementFill (inElement,inBitmapDict):
lElementRectX2=lElementInfo.rectangle.right
lElementRectY1=lElementInfo.rectangle.top
lElementRectY2=lElementInfo.rectangle.bottom
#Выполнить установку элемента, если прямоугольник получить удалось
if lFlagHasRect:
lX=lElementRectX1
#Циклический обход по оси X
while lX<=lElementRectX2:
lY=lElementRectY1
#Циклический обход по Оси Y
while lY<=lElementRectY2:
######################
#Если объект в карте есть
if (lX,lY) in inBitmapDict:
if inBitmapDict[lX,lY] is not None:
#Правила перезатирания карты, если имеется старый объект
#[Накладываемый объект] - НО - ElementNew
#[Имеющийся объект] - ИО - ElementOld
#3 типа вхождения объектов
#тип 1 - [имеющийся объект] полностью входит в [накладываемый объект] (ИО X1 Y1 >= НО X1 Y1; ИО X2 Y2 <= НО X2 Y2) - не вносить НО в bitmap в эти диапазоны
#тип 2 - [имеющийся объект] полностью выходит за пределы [накладываемого объекта] (ИО X1 Y1 < НО X1 Y1; ИО X2 Y2 > НО X2 Y2) - вносить НО в bitmap
#тип 3 - [имеющийся объект] частично входит в [накладываемый объект] (все остальные случаи)- вносить НО в bitmap
#Получить координаты ИО
lElementOldInfo = inBitmapDict[lX,lY].element_info
#lElementNew = inElement
lElementOldX1 = lElementOldInfo.rectangle.left
lElementOldX2 = lElementOldInfo.rectangle.right
lElementOldY1 = lElementOldInfo.rectangle.top
lElementOldY2 = lElementOldInfo.rectangle.bottom
#Проверка вхождения по типу 1
if (lElementOldX1>=lElementRectX1) and (lElementOldY1>=lElementRectY1) and (lElementOldX2<=lElementRectX2) and (lElementOldY2<=lElementRectY2):
#Выполнить корректировку каретки по lY, чтобы не проходить по всем пикселям в рамках этой линии
lY = lElementOldY2 + 1
#Проверка вхождения по типу 3
elif (lElementOldX1<lElementRectX1) and (lElementOldY1<lElementRectY1) and (lElementOldX2>lElementRectX2) and (lElementOldY2>lElementRectY2):
#Установка элемента по адресу [<x>,<y>]
inBitmapDict[lX,lY]=inElement
#Инкремент y
lY=lY+1
#Проверка вхождения по типу 2
else:
#Установка элемента по адресу [<x>,<y>]
inBitmapDict[lX,lY]=inElement
#Инкремент y
lY=lY+1
#Если объекта в карте нет
else:
#Установка элемента по адресу [<x>,<y>]
inBitmapDict[lX,lY]=inElement
#Инкремент y
lY=lY+1
else:
#Установка элемента по адресу [<x>,<y>]
inBitmapDict[lX,lY]=inElement
#Инкремент y
lY=lY+1
######################
#Инкремент X
lX=lX+1
except Exception as e:
lFlagHasRect = False
#Выполнить установку элемента, если прямоугольник получить удалось
if lFlagHasRect:
lX=lElementRectX1
#Циклический обход по оси X
while lX<=lElementRectX2:
lY=lElementRectY1
#Циклический обход по Оси Y
while lY<=lElementRectY2:
#Установка элемента по адресу [<x>,<y>]
inBitmapDict[lX,lY]=inElement
#Инкремент y
lY=lY+1
#Инкремент X
lX=lX+1
return inBitmapDict
#debug
def ElementGetChildElementList(inControlSpecificationArray=[]):
@ -593,10 +748,10 @@ def JSONNormalizeDictList(inDictList):
#Получить объект из атрибутов, которые удалось прочитать
def ElementInfoExportObject(inElementInfo):
#Подготовить выходную структуру данных
lResult = {"name":None,"rich_text":None,"process_id":None,"process":None,"handle":None,"class_name":None,"control_type":None,"control_id":None,"rectangle":{"left":None,"top":None,"right":None,"bottom":None}, 'runtime_id':None}
lResult = {"title":None,"rich_text":None,"process_id":None,"process":None,"handle":None,"class_name":None,"control_type":None,"control_id":None,"rectangle":{"left":None,"top":None,"right":None,"bottom":None}, 'runtime_id':None}
#Проверка name
try:
lResult['name']=inElementInfo.name
lResult['title']=inElementInfo.name
except Exception as e:
True == False
#Проверка rich_text
@ -670,52 +825,62 @@ def GetRootElementList():
def ElementDrawOutlineNew(inSpecificationArray):
draw_outline_new(GetControl(inSpecificationArray))
return
def draw_outline_new(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS_NULL,rect=None):
"""
Draw an outline around the window.
* **colour** can be either an integer or one of 'red', 'green', 'blue'
(default 'green')
* **thickness** thickness of rectangle (default 2)
* **fill** how to fill in the rectangle (default BS_NULL)
* **rect** the coordinates of the rectangle to draw (defaults to
the rectangle of the control)
"""
#pdb.set_trace()
# don't draw if dialog is not visible
#if not lWrapperObject.is_visible():
# return
colours = {
"green": 0x00ff00,
"blue": 0xff0000,
"red": 0x0000ff,
}
# if it's a known colour
if colour in colours:
colour = colours[colour]
if rect is None:
rect = lWrapperObject.rectangle()
# create the pen(outline)
pen_handle = win32functions.CreatePen(
win32defines.PS_SOLID, thickness, colour)
# create the brush (inside)
brush = win32structures.LOGBRUSH()
brush.lbStyle = fill
brush.lbHatch = win32defines.HS_DIAGCROSS
brush_handle = win32functions.CreateBrushIndirect(ctypes.byref(brush))
# get the Device Context
dc = win32functions.CreateDC("DISPLAY", None, None, None )
# push our objects into it
win32functions.SelectObject(dc, brush_handle)
win32functions.SelectObject(dc, pen_handle)
# draw the rectangle to the DC
win32functions.Rectangle(
dc, rect.left, rect.top, rect.right, rect.bottom)
# Delete the brush and pen we created
win32functions.DeleteObject(brush_handle)
win32functions.DeleteObject(pen_handle)
# delete the Display context that we created
win32functions.DeleteDC(dc)
def ElementDrawOutlineNewFocus(inSpecificationArray):
draw_outline_new_focus(GetControl(inSpecificationArray))
return
def draw_outline_new(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS_NULL,rect=None,inFlagSetFocus=False):
if lWrapperObject is not None:
"""
Draw an outline around the window.
* **colour** can be either an integer or one of 'red', 'green', 'blue'
(default 'green')
* **thickness** thickness of rectangle (default 2)
* **fill** how to fill in the rectangle (default BS_NULL)
* **rect** the coordinates of the rectangle to draw (defaults to
the rectangle of the control)
"""
if inFlagSetFocus:
#Установить фокус на объект, чтобы было видно выделение
lWrapperObject.set_focus()
#pdb.set_trace()
# don't draw if dialog is not visible
#if not lWrapperObject.is_visible():
# return
colours = {
"green": 0x00ff00,
"blue": 0xff0000,
"red": 0x0000ff,
}
# if it's a known colour
if colour in colours:
colour = colours[colour]
if rect is None:
rect = lWrapperObject.rectangle()
# create the pen(outline)
pen_handle = win32functions.CreatePen(
win32defines.PS_SOLID, thickness, colour)
# create the brush (inside)
brush = win32structures.LOGBRUSH()
brush.lbStyle = fill
brush.lbHatch = win32defines.HS_DIAGCROSS
brush_handle = win32functions.CreateBrushIndirect(ctypes.byref(brush))
# get the Device Context
dc = win32functions.CreateDC("DISPLAY", None, None, None )
# push our objects into it
win32functions.SelectObject(dc, brush_handle)
win32functions.SelectObject(dc, pen_handle)
# draw the rectangle to the DC
win32functions.Rectangle(
dc, rect.left, rect.top, rect.right, rect.bottom)
# Delete the brush and pen we created
win32functions.DeleteObject(brush_handle)
win32functions.DeleteObject(pen_handle)
# delete the Display context that we created
win32functions.DeleteDC(dc)
#Аналог подсвечивания + установка фокуса
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)
#run()
lText = "Bitness:" + str(struct.calcsize("P") * 8)
#for line in sys.stdin:

Loading…
Cancel
Save