@ -16,6 +16,8 @@ from threading import Timer
mFlagIsDebug = False
mFlagIsDebug = False
mPywinautoApplication = pywinauto . Application ( backend = " win32 " )
mPywinautoApplication = pywinauto . Application ( backend = " win32 " )
mPywinautoActiveBackend = " win32 "
#mPywinautoActiveBackend="uia"
#mPywinautoApplication=pywinauto.Application(backend="uia")
#mPywinautoApplication=pywinauto.Application(backend="uia")
#####
#####
@ -29,57 +31,85 @@ mPywinautoApplication=pywinauto.Application(backend="win32")
#inElementSpecificationList = [ [{lvl_0},{lvl_1},{lvl_2}],... ]
#inElementSpecificationList = [ [{lvl_0},{lvl_1},{lvl_2}],... ]
#result = pywinauto element wrapper instance or None
#result = pywinauto element wrapper instance or None
def AutomationSearchMouseElement ( inElementSpecification ) :
def AutomationSearchMouseElement ( inElementSpecification , inFlagIsSearchOnline = True ) :
lBitmap = { }
lGUISearchElementSelected = None
lGUISearchElementSelected = None
#Создать карту пикселей и элементов
lBitmap = GUISearchBitmapCreate ( GetControl ( inElementSpecification ) , lBitmap )
#Выдать сообщение, что поиск готов к использованию
#print("GUISearch: Ready for search!")
###########
#Версия с задержкой (без таймеров, событий в отдельных потоках)
###########
#Сбросить нажатие Ctrl, если оно было
bool ( win32api . GetAsyncKeyState ( 17 ) )
#Настройка - частота обновления подсвечивания
#Настройка - частота обновления подсвечивания
lTimeSleepSeconds = 0.7
lTimeSleepSeconds = 0.4
#Ветка поиска в режиме реального времени
lFlagLoop = True
if inFlagIsSearchOnline :
while lFlagLoop :
#Сбросить нажатие Ctrl, если оно было
#Проверить, нажата ли клавиша Ctrl (код 17)
bool ( win32api . GetAsyncKeyState ( 17 ) )
lFlagKeyPressedCtrl = bool ( win32api . GetAsyncKeyState ( 17 ) )
lFlagLoop = True
#Подсветить объект, если мышка наведена над тем объектом, который не подсвечивался в прошлый раз
while lFlagLoop :
if not lFlagKeyPressedCtrl :
#Проверить, нажата ли клавиша Ctrl (код 17)
#Получить координаты мыши
lFlagKeyPressedCtrl = bool ( win32api . GetAsyncKeyState ( 17 ) )
( lX , lY ) = win32api . GetCursorPos ( )
#Подсветить объект, если мышка наведена над тем объектом, который не подсвечивался в прошлый раз
#Подсветить объект, если мышь над ним
if not lFlagKeyPressedCtrl :
if ( lX , lY ) in lBitmap :
#Получить координаты мыши
if lGUISearchElementSelected != lBitmap [ lX , lY ] :
( lX , lY ) = win32api . GetCursorPos ( )
lGUISearchElementSelected = lBitmap [ lX , lY ]
lElementFounded = { }
#Классическая функция отрисовки (из pywinauto)
#Создать карту пикселей и элементов
#lBitmap[lX,lY].draw_outline()
#####Внимание! Функция 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 :
else :
lGUISearchElementSelected = None
#Была нажата клавиша Ctrl - выйти из цикла
else :
lFlagLoop = False ;
#Была нажата клавиша Ctrl - выйти из цикла
#Заснуть до следующего цикла
lFlagLoop = False ;
time . sleep ( lTimeSleepSeconds )
#Заснуть до следующего цикла
#Ветка поиска по заранее созданной карте
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
return lGUISearchElementSelected
def AutomationSearchMouseElementHierarchy ( inElementSpecification ) :
def AutomationSearchMouseElementHierarchy ( inElementSpecification ,inFlagIsSearchOnline = True ):
lItemInfo = None
lItemInfo = None
#Запустить функцию поиска элемента по мыши
#Запустить функцию поиска элемента по мыши
lElement = AutomationSearchMouseElement ( inElementSpecification )
lElement = AutomationSearchMouseElement ( inElementSpecification ,inFlagIsSearchOnline )
#Detect backend of the elements
#Detect backend of the elements
lFlagIsBackendWin32 = True
lFlagIsBackendWin32 = True
if lElement . backend . name == ' uia ' :
lFlagIsBackendWin32 = False
#Если объект имеется (не None), то выполнить построение иерархии
#Если объект имеется (не None), то выполнить построение иерархии
if lElement is not None :
if lElement is not None :
if lElement . backend . name == ' uia ' :
lFlagIsBackendWin32 = False
#Циклическое создание дерева
#Циклическое создание дерева
while lElement is not None :
while lElement is not None :
#Продолжать построение иерархии во всех случаях кроме бэк uia & parent() is None
#Продолжать построение иерархии во всех случаях кроме бэк uia & parent() is None
@ -197,9 +227,9 @@ def ProcessParentWriteString(lString):
#print(b"Result: "+lByteString)
#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\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"
#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=open("logSendByteStringWithoutN.log","wb" )
lt . write ( lByteString )
#lt.write(lByteString )
lt . close ( )
#lt.close( )
############################
############################
sys . stdout . buffer . write ( lByteString + bytes ( " \n " , " utf-8 " ) )
sys . stdout . buffer . write ( lByteString + bytes ( " \n " , " utf-8 " ) )
sys . stdout . flush ( ) ;
sys . stdout . flush ( ) ;
@ -226,7 +256,7 @@ def GetControl(inControlSpecificationArray):
lResultList = [ ] ;
lResultList = [ ] ;
if len ( inControlSpecificationArray ) > 0 :
if len ( inControlSpecificationArray ) > 0 :
#Выполнить подключение к объекту
#Выполнить подключение к объекту
lRPAApplication = pywinauto . Application ( )
lRPAApplication = pywinauto . Application ( backend = mPywinautoActiveBackend )
#Проверка разрядности
#Проверка разрядности
lRPAApplication . connect ( * * inControlSpecificationArray [ 0 ] )
lRPAApplication . connect ( * * inControlSpecificationArray [ 0 ] )
#lTempObject=lRPAApplication.window(**inControlSpecificationArray[0])
#lTempObject=lRPAApplication.window(**inControlSpecificationArray[0])
@ -243,7 +273,17 @@ def GetControl(inControlSpecificationArray):
def ElementActionGetList ( inControlSpecificationArray ) :
def ElementActionGetList ( inControlSpecificationArray ) :
#Получить объект
#Получить объект
lObject = GetControl ( 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 = { } ) :
def ElementRunAction ( inControlSpecificationArray , inActionName , inArgumentList = [ ] , inkwArgumentObject = { } ) :
#Определить объект
#Определить объект
@ -308,7 +348,7 @@ def GUISearchRun(inSpecificationArray):
#Создать карту пикселей и элементов
#Создать карту пикселей и элементов
lBitmap = GUISearchBitmapCreate ( GetControl ( inSpecificationArray ) , lBitmap )
lBitmap = GUISearchBitmapCreate ( GetControl ( inSpecificationArray ) , lBitmap )
#Выдать сообщение, что поиск готов к использованию
#Выдать сообщение, что поиск готов к использованию
print ( " GUISearch: Ready for search! " )
#print("GUISearch: Ready for search!" )
#mBitmap=lBitmap
#mBitmap=lBitmap
# Collect events until released
# Collect events until released
#Версия с Events (занимает поток, чтобы использовать общие переменные)
#Версия с Events (занимает поток, чтобы использовать общие переменные)
@ -351,6 +391,78 @@ def GUISearchRun(inSpecificationArray):
time . sleep ( lTimeSleepSeconds )
time . sleep ( lTimeSleepSeconds )
#Вернуть результат поиска
#Вернуть результат поиска
return lGUISearchElementSelected
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 = { } ) :
def GUISearchBitmapCreate ( inElement , inBitmapDict = { } ) :
#Добавить в карту информацию о текущем объекте
#Добавить в карту информацию о текущем объекте
inBitmapDict = GUISearchBitmapElementFill ( inElement , inBitmapDict )
inBitmapDict = GUISearchBitmapElementFill ( inElement , inBitmapDict )
@ -362,6 +474,7 @@ def GUISearchBitmapCreate (inElement,inBitmapDict={}):
#GUISearchBitmapElementFill
#GUISearchBitmapElementFill
def GUISearchBitmapElementFill ( inElement , inBitmapDict ) :
def GUISearchBitmapElementFill ( inElement , inBitmapDict ) :
lElementInfo = inElement . element_info
lElementInfo = inElement . element_info
#pdb.set_trace()
#Получить параметры прямоугольника
#Получить параметры прямоугольника
lElementRectX1 = 0
lElementRectX1 = 0
lElementRectX2 = 0
lElementRectX2 = 0
@ -373,22 +486,64 @@ def GUISearchBitmapElementFill (inElement,inBitmapDict):
lElementRectX2 = lElementInfo . rectangle . right
lElementRectX2 = lElementInfo . rectangle . right
lElementRectY1 = lElementInfo . rectangle . top
lElementRectY1 = lElementInfo . rectangle . top
lElementRectY2 = lElementInfo . rectangle . bottom
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 :
except Exception as e :
lFlagHasRect = False
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
return inBitmapDict
#debug
#debug
def ElementGetChildElementList ( inControlSpecificationArray = [ ] ) :
def ElementGetChildElementList ( inControlSpecificationArray = [ ] ) :
@ -593,10 +748,10 @@ def JSONNormalizeDictList(inDictList):
#Получить объект из атрибутов, которые удалось прочитать
#Получить объект из атрибутов, которые удалось прочитать
def ElementInfoExportObject ( inElementInfo ) :
def ElementInfoExportObject ( inElementInfo ) :
#Подготовить выходную структуру данных
#Подготовить выходную структуру данных
lResult = { " nam e" : 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 = { " titl e" : 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
#Проверка name
try :
try :
lResult [ ' nam e' ] = inElementInfo . name
lResult [ ' titl e' ] = inElementInfo . name
except Exception as e :
except Exception as e :
True == False
True == False
#Проверка rich_text
#Проверка rich_text
@ -670,52 +825,62 @@ def GetRootElementList():
def ElementDrawOutlineNew ( inSpecificationArray ) :
def ElementDrawOutlineNew ( inSpecificationArray ) :
draw_outline_new ( GetControl ( inSpecificationArray ) )
draw_outline_new ( GetControl ( inSpecificationArray ) )
return
return
def draw_outline_new ( lWrapperObject , colour = ' green ' , thickness = 2 , fill = win32defines . BS_NULL , rect = None ) :
def ElementDrawOutlineNewFocus ( inSpecificationArray ) :
"""
draw_outline_new_focus ( GetControl ( inSpecificationArray ) )
Draw an outline around the window .
return
* * * colour * * can be either an integer or one of ' red ' , ' green ' , ' blue '
def draw_outline_new ( lWrapperObject , colour = ' green ' , thickness = 2 , fill = win32defines . BS_NULL , rect = None , inFlagSetFocus = False ) :
( default ' green ' )
if lWrapperObject is not None :
* * * thickness * * thickness of rectangle ( default 2 )
"""
* * * fill * * how to fill in the rectangle ( default BS_NULL )
Draw an outline around the window .
* * * rect * * the coordinates of the rectangle to draw ( defaults to
* * * colour * * can be either an integer or one of ' red ' , ' green ' , ' blue '
the rectangle of the control )
( default ' green ' )
"""
* * * thickness * * thickness of rectangle ( default 2 )
#pdb.set_trace()
* * * fill * * how to fill in the rectangle ( default BS_NULL )
# don't draw if dialog is not visible
* * * rect * * the coordinates of the rectangle to draw ( defaults to
#if not lWrapperObject.is_visible():
the rectangle of the control )
# return
"""
colours = {
if inFlagSetFocus :
" green " : 0x00ff00 ,
#Установить фокус на объект, чтобы было видно выделение
" blue " : 0xff0000 ,
lWrapperObject . set_focus ( )
" red " : 0x0000ff ,
}
#pdb.set_trace()
# if it's a known colour
# don't draw if dialog is not visible
if colour in colours :
#if not lWrapperObject.is_visible():
colour = colours [ colour ]
# return
if rect is None :
colours = {
rect = lWrapperObject . rectangle ( )
" green " : 0x00ff00 ,
# create the pen(outline)
" blue " : 0xff0000 ,
pen_handle = win32functions . CreatePen (
" red " : 0x0000ff ,
win32defines . PS_SOLID , thickness , colour )
}
# create the brush (inside)
# if it's a known colour
brush = win32structures . LOGBRUSH ( )
if colour in colours :
brush . lbStyle = fill
colour = colours [ colour ]
brush . lbHatch = win32defines . HS_DIAGCROSS
if rect is None :
brush_handle = win32functions . CreateBrushIndirect ( ctypes . byref ( brush ) )
rect = lWrapperObject . rectangle ( )
# get the Device Context
# create the pen(outline)
dc = win32functions . CreateDC ( " DISPLAY " , None , None , None )
pen_handle = win32functions . CreatePen (
# push our objects into it
win32defines . PS_SOLID , thickness , colour )
win32functions . SelectObject ( dc , brush_handle )
# create the brush (inside)
win32functions . SelectObject ( dc , pen_handle )
brush = win32structures . LOGBRUSH ( )
# draw the rectangle to the DC
brush . lbStyle = fill
win32functions . Rectangle (
brush . lbHatch = win32defines . HS_DIAGCROSS
dc , rect . left , rect . top , rect . right , rect . bottom )
brush_handle = win32functions . CreateBrushIndirect ( ctypes . byref ( brush ) )
# Delete the brush and pen we created
# get the Device Context
win32functions . DeleteObject ( brush_handle )
dc = win32functions . CreateDC ( " DISPLAY " , None , None , None )
win32functions . DeleteObject ( pen_handle )
# push our objects into it
# delete the Display context that we created
win32functions . SelectObject ( dc , brush_handle )
win32functions . DeleteDC ( dc )
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()
#run()
lText = " Bitness: " + str ( struct . calcsize ( " P " ) * 8 )
lText = " Bitness: " + str ( struct . calcsize ( " P " ) * 8 )
#for line in sys.stdin:
#for line in sys.stdin: