|
|
|
|
from pyautogui import *
|
|
|
|
|
import pyscreeze
|
|
|
|
|
import ctypes
|
|
|
|
|
from pyOpenRPA.Tools import CrossOS
|
|
|
|
|
if CrossOS.IS_WINDOWS_BOOL:
|
|
|
|
|
from pywinauto import win32defines, win32structures, win32functions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def BoxCreate(inTopInt:int, inLeftInt:int, inHeightInt:int, inWidthInt:int) -> pyscreeze.Box:
|
|
|
|
|
"""Создать экземпляр прямоугольной области.
|
|
|
|
|
|
|
|
|
|
!ВНИМАНИЕ! Координаты inTopInt, inLeftInt определяют верхний левый край прямоугольной области.
|
|
|
|
|
|
|
|
|
|
:param inTopInt: Координата левой верхней точки в пикселях по оси X (горизонталь)
|
|
|
|
|
:type inTopInt: int
|
|
|
|
|
:param inLeftInt: Координата левой верхней точки в пикселях по оси Y (вертикаль)
|
|
|
|
|
:type inLeftInt: int
|
|
|
|
|
:param inHeightInt: Расстояние вниз от левой верхней точки в пикселях
|
|
|
|
|
:type inHeightInt: int
|
|
|
|
|
:param inWidthInt: Расстояние вправо от левой верхней точки в пикселях
|
|
|
|
|
:type inWidthInt: int
|
|
|
|
|
"""
|
|
|
|
|
return pyscreeze.Box(top = inTopInt, left = inLeftInt, height = inHeightInt, width = inWidthInt)
|
|
|
|
|
|
|
|
|
|
def BoxNormalize(*inArgList, **inAgrDict) -> list:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def BoxMoveTo(inBox, inDXInt=None, inDYInt=None):
|
|
|
|
|
"""Переместить прямоугольную область (сохранить длину/ширину).
|
|
|
|
|
|
|
|
|
|
!ВНИМАНИЕ! ПОДДЕРЖИВАЕТ ПАКЕТНУЮ ОБРАТКУ ПРИ ПЕРЕДАЧЕ СПИСКА ЭКЗЕМПЛЯРОВ BOX
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
# Screen: Взаимодействие с экраном
|
|
|
|
|
from pyOpenRPA.Robot import Screen
|
|
|
|
|
# Вариант изменения 1-го элемента
|
|
|
|
|
# Создать пробную прямоугольную область
|
|
|
|
|
lBox = Screen.BoxCreate(inTopInt=10, inLeftInt=10, inHeightInt=10, inWidthInt=10)
|
|
|
|
|
# Переместить пробную прямоугольную область
|
|
|
|
|
lBox = Screen.BoxMoveTo(lBox, inDXInt=100, inDYInt=200)
|
|
|
|
|
|
|
|
|
|
:param inBox: Экземпляр класса прямоугольной области Box
|
|
|
|
|
:type inBox: pyscreeze.Box
|
|
|
|
|
:param inDXInt: Смещение левой верхней координаты по оси X в пикселях (горизонтальная ось).
|
|
|
|
|
:type inDXInt: int, опциональный
|
|
|
|
|
:param inDYInt: Смещение левой верхней координаты по оси Y в пикселях (вертикальная ось).
|
|
|
|
|
:type inDYInt: int, опциональный
|
|
|
|
|
:return: Экземпляр класса прямоугольной области Box
|
|
|
|
|
:rtype: pyscreeze.Box
|
|
|
|
|
"""
|
|
|
|
|
if type(inBox) is list:
|
|
|
|
|
lResult = []
|
|
|
|
|
for lBox in inBox:
|
|
|
|
|
lResult.append(BoxMoveTo(lBox, inDXInt=inDXInt, inDYInt=inDYInt))
|
|
|
|
|
return lResult
|
|
|
|
|
else:
|
|
|
|
|
lTopInt = inBox.top
|
|
|
|
|
lLeftInt = inBox.left
|
|
|
|
|
if inDXInt: lLeftInt = inBox.left + inDXInt
|
|
|
|
|
if inDYInt: lTopInt = inBox.top + inDYInt
|
|
|
|
|
return BoxCreate(inTopInt=lTopInt, inLeftInt=lLeftInt,
|
|
|
|
|
inHeightInt=inBox.height, inWidthInt=inBox.width)
|
|
|
|
|
|
|
|
|
|
def BoxModify(inBox, inDWidthInt=None, inDHeightInt=None, inAnchorStr="CC"):
|
|
|
|
|
"""Изменить ширину / высоту прямоугольной области.
|
|
|
|
|
|
|
|
|
|
!ВНИМАНИЕ! ПОДДЕРЖИВАЕТ ПАКЕТНУЮ ОБРАТКУ ПРИ ПЕРЕДАЧЕ СПИСКА ЭКЗЕМПЛЯРОВ BOX
|
|
|
|
|
|
|
|
|
|
!ВНИМАНИЕ! ЕСЛИ СМЕЩЕНИЕ ПРИВЕДЕТ К ОБРАЗОВАНИЮ ДРОБНОГО ЧИСЛА, БУДЕТ ВЫПОЛНЕНО ОКРУГЛЕНИЕ ПО МАТЕМАТИЧЕСКИМ ПРАВИЛАМ
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
# Screen: Взаимодействие с экраном
|
|
|
|
|
from pyOpenRPA.Robot import Screen
|
|
|
|
|
# Вариант изменения 1-го элемента
|
|
|
|
|
# Создать пробную прямоугольную область
|
|
|
|
|
lBox = Screen.BoxCreate(inTopInt=10, inLeftInt=10, inHeightInt=10, inWidthInt=10)
|
|
|
|
|
# Скорректировать пробную прямоугольную область
|
|
|
|
|
lBox2 = Screen.BoxModify(lBox,10,10,"CC"); print(lBox2)
|
|
|
|
|
lBox2 = Screen.BoxModify(lBox,10,10,"LU"); print(lBox2)
|
|
|
|
|
lBox2 = Screen.BoxModify(lBox,10,10,"LD"); print(lBox2)
|
|
|
|
|
lBox2 = Screen.BoxModify(lBox,10,10,"RU"); print(lBox2)
|
|
|
|
|
lBox2 = Screen.BoxModify(lBox,10,10,"RD"); print(lBox2)
|
|
|
|
|
|
|
|
|
|
:param inBox: Экземпляр класса прямоугольной области Box
|
|
|
|
|
:type inBox: pyscreeze.Box
|
|
|
|
|
:param inDXInt: Смещение левой верхней координаты по оси X в пикселях (горизонтальная ось).
|
|
|
|
|
:type inDXInt: int, опциональный
|
|
|
|
|
:param inDYInt: Смещение левой верхней координаты по оси Y в пикселях (вертикальная ось).
|
|
|
|
|
:type inDYInt: int, опциональный
|
|
|
|
|
:param inAnchorStr: Символьное указание точки (подробнее см. выше), относительно которой выполнить изменение прямоугольной области. Допустимые значения: "CC" (по умолчанию), "LU", "LD", "RD", "RU"
|
|
|
|
|
:type inAnchorStr: str, опциональный
|
|
|
|
|
:return: Экземпляр класса прямоугольной области Box
|
|
|
|
|
:rtype: pyscreeze.Box
|
|
|
|
|
"""
|
|
|
|
|
if type(inBox) is list:
|
|
|
|
|
lResult = []
|
|
|
|
|
for lBox in inBox:
|
|
|
|
|
lResult.append(BoxModify(lBox, inDWidthInt=inDWidthInt, inDHeightInt=inDHeightInt, inAnchorStr=inAnchorStr))
|
|
|
|
|
return lResult
|
|
|
|
|
else:
|
|
|
|
|
lTopInt = inBox.top
|
|
|
|
|
lLeftInt = inBox.left
|
|
|
|
|
lWidthInt = inBox.width + inDWidthInt
|
|
|
|
|
lHeightInt = inBox.height + inDHeightInt
|
|
|
|
|
inAnchorStr = inAnchorStr.upper() # ВЕРХНИЙ РЕГИСТР
|
|
|
|
|
if inDWidthInt: # Изменения по ширине
|
|
|
|
|
if "C" in inAnchorStr:
|
|
|
|
|
lLeftInt = round(lLeftInt - inDWidthInt / 2)
|
|
|
|
|
elif "R" in inAnchorStr:
|
|
|
|
|
lLeftInt = lLeftInt - inDWidthInt
|
|
|
|
|
if inDHeightInt: # Изменения по высоте
|
|
|
|
|
if "C" in inAnchorStr:
|
|
|
|
|
lTopInt = round(lTopInt - inDHeightInt / 2)
|
|
|
|
|
elif "D" in inAnchorStr:
|
|
|
|
|
lTopInt = lTopInt - inDHeightInt
|
|
|
|
|
return BoxCreate(inTopInt=lTopInt, inLeftInt=lLeftInt,
|
|
|
|
|
inHeightInt=lHeightInt, inWidthInt=lWidthInt)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def BoxDraw(inBox, inColorStr='green',inThicknessInt = 2):
|
|
|
|
|
""" Выполнить подсветку прямоугольной области inBox на экране
|
|
|
|
|
|
|
|
|
|
!ВНИМАНИЕ! РАБОТАЕТ ТОЛЬКО НА ОС WINDOWS
|
|
|
|
|
|
|
|
|
|
!ВНИМАНИЕ! ПОДДЕРЖИВАЕТ ПАКЕТНУЮ ОБРАТКУ ПРИ ПЕРЕДАЧЕ СПИСКА ЭКЗЕМПЛЯРОВ BOX
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
# Screen: Взаимодействие с экраном
|
|
|
|
|
from pyOpenRPA.Robot import Screen
|
|
|
|
|
# ВАРИАНТ ОТРИСОВКИ 1ГО ЭЛЕМЕНТА
|
|
|
|
|
# Создать пробную прямоугольную область
|
|
|
|
|
lBox = Screen.BoxCreate(inTopInt=10, inLeftInt=10, inHeightInt=10, inWidthInt=10)
|
|
|
|
|
Screen.BoxDraw(lBox)
|
|
|
|
|
|
|
|
|
|
# ВАРИАНТ ПАКЕТНОЙ ОТРИСОВКИ
|
|
|
|
|
# Создать пробную прямоугольную область
|
|
|
|
|
lBox = Screen.BoxCreate(inTopInt=10, inLeftInt=10, inHeightInt=100, inWidthInt=100)
|
|
|
|
|
lBox2 = Screen.BoxCreate(inTopInt=60, inLeftInt=60, inHeightInt=100, inWidthInt=100)
|
|
|
|
|
Screen.BoxDraw([lBox, lBox2])
|
|
|
|
|
|
|
|
|
|
:param inBox: UIO объект, который будет подсвечен
|
|
|
|
|
:type inBox: object UIO, обязательный
|
|
|
|
|
:param inColorStr: цвет подсветки UIO объекта. Варианты: 'red', 'green', 'blue'. По умолчанию 'green'
|
|
|
|
|
:type inColorStr: str, необязательный
|
|
|
|
|
:param inThicknessInt: толщина подсветки UIO объекта. По умолчанию 2
|
|
|
|
|
:type inThicknessInt: int, необязательный
|
|
|
|
|
"""
|
|
|
|
|
if type(inBox) is list:
|
|
|
|
|
for lBox in inBox:
|
|
|
|
|
BoxDraw(inBox=lBox, inColorStr=inColorStr,inThicknessInt = inThicknessInt)
|
|
|
|
|
else:
|
|
|
|
|
fill = win32defines.BS_NULL
|
|
|
|
|
if inBox is not None:
|
|
|
|
|
"""
|
|
|
|
|
Draw an outline around the window.
|
|
|
|
|
* **inColorStr** can be either an integer or one of 'red', 'green', 'blue'
|
|
|
|
|
(default 'green')
|
|
|
|
|
* **inThicknessInt** inThicknessInt of rectangle (default 2)
|
|
|
|
|
* **fill** how to fill in the rectangle (default BS_NULL)
|
|
|
|
|
"""
|
|
|
|
|
# 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 inColorStr in colours:
|
|
|
|
|
inColorStr = colours[inColorStr]
|
|
|
|
|
# create the pen(outline)
|
|
|
|
|
pen_handle = win32functions.CreatePen(
|
|
|
|
|
win32defines.PS_SOLID, inThicknessInt, inColorStr)
|
|
|
|
|
# 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, inBox.left, inBox.top, inBox.left+inBox.width, inBox.top+inBox.height)
|
|
|
|
|
# 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)
|