signature:
def computeStatsEigen ( self ) :
    """compute the eigen decomp using copied var stats to avoid concurrent read / write from other queue"""

implementation:
# TO - DO : figure out why this op has delays ( possibly moving
# eigenvectors around ? )
with tf . device ( '/cpu:0' ) :
    def removeNone ( tensor_list ) :
        local_list = [ ]
        for item in tensor_list :
            if item is not None :
                local_list . append ( item )
        return local_list
    def copyStats ( var_list ) :
        print ( "copying stats to buffer tensors before eigen decomp" )
        redundant_stats = { }
        copied_list = [ ]
        for item in var_list :
            if item is not None :
                if item not in redundant_stats :
                    if self . _use_float64 :
                        redundant_stats [ item ] = tf . cast ( tf . identity ( item ) , tf . float64 )
                    else :
                        redundant_stats [ item ] = tf . identity ( item )
                copied_list . append ( redundant_stats [ item ] )
            else :
                copied_list . append ( None )
        return copied_list
    # stats = [ copyStats ( self . fStats ) , copyStats ( self . bStats ) ]
    # stats = [ self . fStats , self . bStats ]
    stats_eigen = self . stats_eigen
    computedEigen = { }
    eigen_reverse_lookup = { }
    updateOps = [ ]
    # sync copied stats
    # with tf . control _ dependencies ( removeNone ( stats [ 0 ] ) +
    # removeNone ( stats [ 1 ] ) ) :
    with tf . control_dependencies ( [ ] ) :
        for stats_var in stats_eigen :
            if stats_var not in computedEigen :
                eigens = tf . self_adjoint_eig ( stats_var )
                e = eigens [ 0 ]
                Q = eigens [ 1 ]
                if self . _use_float64 :
                    e = tf . cast ( e , tf . float32 )
                    Q = tf . cast ( Q , tf . float32 )
                updateOps . append ( e )
                updateOps . append ( Q )
                computedEigen [ stats_var ] = { 'e' : e , 'Q' : Q }
                eigen_reverse_lookup [ e ] = stats_eigen [ stats_var ] [ 'e' ]
                eigen_reverse_lookup [ Q ] = stats_eigen [ stats_var ] [ 'Q' ]
    self . eigen_reverse_lookup = eigen_reverse_lookup
    self . eigen_update_list = updateOps
return updateOps


signature:
def tf_step ( self , time , variables , ** kwargs ) :
    """Creates the TensorFlow operations for performing an optimization step on the given variables , including
 actually changing the values of the variables .
 Args :
 time : Time tensor . Not used for this optimizer .
 variables : List of variables to optimize .
 * * kwargs :
 fn _ loss : loss function tensor to differentiate .
 Returns :
 List of delta tensors corresponding to the updates for each optimized variable ."""

implementation:
fn_loss = kwargs [ "fn_loss" ]
if variables is None :
    variables = tf . trainable_variables
return tf . gradients ( fn_loss , variables )


signature:
def apply_step ( self , variables , deltas , loss_sampled ) :
    """Applies the given ( and already calculated ) step deltas to the variable values .
 Args :
 variables : List of variables .
 deltas : List of deltas of same length .
 loss _ sampled : the sampled loss
 Returns :
 The step - applied operation . A tf . group of tf . assign _ add ops ."""

implementation:
update_stats_op = self . compute_and_apply_stats ( loss_sampled , var_list = var_list )
grads = [ ( a , b ) for a , b in zip ( deltas , varlist ) ]
kfacOptim , _ = self . apply_gradients_kfac ( grads )
return kfacOptim


signature:
def minimize ( self , time , variables , ** kwargs ) :
    """Performs an optimization step .
 Args :
 time : Time tensor . Not used for this
 variables : List of variables to optimize .
 * * kwargs :
 fn _ loss : loss function tensor that is differentiated
 sampled _ loss : the sampled loss from running the model .
 Returns :
 The optimization operation ."""

implementation:
loss = kwargs [ "fn_loss" ]
sampled_loss = kwargs [ "sampled_loss" ]
min_op , _ = self . minimize_ ( loss , sampled_loss , var_list = variables )
return min_op


signature:
def setup_components_and_tf_funcs ( self , custom_getter = None ) :
    """Constructs the extra Replay memory ."""

implementation:
custom_getter = super ( QDemoModel , self ) . setup_components_and_tf_funcs ( custom_getter )
self . demo_memory = Replay ( states = self . states_spec , internals = self . internals_spec , actions = self . actions_spec , include_next_states = True , capacity = self . demo_memory_capacity , scope = 'demo-replay' , summary_labels = self . summary_labels )
# Import demonstration optimization .
self . fn_import_demo_experience = tf . make_template ( name_ = 'import-demo-experience' , func_ = self . tf_import_demo_experience , custom_getter_ = custom_getter )
# Demonstration loss .
self . fn_demo_loss = tf . make_template ( name_ = 'demo-loss' , func_ = self . tf_demo_loss , custom_getter_ = custom_getter )
# Combined loss .
self . fn_combined_loss = tf . make_template ( name_ = 'combined-loss' , func_ = self . tf_combined_loss , custom_getter_ = custom_getter )
# Demonstration optimization .
self . fn_demo_optimization = tf . make_template ( name_ = 'demo-optimization' , func_ = self . tf_demo_optimization , custom_getter_ = custom_getter )
return custom_getter


signature:
def tf_import_demo_experience ( self , states , internals , actions , terminal , reward ) :
    """Imports a single experience to memory ."""

implementation: return self . demo_memory . store ( states = states , internals = internals , actions = actions , terminal = terminal , reward = reward )


signature:
def tf_demo_loss ( self , states , actions , terminal , reward , internals , update , reference = None ) :
    """Extends the q - model loss via the dqfd large - margin loss ."""

implementation:
embedding = self . network . apply ( x = states , internals = internals , update = update )
deltas = list ( )
for name in sorted ( actions ) :
    action = actions [ name ]
    distr_params = self . distributions [ name ] . parameterize ( x = embedding )
    state_action_value = self . distributions [ name ] . state_action_value ( distr_params = distr_params , action = action )
    # Create the supervised margin loss
    # Zero for the action taken , one for all other actions , now multiply by expert margin
    if self . actions_spec [ name ] [ 'type' ] == 'bool' :
        num_actions = 2
        action = tf . cast ( x = action , dtype = util . tf_dtype ( 'int' ) )
    else :
        num_actions = self . actions_spec [ name ] [ 'num_actions' ]
    one_hot = tf . one_hot ( indices = action , depth = num_actions )
    ones = tf . ones_like ( tensor = one_hot , dtype = tf . float32 )
    inverted_one_hot = ones - one_hot
    # max _ a ( [ Q ( s , a ) + l ( s , a _ E , a ) ] , l ( s , a _ E , a ) is 0 for expert action and margin value for others
    state_action_values = self . distributions [ name ] . state_action_value ( distr_params = distr_params )
    state_action_values = state_action_values + inverted_one_hot * self . expert_margin
    supervised_selector = tf . reduce_max ( input_tensor = state_action_values , axis = - 1 )
    # J _ E ( Q ) = max _ a ( [ Q ( s , a ) + l ( s , a _ E , a ) ] - Q ( s , a _ E )
    delta = supervised_selector - state_action_value
    action_size = util . prod ( self . actions_spec [ name ] [ 'shape' ] )
    delta = tf . reshape ( tensor = delta , shape = ( - 1 , action_size ) )
    deltas . append ( delta )
loss_per_instance = tf . reduce_mean ( input_tensor = tf . concat ( values = deltas , axis = 1 ) , axis = 1 )
loss_per_instance = tf . square ( x = loss_per_instance )
return tf . reduce_mean ( input_tensor = loss_per_instance , axis = 0 )


signature:
def tf_combined_loss ( self , states , internals , actions , terminal , reward , next_states , next_internals , update , reference = None ) :
    """Combines Q - loss and demo loss ."""

implementation:
q_model_loss = self . fn_loss ( states = states , internals = internals , actions = actions , terminal = terminal , reward = reward , next_states = next_states , next_internals = next_internals , update = update , reference = reference )
demo_loss = self . fn_demo_loss ( states = states , internals = internals , actions = actions , terminal = terminal , reward = reward , update = update , reference = reference )
return q_model_loss + self . supervised_weight * demo_loss


signature:
def get_variables ( self , include_submodules = False , include_nontrainable = False ) :
    """Returns the TensorFlow variables used by the model .
 Returns :
 List of variables ."""

implementation:
model_variables = super ( QDemoModel , self ) . get_variables ( include_submodules = include_submodules , include_nontrainable = include_nontrainable )
if include_nontrainable :
    demo_memory_variables = self . demo_memory . get_variables ( )
    model_variables += demo_memory_variables
return model_variables


signature:
def import_demo_experience ( self , states , internals , actions , terminal , reward ) :
    """Stores demonstrations in the demo memory ."""

implementation:
fetches = self . import_demo_experience_output
feed_dict = self . get_feed_dict ( states = states , internals = internals , actions = actions , terminal = terminal , reward = reward )
self . monitored_session . run ( fetches = fetches , feed_dict = feed_dict )


signature:
def demo_update ( self ) :
    """Performs a demonstration update by calling the demo optimization operation .
 Note that the batch data does not have to be fetched from the demo memory as this is now part of
 the TensorFlow operation of the demo update ."""

implementation:
fetches = self . demo_optimization_output
self . monitored_session . run ( fetches = fetches )


signature:
def from_config ( config , kwargs = None ) :
    """Creates a solver from a specification dict ."""

implementation: return util . get_object ( obj = config , predefined = tensorforce . core . optimizers . solvers . solvers , kwargs = kwargs )


signature:
def tf_step ( self , time , variables , ** kwargs ) :
    """Keyword Args :
 arguments : Dict of arguments for passing to fn _ loss as * * kwargs .
 fn _ loss : A callable taking arguments as kwargs and returning the loss op of the current model ."""

implementation:
arguments = kwargs [ "arguments" ]
fn_loss = kwargs [ "fn_loss" ]
loss = fn_loss ( ** arguments )
# Force loss value to be calculated .
with tf . control_dependencies ( control_inputs = ( loss , ) ) : # Trivial operation to enforce control dependency
    previous_variables = [ variable + 0.0 for variable in variables ]
# The actual tensorflow minimize op .
with tf . control_dependencies ( control_inputs = previous_variables ) :
    applied = self . tf_optimizer . minimize ( loss = loss , var_list = variables )
# colocate _ gradients _ with _ ops = True
# Return deltas after actually having change the variables .
with tf . control_dependencies ( control_inputs = ( applied , ) ) :
    return [ variable - previous_variable for variable , previous_variable in zip ( variables , previous_variables ) ]


signature:
def SetClipboardText ( text : str ) -> bool :
    """Return bool , True if succeed otherwise False ."""

implementation:
if ctypes . windll . user32 . OpenClipboard ( 0 ) :
    ctypes . windll . user32 . EmptyClipboard ( )
    textByteLen = ( len ( text ) + 1 ) * 2
    hClipboardData = ctypes . windll . kernel32 . GlobalAlloc ( 0 , textByteLen )
    # GMEM _ FIXED = 0
    hDestText = ctypes . windll . kernel32 . GlobalLock ( hClipboardData )
    ctypes . cdll . msvcrt . wcsncpy ( ctypes . c_wchar_p ( hDestText ) , ctypes . c_wchar_p ( text ) , textByteLen // 2 )
    ctypes . windll . kernel32 . GlobalUnlock ( hClipboardData )
    # system owns hClipboardData after calling SetClipboardData ,
    # application can not write to or free the data once ownership has been transferred to the system
    ctypes . windll . user32 . SetClipboardData ( 13 , hClipboardData )
    # CF _ TEXT = 1 , CF _ UNICODETEXT = 13
    ctypes . windll . user32 . CloseClipboard ( )
    return True
return False


signature:
def SetConsoleColor ( color : int ) -> bool :
    """Change the text color on console window .
 color : int , a value in class ` ConsoleColor ` .
 Return bool , True if succeed otherwise False ."""

implementation:
global _ConsoleOutputHandle
global _DefaultConsoleColor
if not _DefaultConsoleColor :
    if not _ConsoleOutputHandle :
        _ConsoleOutputHandle = ctypes . windll . kernel32 . GetStdHandle ( _StdOutputHandle )
    bufferInfo = ConsoleScreenBufferInfo ( )
    ctypes . windll . kernel32 . GetConsoleScreenBufferInfo ( _ConsoleOutputHandle , ctypes . byref ( bufferInfo ) )
    _DefaultConsoleColor = int ( bufferInfo . wAttributes & 0xFF )
if sys . stdout :
    sys . stdout . flush ( )
bool ( ctypes . windll . kernel32 . SetConsoleTextAttribute ( _ConsoleOutputHandle , color ) )


signature:
def ResetConsoleColor ( ) -> bool :
    """Reset to the default text color on console window .
 Return bool , True if succeed otherwise False ."""

implementation:
if sys . stdout :
    sys . stdout . flush ( )
bool ( ctypes . windll . kernel32 . SetConsoleTextAttribute ( _ConsoleOutputHandle , _DefaultConsoleColor ) )


signature:
def WindowFromPoint ( x : int , y : int ) -> int :
    """WindowFromPoint from Win32.
 Return int , a native window handle ."""

implementation: return ctypes . windll . user32 . WindowFromPoint ( ctypes . wintypes . POINT ( x , y ) )


signature:
def GetCursorPos ( ) -> tuple :
    """GetCursorPos from Win32.
 Get current mouse cursor positon .
 Return tuple , two ints tuple ( x , y ) ."""

implementation:
point = ctypes . wintypes . POINT ( 0 , 0 )
ctypes . windll . user32 . GetCursorPos ( ctypes . byref ( point ) )
return point . x , point . y


signature:
def SetCursorPos ( x : int , y : int ) -> bool :
    """SetCursorPos from Win32.
 Set mouse cursor to point x , y .
 x : int .
 y : int .
 Return bool , True if succeed otherwise False ."""

implementation: return bool ( ctypes . windll . user32 . SetCursorPos ( x , y ) )


signature:
def mouse_event ( dwFlags : int , dx : int , dy : int , dwData : int , dwExtraInfo : int ) -> None :
    """mouse _ event from Win32."""

implementation: ctypes . windll . user32 . mouse_event ( dwFlags , dx , dy , dwData , dwExtraInfo )


signature:
def keybd_event ( bVk : int , bScan : int , dwFlags : int , dwExtraInfo : int ) -> None :
    """keybd _ event from Win32."""

implementation: ctypes . windll . user32 . keybd_event ( bVk , bScan , dwFlags , dwExtraInfo )


signature:
def PostMessage ( handle : int , msg : int , wParam : int , lParam : int ) -> bool :
    """PostMessage from Win32.
 Return bool , True if succeed otherwise False ."""

implementation: return bool ( ctypes . windll . user32 . PostMessageW ( ctypes . c_void_p ( handle ) , msg , wParam , lParam ) )


signature:
def SendMessage ( handle : int , msg : int , wParam : int , lParam : int ) -> int :
    """SendMessage from Win32.
 Return int , the return value specifies the result of the message processing ;
 it depends on the message sent ."""

implementation: return ctypes . windll . user32 . SendMessageW ( ctypes . c_void_p ( handle ) , msg , wParam , lParam )


signature:
def Click ( x : int , y : int , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate mouse click at point x , y .
 x : int .
 y : int .
 waitTime : float ."""

implementation:
SetCursorPos ( x , y )
screenWidth , screenHeight = GetScreenSize ( )
mouse_event ( MouseEventFlag . LeftDown | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( 0.05 )
mouse_event ( MouseEventFlag . LeftUp | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( waitTime )


signature:
def MiddleClick ( x : int , y : int , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate mouse middle click at point x , y .
 x : int .
 y : int .
 waitTime : float ."""

implementation:
SetCursorPos ( x , y )
screenWidth , screenHeight = GetScreenSize ( )
mouse_event ( MouseEventFlag . MiddleDown | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( 0.05 )
mouse_event ( MouseEventFlag . MiddleUp | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( waitTime )


signature:
def RightClick ( x : int , y : int , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate mouse right click at point x , y .
 x : int .
 y : int .
 waitTime : float ."""

implementation:
SetCursorPos ( x , y )
screenWidth , screenHeight = GetScreenSize ( )
mouse_event ( MouseEventFlag . RightDown | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( 0.05 )
mouse_event ( MouseEventFlag . RightUp | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( waitTime )


signature:
def PressMouse ( x : int , y : int , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Press left mouse .
 x : int .
 y : int .
 waitTime : float ."""

implementation:
SetCursorPos ( x , y )
screenWidth , screenHeight = GetScreenSize ( )
mouse_event ( MouseEventFlag . LeftDown | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( waitTime )


signature:
def ReleaseMouse ( waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Release left mouse .
 waitTime : float ."""

implementation:
x , y = GetCursorPos ( )
screenWidth , screenHeight = GetScreenSize ( )
mouse_event ( MouseEventFlag . LeftUp | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( waitTime )


signature:
def RightPressMouse ( x : int , y : int , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Press right mouse .
 x : int .
 y : int .
 waitTime : float ."""

implementation:
SetCursorPos ( x , y )
screenWidth , screenHeight = GetScreenSize ( )
mouse_event ( MouseEventFlag . RightDown | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( waitTime )


signature:
def RightReleaseMouse ( waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Release right mouse .
 waitTime : float ."""

implementation:
x , y = GetCursorPos ( )
screenWidth , screenHeight = GetScreenSize ( )
mouse_event ( MouseEventFlag . RightUp | MouseEventFlag . Absolute , x * 65535 // screenWidth , y * 65535 // screenHeight , 0 , 0 )
time . sleep ( waitTime )


signature:
def MoveTo ( x : int , y : int , moveSpeed : float = 1 , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate mouse move to point x , y from current cursor .
 x : int .
 y : int .
 moveSpeed : float , 1 normal speed , < 1 move slower , > 1 move faster .
 waitTime : float ."""

implementation:
if moveSpeed <= 0 :
    moveTime = 0
else :
    moveTime = MAX_MOVE_SECOND / moveSpeed
curX , curY = GetCursorPos ( )
xCount = abs ( x - curX )
yCount = abs ( y - curY )
maxPoint = max ( xCount , yCount )
screenWidth , screenHeight = GetScreenSize ( )
maxSide = max ( screenWidth , screenHeight )
minSide = min ( screenWidth , screenHeight )
if maxPoint > minSide :
    maxPoint = minSide
if maxPoint < maxSide :
    maxPoint = 100 + int ( ( maxSide - 100 ) / maxSide * maxPoint )
    moveTime = moveTime * maxPoint * 1.0 / maxSide
stepCount = maxPoint // 20
if stepCount > 1 :
    xStep = ( x - curX ) * 1.0 / stepCount
    yStep = ( y - curY ) * 1.0 / stepCount
    interval = moveTime / stepCount
    for i in range ( stepCount ) :
        cx = curX + int ( xStep * i )
        cy = curY + int ( yStep * i )
        # upper - left ( 0,0 ) , lower - right ( 65536,65536)
        # mouse _ event ( MouseEventFlag . Move | MouseEventFlag . Absolute , cx * 65536 / / screenWidth , cy * 65536 / / screenHeight , 0 , 0)
        SetCursorPos ( cx , cy )
        time . sleep ( interval )
SetCursorPos ( x , y )
time . sleep ( waitTime )


signature:
def DragDrop ( x1 : int , y1 : int , x2 : int , y2 : int , moveSpeed : float = 1 , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate mouse left button drag from point x1 , y1 drop to point x2 , y2.
 x1 : int .
 y1 : int .
 x2 : int .
 y2 : int .
 moveSpeed : float , 1 normal speed , < 1 move slower , > 1 move faster .
 waitTime : float ."""

implementation:
PressMouse ( x1 , y1 , 0.05 )
MoveTo ( x2 , y2 , moveSpeed , 0.05 )
ReleaseMouse ( waitTime )


signature:
def RightDragDrop ( x1 : int , y1 : int , x2 : int , y2 : int , moveSpeed : float = 1 , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate mouse right button drag from point x1 , y1 drop to point x2 , y2.
 x1 : int .
 y1 : int .
 x2 : int .
 y2 : int .
 moveSpeed : float , 1 normal speed , < 1 move slower , > 1 move faster .
 waitTime : float ."""

implementation:
RightPressMouse ( x1 , y1 , 0.05 )
MoveTo ( x2 , y2 , moveSpeed , 0.05 )
RightReleaseMouse ( waitTime )


signature:
def WheelUp ( wheelTimes : int = 1 , interval : float = 0.05 , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate mouse wheel up .
 wheelTimes : int .
 interval : float .
 waitTime : float ."""

implementation:
for i in range ( wheelTimes ) :
    mouse_event ( MouseEventFlag . Wheel , 0 , 0 , 120 , 0 )
    # WHEEL _ DELTA = 120
    time . sleep ( interval )
time . sleep ( waitTime )


signature:
def GetScreenSize ( ) -> tuple :
    """Return tuple , two ints tuple ( width , height ) ."""

implementation:
SM_CXSCREEN = 0
SM_CYSCREEN = 1
w = ctypes . windll . user32 . GetSystemMetrics ( SM_CXSCREEN )
h = ctypes . windll . user32 . GetSystemMetrics ( SM_CYSCREEN )
return w , h


signature:
def GetPixelColor ( x : int , y : int , handle : int = 0 ) -> int :
    """Get pixel color of a native window .
 x : int .
 y : int .
 handle : int , the handle of a native window .
 Return int , the bgr value of point ( x , y ) .
 r = bgr & 0x0000FF
 g = ( bgr & 0x00FF00 ) > > 8
 b = ( bgr & 0xFF0000 ) > > 16
 If handle is 0 , get pixel from Desktop window ( root control ) .
 Note :
 Not all devices support GetPixel .
 An application should call GetDeviceCaps to determine whether a specified device supports this function .
 For example , console window doesn ' t support ."""

implementation:
hdc = ctypes . windll . user32 . GetWindowDC ( ctypes . c_void_p ( handle ) )
bgr = ctypes . windll . gdi32 . GetPixel ( hdc , x , y )
ctypes . windll . user32 . ReleaseDC ( ctypes . c_void_p ( handle ) , hdc )
return bgr


signature:
def MessageBox ( content : str , title : str , flags : int = MB . Ok ) -> int :
    """MessageBox from Win32.
 content : str .
 title : str .
 flags : int , a value or some combined values in class ` MB ` .
 Return int , a value in MB whose name starts with Id , such as MB . IdOk"""

implementation: return ctypes . windll . user32 . MessageBoxW ( ctypes . c_void_p ( 0 ) , ctypes . c_wchar_p ( content ) , ctypes . c_wchar_p ( title ) , flags )


signature:
def SetForegroundWindow ( handle : int ) -> bool :
    """SetForegroundWindow from Win32.
 handle : int , the handle of a native window .
 Return bool , True if succeed otherwise False ."""

implementation: return bool ( ctypes . windll . user32 . SetForegroundWindow ( ctypes . c_void_p ( handle ) ) )


signature:
def BringWindowToTop ( handle : int ) -> bool :
    """BringWindowToTop from Win32.
 handle : int , the handle of a native window .
 Return bool , True if succeed otherwise False ."""

implementation: return bool ( ctypes . windll . user32 . BringWindowToTop ( ctypes . c_void_p ( handle ) ) )


signature:
def SwitchToThisWindow ( handle : int ) -> None :
    """SwitchToThisWindow from Win32.
 handle : int , the handle of a native window ."""

implementation: ctypes . windll . user32 . SwitchToThisWindow ( ctypes . c_void_p ( handle ) , 1 )


signature:
def GetAncestor ( handle : int , flag : int ) -> int :
    """GetAncestor from Win32.
 handle : int , the handle of a native window .
 index : int , a value in class ` GAFlag ` .
 Return int , a native window handle ."""

implementation: return ctypes . windll . user32 . GetAncestor ( ctypes . c_void_p ( handle ) , flag )


signature:
def IsTopLevelWindow ( handle : int ) -> bool :
    """IsTopLevelWindow from Win32.
 handle : int , the handle of a native window .
 Return bool .
 Only available on Windows 7 or Higher ."""

implementation: return bool ( ctypes . windll . user32 . IsTopLevelWindow ( ctypes . c_void_p ( handle ) ) )


signature:
def GetWindowLong ( handle : int , index : int ) -> int :
    """GetWindowLong from Win32.
 handle : int , the handle of a native window .
 index : int ."""

implementation: return ctypes . windll . user32 . GetWindowLongW ( ctypes . c_void_p ( handle ) , index )


signature:
def SetWindowLong ( handle : int , index : int , value : int ) -> int :
    """SetWindowLong from Win32.
 handle : int , the handle of a native window .
 index : int .
 value : int .
 Return int , the previous value before set ."""

implementation: return ctypes . windll . user32 . SetWindowLongW ( ctypes . c_void_p ( handle ) , index , value )


signature:
def IsIconic ( handle : int ) -> bool :
    """IsIconic from Win32.
 Determine whether a native window is minimized .
 handle : int , the handle of a native window .
 Return bool ."""

implementation: return bool ( ctypes . windll . user32 . IsIconic ( ctypes . c_void_p ( handle ) ) )


signature:
def IsZoomed ( handle : int ) -> bool :
    """IsZoomed from Win32.
 Determine whether a native window is maximized .
 handle : int , the handle of a native window .
 Return bool ."""

implementation: return bool ( ctypes . windll . user32 . IsZoomed ( ctypes . c_void_p ( handle ) ) )


signature:
def IsWindowVisible ( handle : int ) -> bool :
    """IsWindowVisible from Win32.
 handle : int , the handle of a native window .
 Return bool ."""

implementation: return bool ( ctypes . windll . user32 . IsWindowVisible ( ctypes . c_void_p ( handle ) ) )


signature:
def ShowWindow ( handle : int , cmdShow : int ) -> bool :
    """ShowWindow from Win32.
 handle : int , the handle of a native window .
 cmdShow : int , a value in clas ` SW ` .
 Return bool , True if succeed otherwise False ."""

implementation: return ctypes . windll . user32 . ShowWindow ( ctypes . c_void_p ( handle ) , cmdShow )


signature:
def MoveWindow ( handle : int , x : int , y : int , width : int , height : int , repaint : int = 1 ) -> bool :
    """MoveWindow from Win32.
 handle : int , the handle of a native window .
 x : int .
 y : int .
 width : int .
 height : int .
 repaint : int , use 1 or 0.
 Return bool , True if succeed otherwise False ."""

implementation: return bool ( ctypes . windll . user32 . MoveWindow ( ctypes . c_void_p ( handle ) , x , y , width , height , repaint ) )


signature:
def SetWindowPos ( handle : int , hWndInsertAfter : int , x : int , y : int , width : int , height : int , flags : int ) -> bool :
    """SetWindowPos from Win32.
 handle : int , the handle of a native window .
 hWndInsertAfter : int , a value whose name starts with ' HWND ' in class SWP .
 x : int .
 y : int .
 width : int .
 height : int .
 flags : int , values whose name starts with ' SWP ' in class ` SWP ` .
 Return bool , True if succeed otherwise False ."""

implementation: return ctypes . windll . user32 . SetWindowPos ( ctypes . c_void_p ( handle ) , ctypes . c_void_p ( hWndInsertAfter ) , x , y , width , height , flags )


signature:
def SetWindowTopmost ( handle : int , isTopmost : bool ) -> bool :
    """handle : int , the handle of a native window .
 isTopmost : bool
 Return bool , True if succeed otherwise False ."""

implementation:
topValue = SWP . HWND_Topmost if isTopmost else SWP . HWND_NoTopmost
return bool ( SetWindowPos ( handle , topValue , 0 , 0 , 0 , 0 , SWP . SWP_NoSize | SWP . SWP_NoMove ) )


signature:
def GetWindowText ( handle : int ) -> str :
    """GetWindowText from Win32.
 handle : int , the handle of a native window .
 Return str ."""

implementation:
arrayType = ctypes . c_wchar * MAX_PATH
values = arrayType ( )
ctypes . windll . user32 . GetWindowTextW ( ctypes . c_void_p ( handle ) , values , MAX_PATH )
return values . value


signature:
def SetWindowText ( handle : int , text : str ) -> bool :
    """SetWindowText from Win32.
 handle : int , the handle of a native window .
 text : str .
 Return bool , True if succeed otherwise False ."""

implementation: return bool ( ctypes . windll . user32 . SetWindowTextW ( ctypes . c_void_p ( handle ) , ctypes . c_wchar_p ( text ) ) )


signature:
def GetEditText ( handle : int ) -> str :
    """Get text of a native Win32 Edit .
 handle : int , the handle of a native window .
 Return str ."""

implementation:
textLen = SendMessage ( handle , 0x000E , 0 , 0 ) + 1
# WM _ GETTEXTLENGTH
arrayType = ctypes . c_wchar * textLen
values = arrayType ( )
SendMessage ( handle , 0x000D , textLen , values )
# WM _ GETTEXT
return values . value


signature:
def GetConsoleOriginalTitle ( ) -> str :
    """GetConsoleOriginalTitle from Win32.
 Return str .
 Only available on Windows Vista or higher ."""

implementation:
if IsNT6orHigher :
    arrayType = ctypes . c_wchar * MAX_PATH
    values = arrayType ( )
    ctypes . windll . kernel32 . GetConsoleOriginalTitleW ( values , MAX_PATH )
    return values . value
else :
    raise RuntimeError ( 'GetConsoleOriginalTitle is not supported on Windows XP or lower.' )


signature:
def GetConsoleTitle ( ) -> str :
    """GetConsoleTitle from Win32.
 Return str ."""

implementation:
arrayType = ctypes . c_wchar * MAX_PATH
values = arrayType ( )
ctypes . windll . kernel32 . GetConsoleTitleW ( values , MAX_PATH )
return values . value


signature:
def SetConsoleTitle ( text : str ) -> bool :
    """SetConsoleTitle from Win32.
 text : str .
 Return bool , True if succeed otherwise False ."""

implementation: return bool ( ctypes . windll . kernel32 . SetConsoleTitleW ( ctypes . c_wchar_p ( text ) ) )


signature:
def IsDesktopLocked ( ) -> bool :
    """Check if desktop is locked .
 Return bool .
 Desktop is locked if press Win + L , Ctrl + Alt + Del or in remote desktop mode ."""

implementation:
isLocked = False
desk = ctypes . windll . user32 . OpenDesktopW ( ctypes . c_wchar_p ( 'Default' ) , 0 , 0 , 0x0100 )
# DESKTOP _ SWITCHDESKTOP = 0x0100
if desk :
    isLocked = not ctypes . windll . user32 . SwitchDesktop ( desk )
    ctypes . windll . user32 . CloseDesktop ( desk )
return isLocked


signature:
def PlayWaveFile ( filePath : str = r'C:\Windows\Media\notify.wav' , isAsync : bool = False , isLoop : bool = False ) -> bool :
    """Call PlaySound from Win32.
 filePath : str , if emtpy , stop playing the current sound .
 isAsync : bool , if True , the sound is played asynchronously and returns immediately .
 isLoop : bool , if True , the sound plays repeatedly until PlayWaveFile ( None ) is called again , must also set isAsync to True .
 Return bool , True if succeed otherwise False ."""

implementation:
if filePath :
    SND_ASYNC = 0x0001
    SND_NODEFAULT = 0x0002
    SND_LOOP = 0x0008
    SND_FILENAME = 0x20000
    flags = SND_NODEFAULT | SND_FILENAME
    if isAsync :
        flags |= SND_ASYNC
    if isLoop :
        flags |= SND_LOOP
        flags |= SND_ASYNC
    return bool ( ctypes . windll . winmm . PlaySoundW ( ctypes . c_wchar_p ( filePath ) , ctypes . c_void_p ( 0 ) , flags ) )
else :
    return bool ( ctypes . windll . winmm . PlaySoundW ( ctypes . c_wchar_p ( 0 ) , ctypes . c_void_p ( 0 ) , 0 ) )


signature:
def IsProcess64Bit ( processId : int ) -> bool :
    """Return True if process is 64 bit .
 Return False if process is 32 bit .
 Return None if unknown , maybe caused by having no acess right to the process ."""

implementation:
try :
    func = ctypes . windll . ntdll . ZwWow64ReadVirtualMemory64
    # only 64 bit OS has this function
except Exception as ex :
    return False
try :
    IsWow64Process = ctypes . windll . kernel32 . IsWow64Process
    IsWow64Process . argtypes = ( ctypes . c_void_p , ctypes . POINTER ( ctypes . c_int ) )
except Exception as ex :
    return False
hProcess = ctypes . windll . kernel32 . OpenProcess ( 0x1000 , 0 , processId )
# PROCESS _ QUERY _ INFORMATION = 0x0400 , PROCESS _ QUERY _ LIMITED _ INFORMATION = 0x1000
if hProcess :
    is64Bit = ctypes . c_int32 ( )
    if IsWow64Process ( hProcess , ctypes . byref ( is64Bit ) ) :
        ctypes . windll . kernel32 . CloseHandle ( ctypes . c_void_p ( hProcess ) )
        return False if is64Bit . value else True
    else :
        ctypes . windll . kernel32 . CloseHandle ( ctypes . c_void_p ( hProcess ) )


signature:
def RunScriptAsAdmin ( argv : list , workingDirectory : str = None , showFlag : int = SW . ShowNormal ) -> bool :
    """Run a python script as administrator .
 System will show a popup dialog askes you whether to elevate as administrator if UAC is enabled .
 argv : list , a str list like sys . argv , argv [ 0 ] is the script file , argv [ 1 : ] are other arguments .
 workingDirectory : str , the working directory for the script file .
 showFlag : int , a value in class ` SW ` .
 Return bool , True if succeed ."""

implementation:
args = ' ' . join ( '"{}"' . format ( arg ) for arg in argv )
return ctypes . windll . shell32 . ShellExecuteW ( None , "runas" , sys . executable , args , workingDirectory , showFlag ) > 32


signature:
def SendKey ( key : int , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate typing a key .
 key : int , a value in class ` Keys ` ."""

implementation:
keybd_event ( key , 0 , KeyboardEventFlag . KeyDown | KeyboardEventFlag . ExtendedKey , 0 )
keybd_event ( key , 0 , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey , 0 )
time . sleep ( waitTime )


signature:
def PressKey ( key : int , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate a key down for key .
 key : int , a value in class ` Keys ` .
 waitTime : float ."""

implementation:
keybd_event ( key , 0 , KeyboardEventFlag . KeyDown | KeyboardEventFlag . ExtendedKey , 0 )
time . sleep ( waitTime )


signature:
def ReleaseKey ( key : int , waitTime : float = OPERATION_WAIT_TIME ) -> None :
    """Simulate a key up for key .
 key : int , a value in class ` Keys ` .
 waitTime : float ."""

implementation:
keybd_event ( key , 0 , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey , 0 )
time . sleep ( waitTime )


signature:
def IsKeyPressed ( key : int ) -> bool :
    """key : int , a value in class ` Keys ` .
 Return bool ."""

implementation:
state = ctypes . windll . user32 . GetAsyncKeyState ( key )
return bool ( state & 0x8000 )


signature:
def _CreateInput ( structure ) -> INPUT :
    """Create Win32 struct ` INPUT ` for ` SendInput ` .
 Return ` INPUT ` ."""

implementation:
if isinstance ( structure , MOUSEINPUT ) :
    return INPUT ( InputType . Mouse , _INPUTUnion ( mi = structure ) )
if isinstance ( structure , KEYBDINPUT ) :
    return INPUT ( InputType . Keyboard , _INPUTUnion ( ki = structure ) )
if isinstance ( structure , HARDWAREINPUT ) :
    return INPUT ( InputType . Hardware , _INPUTUnion ( hi = structure ) )
raise TypeError ( 'Cannot create INPUT structure!' )


signature:
def MouseInput ( dx : int , dy : int , mouseData : int = 0 , dwFlags : int = MouseEventFlag . LeftDown , time_ : int = 0 ) -> INPUT :
    """Create Win32 struct ` MOUSEINPUT ` for ` SendInput ` .
 Return ` INPUT ` ."""

implementation: return _CreateInput ( MOUSEINPUT ( dx , dy , mouseData , dwFlags , time_ , None ) )


signature:
def KeyboardInput ( wVk : int , wScan : int , dwFlags : int = KeyboardEventFlag . KeyDown , time_ : int = 0 ) -> INPUT :
    """Create Win32 struct ` KEYBDINPUT ` for ` SendInput ` ."""

implementation: return _CreateInput ( KEYBDINPUT ( wVk , wScan , dwFlags , time_ , None ) )


signature:
def HardwareInput ( uMsg : int , param : int = 0 ) -> INPUT :
    """Create Win32 struct ` HARDWAREINPUT ` for ` SendInput ` ."""

implementation: return _CreateInput ( HARDWAREINPUT ( uMsg , param & 0xFFFF , param >> 16 & 0xFFFF ) )


signature:
def SendUnicodeChar ( char : str ) -> int :
    """Type a single unicode char .
 char : str , len ( char ) must equal to 1.
 Return int , the number of events that it successfully inserted into the keyboard or mouse input stream .
 If the function returns zero , the input was already blocked by another thread ."""

implementation: return SendInput ( KeyboardInput ( 0 , ord ( char ) , KeyboardEventFlag . KeyUnicode | KeyboardEventFlag . KeyDown ) , KeyboardInput ( 0 , ord ( char ) , KeyboardEventFlag . KeyUnicode | KeyboardEventFlag . KeyUp ) )


signature:
def _VKtoSC ( key : int ) -> int :
    """This function is only for internal use in SendKeys .
 key : int , a value in class ` Keys ` .
 Return int ."""

implementation:
if key in _SCKeys :
    return _SCKeys [ key ]
scanCode = ctypes . windll . user32 . MapVirtualKeyA ( key , 0 )
if not scanCode :
    return 0
keyList = [ Keys . VK_APPS , Keys . VK_CANCEL , Keys . VK_SNAPSHOT , Keys . VK_DIVIDE , Keys . VK_NUMLOCK ]
if key in keyList :
    scanCode |= 0x0100
return scanCode


signature:
def SendKeys ( text : str , interval : float = 0.01 , waitTime : float = OPERATION_WAIT_TIME , debug : bool = False ) -> None :
    """Simulate typing keys on keyboard .
 text : str , keys to type .
 interval : float , seconds between keys .
 waitTime : float .
 debug : bool , if True , print the keys .
 Examples :
 { Ctrl } , { Delete } . . . are special keys ' name in SpecialKeyNames .
 SendKeys ( ' { Ctrl } a { Delete } { Ctrl } v { Ctrl } s { Ctrl } { Shift } s { Win } e { PageDown } ' ) # press Ctrl + a , Delete , Ctrl + v , Ctrl + s , Ctrl + Shift + s , Win + e , PageDown
 SendKeys ( ' { Ctrl } ( AB ) ( { Shift } ( 123 ) ) ' ) # press Ctrl + A + B , type ( , press Shift + 1 + 2 + 3 , type ) , if ( ) follows a hold key , hold key won ' t release util )
 SendKeys ( ' { Ctrl } { a 3 } ' ) # press Ctrl + a at the same time , release Ctrl + a , then type a 2 times
 SendKeys ( ' { a 3 } { B 5 } ' ) # type a 3 times , type B 5 times
 SendKeys ( ' { { } Hello { } } abc { a } { b } { c } test { } 3 } { ! } { a } ( ) { ( } { ) } ' ) # type : { Hello } abc abc test } } } ! a ( ) ( )
 SendKeys ( ' 0123456789 { Enter } ' )
 SendKeys ( ' ABCDEFGHIJKLMNOPQRSTUVWXYZ { Enter } ' )
 SendKeys ( ' abcdefghijklmnopqrstuvwxyz { Enter } ' )
 SendKeys ( ' ` ~ ! @ # $ % ^ & * ( ) - _ = + { Enter } ' )
 SendKeys ( ' [ ] { { } { } } \\ | ; : \' \" , < . > / ? { Enter } ' )"""

implementation:
holdKeys = ( 'WIN' , 'LWIN' , 'RWIN' , 'SHIFT' , 'LSHIFT' , 'RSHIFT' , 'CTRL' , 'CONTROL' , 'LCTRL' , 'RCTRL' , 'LCONTROL' , 'LCONTROL' , 'ALT' , 'LALT' , 'RALT' )
keys = [ ]
printKeys = [ ]
i = 0
insertIndex = 0
length = len ( text )
hold = False
include = False
lastKeyValue = None
while True :
    if text [ i ] == '{' :
        rindex = text . find ( '}' , i )
        if rindex == i + 1 :
            rindex = text . find ( '}' , i + 2 )
        if rindex == - 1 :
            raise ValueError ( '"{" or "{}" is not valid, use "{{}" for "{", use "{}}" for "}"' )
        key = text [ i + 1 : rindex ]
        key = [ it for it in key . split ( ' ' ) if it ]
        if not key :
            raise ValueError ( '"{}" is not valid, use "{{Space}}" or " " for " "' . format ( text [ i : rindex + 1 ] ) )
        if ( len ( key ) == 2 and not key [ 1 ] . isdigit ( ) ) or len ( key ) > 2 :
            raise ValueError ( '"{}" is not valid' . format ( text [ i : rindex + 1 ] ) )
        upperKey = key [ 0 ] . upper ( )
        count = 1
        if len ( key ) > 1 :
            count = int ( key [ 1 ] )
        for j in range ( count ) :
            if hold :
                if upperKey in SpecialKeyNames :
                    keyValue = SpecialKeyNames [ upperKey ]
                    if type ( lastKeyValue ) == type ( keyValue ) and lastKeyValue == keyValue :
                        insertIndex += 1
                    printKeys . insert ( insertIndex , ( key [ 0 ] , 'KeyDown | ExtendedKey' ) )
                    printKeys . insert ( insertIndex + 1 , ( key [ 0 ] , 'KeyUp | ExtendedKey' ) )
                    keys . insert ( insertIndex , ( keyValue , KeyboardEventFlag . KeyDown | KeyboardEventFlag . ExtendedKey ) )
                    keys . insert ( insertIndex + 1 , ( keyValue , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey ) )
                    lastKeyValue = keyValue
                elif key [ 0 ] in CharacterCodes :
                    keyValue = CharacterCodes [ key [ 0 ] ]
                    if type ( lastKeyValue ) == type ( keyValue ) and lastKeyValue == keyValue :
                        insertIndex += 1
                    printKeys . insert ( insertIndex , ( key [ 0 ] , 'KeyDown | ExtendedKey' ) )
                    printKeys . insert ( insertIndex + 1 , ( key [ 0 ] , 'KeyUp | ExtendedKey' ) )
                    keys . insert ( insertIndex , ( keyValue , KeyboardEventFlag . KeyDown | KeyboardEventFlag . ExtendedKey ) )
                    keys . insert ( insertIndex + 1 , ( keyValue , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey ) )
                    lastKeyValue = keyValue
                else :
                    printKeys . insert ( insertIndex , ( key [ 0 ] , 'UnicodeChar' ) )
                    keys . insert ( insertIndex , ( key [ 0 ] , 'UnicodeChar' ) )
                    lastKeyValue = key [ 0 ]
                if include :
                    insertIndex += 1
                else :
                    if upperKey in holdKeys :
                        insertIndex += 1
                    else :
                        hold = False
            else :
                if upperKey in SpecialKeyNames :
                    keyValue = SpecialKeyNames [ upperKey ]
                    printKeys . append ( ( key [ 0 ] , 'KeyDown | ExtendedKey' ) )
                    printKeys . append ( ( key [ 0 ] , 'KeyUp | ExtendedKey' ) )
                    keys . append ( ( keyValue , KeyboardEventFlag . KeyDown | KeyboardEventFlag . ExtendedKey ) )
                    keys . append ( ( keyValue , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey ) )
                    lastKeyValue = keyValue
                    if upperKey in holdKeys :
                        hold = True
                        insertIndex = len ( keys ) - 1
                    else :
                        hold = False
                else :
                    printKeys . append ( ( key [ 0 ] , 'UnicodeChar' ) )
                    keys . append ( ( key [ 0 ] , 'UnicodeChar' ) )
                    lastKeyValue = key [ 0 ]
        i = rindex + 1
    elif text [ i ] == '(' :
        if hold :
            include = True
        else :
            printKeys . append ( ( text [ i ] , 'UnicodeChar' ) )
            keys . append ( ( text [ i ] , 'UnicodeChar' ) )
            lastKeyValue = text [ i ]
        i += 1
    elif text [ i ] == ')' :
        if hold :
            include = False
            hold = False
        else :
            printKeys . append ( ( text [ i ] , 'UnicodeChar' ) )
            keys . append ( ( text [ i ] , 'UnicodeChar' ) )
            lastKeyValue = text [ i ]
        i += 1
    else :
        if hold :
            if text [ i ] in CharacterCodes :
                keyValue = CharacterCodes [ text [ i ] ]
                if include and type ( lastKeyValue ) == type ( keyValue ) and lastKeyValue == keyValue :
                    insertIndex += 1
                printKeys . insert ( insertIndex , ( text [ i ] , 'KeyDown | ExtendedKey' ) )
                printKeys . insert ( insertIndex + 1 , ( text [ i ] , 'KeyUp | ExtendedKey' ) )
                keys . insert ( insertIndex , ( keyValue , KeyboardEventFlag . KeyDown | KeyboardEventFlag . ExtendedKey ) )
                keys . insert ( insertIndex + 1 , ( keyValue , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey ) )
                lastKeyValue = keyValue
            else :
                printKeys . append ( ( text [ i ] , 'UnicodeChar' ) )
                keys . append ( ( text [ i ] , 'UnicodeChar' ) )
                lastKeyValue = text [ i ]
            if include :
                insertIndex += 1
            else :
                hold = False
        else :
            printKeys . append ( ( text [ i ] , 'UnicodeChar' ) )
            keys . append ( ( text [ i ] , 'UnicodeChar' ) )
            lastKeyValue = text [ i ]
        i += 1
    if i >= length :
        break
hotkeyInterval = 0.01
for i , key in enumerate ( keys ) :
    if key [ 1 ] == 'UnicodeChar' :
        SendUnicodeChar ( key [ 0 ] )
        time . sleep ( interval )
        if debug :
            Logger . ColorfullyWrite ( '<Color=DarkGreen>{}</Color>, sleep({})\n' . format ( printKeys [ i ] , interval ) , writeToFile = False )
    else :
        scanCode = _VKtoSC ( key [ 0 ] )
        keybd_event ( key [ 0 ] , scanCode , key [ 1 ] , 0 )
        if debug :
            Logger . Write ( printKeys [ i ] , ConsoleColor . DarkGreen , writeToFile = False )
        if i + 1 == len ( keys ) :
            time . sleep ( interval )
            if debug :
                Logger . Write ( ', sleep({})\n' . format ( interval ) , writeToFile = False )
        else :
            if key [ 1 ] & KeyboardEventFlag . KeyUp :
                if keys [ i + 1 ] [ 1 ] == 'UnicodeChar' or keys [ i + 1 ] [ 1 ] & KeyboardEventFlag . KeyUp == 0 :
                    time . sleep ( interval )
                    if debug :
                        Logger . Write ( ', sleep({})\n' . format ( interval ) , writeToFile = False )
                else :
                    time . sleep ( hotkeyInterval )
                    # must sleep for a while , otherwise combined keys may not be caught
                    if debug :
                        Logger . Write ( ', sleep({})\n' . format ( hotkeyInterval ) , writeToFile = False )
            else : # KeyboardEventFlag . KeyDown
                time . sleep ( hotkeyInterval )
                if debug :
                    Logger . Write ( ', sleep({})\n' . format ( hotkeyInterval ) , writeToFile = False )
# make sure hold keys are not pressed
# win = ctypes . windll . user32 . GetAsyncKeyState ( Keys . VK _ LWIN )
# ctrl = ctypes . windll . user32 . GetAsyncKeyState ( Keys . VK _ CONTROL )
# alt = ctypes . windll . user32 . GetAsyncKeyState ( Keys . VK _ MENU )
# shift = ctypes . windll . user32 . GetAsyncKeyState ( Keys . VK _ SHIFT )
# if win & 0x8000:
# Logger . WriteLine ( ' ERROR : WIN is pressed , it should not be pressed ! ' , ConsoleColor . Red )
# keybd _ event ( Keys . VK _ LWIN , 0 , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey , 0)
# if ctrl & 0x8000:
# Logger . WriteLine ( ' ERROR : CTRL is pressed , it should not be pressed ! ' , ConsoleColor . Red )
# keybd _ event ( Keys . VK _ CONTROL , 0 , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey , 0)
# if alt & 0x8000:
# Logger . WriteLine ( ' ERROR : ALT is pressed , it should not be pressed ! ' , ConsoleColor . Red )
# keybd _ event ( Keys . VK _ MENU , 0 , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey , 0)
# if shift & 0x8000:
# Logger . WriteLine ( ' ERROR : SHIFT is pressed , it should not be pressed ! ' , ConsoleColor . Red )
# keybd _ event ( Keys . VK _ SHIFT , 0 , KeyboardEventFlag . KeyUp | KeyboardEventFlag . ExtendedKey , 0)
time . sleep ( waitTime )


signature:
def GetPatternIdInterface ( patternId : int ) :
    """Get pattern COM interface by pattern id .
 patternId : int , a value in class ` PatternId ` .
 Return comtypes . _ cominterface _ meta ."""

implementation:
global _PatternIdInterfaces
if not _PatternIdInterfaces :
    _PatternIdInterfaces = { # PatternId . AnnotationPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationAnnotationPattern ,
    # PatternId . CustomNavigationPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationCustomNavigationPattern ,
    PatternId . DockPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationDockPattern , # PatternId . DragPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationDragPattern ,
    # PatternId . DropTargetPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationDropTargetPattern ,
    PatternId . ExpandCollapsePattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationExpandCollapsePattern , PatternId . GridItemPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationGridItemPattern , PatternId . GridPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationGridPattern , PatternId . InvokePattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationInvokePattern , PatternId . ItemContainerPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationItemContainerPattern , PatternId . LegacyIAccessiblePattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationLegacyIAccessiblePattern , PatternId . MultipleViewPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationMultipleViewPattern , # PatternId . ObjectModelPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationObjectModelPattern ,
    PatternId . RangeValuePattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationRangeValuePattern , PatternId . ScrollItemPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationScrollItemPattern , PatternId . ScrollPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationScrollPattern , PatternId . SelectionItemPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationSelectionItemPattern , PatternId . SelectionPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationSelectionPattern , # PatternId . SpreadsheetItemPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationSpreadsheetItemPattern ,
    # PatternId . SpreadsheetPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationSpreadsheetPattern ,
    # PatternId . StylesPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationStylesPattern ,
    PatternId . SynchronizedInputPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationSynchronizedInputPattern , PatternId . TableItemPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTableItemPattern , PatternId . TablePattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTablePattern , # PatternId . TextChildPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTextChildPattern ,
    # PatternId . TextEditPattern : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTextEditPattern ,
    PatternId . TextPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTextPattern , # PatternId . TextPattern2 : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTextPattern2,
    PatternId . TogglePattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTogglePattern , PatternId . TransformPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTransformPattern , # PatternId . TransformPattern2 : _ AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTransformPattern2,
    PatternId . ValuePattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationValuePattern , PatternId . VirtualizedItemPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationVirtualizedItemPattern , PatternId . WindowPattern : _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationWindowPattern , }
    debug = False
    # the following patterns dosn ' t exist on Windows 7 or lower
    try :
        _PatternIdInterfaces [ PatternId . AnnotationPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationAnnotationPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have AnnotationPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . CustomNavigationPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationCustomNavigationPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have CustomNavigationPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . DragPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationDragPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have DragPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . DropTargetPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationDropTargetPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have DropTargetPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . ObjectModelPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationObjectModelPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have ObjectModelPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . SpreadsheetItemPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationSpreadsheetItemPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have SpreadsheetItemPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . SpreadsheetPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationSpreadsheetPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have SpreadsheetPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . StylesPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationStylesPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have StylesPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . TextChildPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTextChildPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have TextChildPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . TextEditPattern ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTextEditPattern
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have TextEditPattern.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . TextPattern2 ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTextPattern2
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have TextPattern2.' , ConsoleColor . Yellow )
    try :
        _PatternIdInterfaces [ PatternId . TransformPattern2 ] = _AutomationClient . instance ( ) . UIAutomationCore . IUIAutomationTransformPattern2
    except :
        if debug :
            Logger . WriteLine ( 'UIAutomationCore does not have TransformPattern2.' , ConsoleColor . Yellow )
return _PatternIdInterfaces [ patternId ]


signature:
def CreatePattern ( patternId : int , pattern : ctypes . POINTER ( comtypes . IUnknown ) ) :
    """Create a concreate pattern by pattern id and pattern ( POINTER ( IUnknown ) ) ."""

implementation:
subPattern = pattern . QueryInterface ( GetPatternIdInterface ( patternId ) )
if subPattern :
    return PatternConstructors [ patternId ] ( pattern = subPattern )


signature:
def WalkTree ( top , getChildren : Callable = None , getFirstChild : Callable = None , getNextSibling : Callable = None , yieldCondition : Callable = None , includeTop : bool = False , maxDepth : int = 0xFFFFFFFF ) :
    """Walk a tree not using recursive algorithm .
 top : a tree node .
 getChildren : function ( treeNode ) - > list .
 getNextSibling : function ( treeNode ) - > treeNode .
 getNextSibling : function ( treeNode ) - > treeNode .
 yieldCondition : function ( treeNode , depth ) - > bool .
 includeTop : bool , if True yield top first .
 maxDepth : int , enum depth .
 If getChildren is valid , ignore getFirstChild and getNextSibling ,
 yield 3 items tuple : ( treeNode , depth , remain children count in current depth ) .
 If getChildren is not valid , using getFirstChild and getNextSibling ,
 yield 2 items tuple : ( treeNode , depth ) .
 If yieldCondition is not None , only yield tree nodes that yieldCondition ( treeNode , depth ) - > bool returns True .
 For example :
 def GetDirChildren ( dir _ ) :
 if os . path . isdir ( dir _ ) :
 return [ os . path . join ( dir _ , it ) for it in os . listdir ( dir _ ) ]
 for it , depth , leftCount in WalkTree ( ' D : \\ ' , getChildren = GetDirChildren ) :
 print ( it , depth , leftCount )"""

implementation:
if maxDepth <= 0 :
    return
depth = 0
if getChildren :
    if includeTop :
        if not yieldCondition or yieldCondition ( top , 0 ) :
            yield top , 0 , 0
    children = getChildren ( top )
    childList = [ children ]
    while depth >= 0 : # or while childList :
        lastItems = childList [ - 1 ]
        if lastItems :
            if not yieldCondition or yieldCondition ( lastItems [ 0 ] , depth + 1 ) :
                yield lastItems [ 0 ] , depth + 1 , len ( lastItems ) - 1
            if depth + 1 < maxDepth :
                children = getChildren ( lastItems [ 0 ] )
                if children :
                    depth += 1
                    childList . append ( children )
            del lastItems [ 0 ]
        else :
            del childList [ depth ]
            depth -= 1
elif getFirstChild and getNextSibling :
    if includeTop :
        if not yieldCondition or yieldCondition ( top , 0 ) :
            yield top , 0
    child = getFirstChild ( top )
    childList = [ child ]
    while depth >= 0 : # or while childList :
        lastItem = childList [ - 1 ]
        if lastItem :
            if not yieldCondition or yieldCondition ( lastItem , depth + 1 ) :
                yield lastItem , depth + 1
            child = getNextSibling ( lastItem )
            childList [ depth ] = child
            if depth + 1 < maxDepth :
                child = getFirstChild ( lastItem )
                if child :
                    depth += 1
                    childList . append ( child )
        else :
            del childList [ depth ]
            depth -= 1


signature:
def ControlFromPoint ( x : int , y : int ) -> Control :
    """Call IUIAutomation ElementFromPoint x , y . May return None if mouse is over cmd ' s title bar icon .
 Return ` Control ` subclass or None ."""

implementation:
element = _AutomationClient . instance ( ) . IUIAutomation . ElementFromPoint ( ctypes . wintypes . POINT ( x , y ) )
return Control . CreateControlFromElement ( element )


signature:
def ControlFromPoint2 ( x : int , y : int ) -> Control :
    """Get a native handle from point x , y and call IUIAutomation . ElementFromHandle .
 Return ` Control ` subclass ."""

implementation: return Control . CreateControlFromElement ( _AutomationClient . instance ( ) . IUIAutomation . ElementFromHandle ( WindowFromPoint ( x , y ) ) )


signature:
def ControlFromHandle ( handle : int ) -> Control :
    """Call IUIAutomation . ElementFromHandle with a native handle .
 handle : int , a native window handle .
 Return ` Control ` subclass ."""

implementation: return Control . CreateControlFromElement ( _AutomationClient . instance ( ) . IUIAutomation . ElementFromHandle ( handle ) )


signature:
def ControlsAreSame ( control1 : Control , control2 : Control ) -> bool :
    """control1 : ` Control ` or its subclass .
 control2 : ` Control ` or its subclass .
 Return bool , True if control1 and control2 represent the same control otherwise False ."""

implementation: return bool ( _AutomationClient . instance ( ) . IUIAutomation . CompareElements ( control1 . Element , control2 . Element ) )


signature:
def WalkControl ( control : Control , includeTop : bool = False , maxDepth : int = 0xFFFFFFFF ) :
    """control : ` Control ` or its subclass .
 includeTop : bool , if True , yield ( control , 0 ) first .
 maxDepth : int , enum depth .
 Yield 2 items tuple ( control : Control , depth : int ) ."""

implementation:
if includeTop :
    yield control , 0
if maxDepth <= 0 :
    return
depth = 0
child = control . GetFirstChildControl ( )
controlList = [ child ]
while depth >= 0 :
    lastControl = controlList [ - 1 ]
    if lastControl :
        yield lastControl , depth + 1
        child = lastControl . GetNextSiblingControl ( )
        controlList [ depth ] = child
        if depth + 1 < maxDepth :
            child = lastControl . GetFirstChildControl ( )
            if child :
                depth += 1
                controlList . append ( child )
    else :
        del controlList [ depth ]
        depth -= 1


signature:
def LogControl ( control : Control , depth : int = 0 , showAllName : bool = True ) -> None :
    """Print and log control ' s properties .
 control : ` Control ` or its subclass .
 depth : int , current depth .
 showAllName : bool , if False , print the first 30 characters of control . Name ."""

implementation:
def getKeyName ( theDict , theValue ) :
    for key in theDict :
        if theValue == theDict [ key ] :
            return key
indent = ' ' * depth * 4
Logger . Write ( '{0}ControlType: ' . format ( indent ) )
Logger . Write ( control . ControlTypeName , ConsoleColor . DarkGreen )
Logger . Write ( '    ClassName: ' )
Logger . Write ( control . ClassName , ConsoleColor . DarkGreen )
Logger . Write ( '    AutomationId: ' )
Logger . Write ( control . AutomationId , ConsoleColor . DarkGreen )
Logger . Write ( '    Rect: ' )
Logger . Write ( control . BoundingRectangle , ConsoleColor . DarkGreen )
Logger . Write ( '    Name: ' )
Logger . Write ( control . Name , ConsoleColor . DarkGreen , printTruncateLen = 0 if showAllName else 30 )
Logger . Write ( '    Handle: ' )
Logger . Write ( '0x{0:X}({0})' . format ( control . NativeWindowHandle ) , ConsoleColor . DarkGreen )
Logger . Write ( '    Depth: ' )
Logger . Write ( depth , ConsoleColor . DarkGreen )
supportedPatterns = list ( filter ( lambda t : t [ 0 ] , ( ( control . GetPattern ( id_ ) , name ) for id_ , name in PatternIdNames . items ( ) ) ) )
for pt , name in supportedPatterns :
    if isinstance ( pt , ValuePattern ) :
        Logger . Write ( '    ValuePattern.Value: ' )
        Logger . Write ( pt . Value , ConsoleColor . DarkGreen , printTruncateLen = 0 if showAllName else 30 )
    elif isinstance ( pt , RangeValuePattern ) :
        Logger . Write ( '    RangeValuePattern.Value: ' )
        Logger . Write ( pt . Value , ConsoleColor . DarkGreen )
    elif isinstance ( pt , TogglePattern ) :
        Logger . Write ( '    TogglePattern.ToggleState: ' )
        Logger . Write ( 'ToggleState.' + getKeyName ( ToggleState . __dict__ , pt . ToggleState ) , ConsoleColor . DarkGreen )
    elif isinstance ( pt , SelectionItemPattern ) :
        Logger . Write ( '    SelectionItemPattern.IsSelected: ' )
        Logger . Write ( pt . IsSelected , ConsoleColor . DarkGreen )
    elif isinstance ( pt , ExpandCollapsePattern ) :
        Logger . Write ( '    ExpandCollapsePattern.ExpandCollapseState: ' )
        Logger . Write ( 'ExpandCollapseState.' + getKeyName ( ExpandCollapseState . __dict__ , pt . ExpandCollapseState ) , ConsoleColor . DarkGreen )
    elif isinstance ( pt , ScrollPattern ) :
        Logger . Write ( '    ScrollPattern.HorizontalScrollPercent: ' )
        Logger . Write ( pt . HorizontalScrollPercent , ConsoleColor . DarkGreen )
        Logger . Write ( '    ScrollPattern.VerticalScrollPercent: ' )
        Logger . Write ( pt . VerticalScrollPercent , ConsoleColor . DarkGreen )
    elif isinstance ( pt , GridPattern ) :
        Logger . Write ( '    GridPattern.RowCount: ' )
        Logger . Write ( pt . RowCount , ConsoleColor . DarkGreen )
        Logger . Write ( '    GridPattern.ColumnCount: ' )
        Logger . Write ( pt . ColumnCount , ConsoleColor . DarkGreen )
    elif isinstance ( pt , GridItemPattern ) :
        Logger . Write ( '    GridItemPattern.Row: ' )
        Logger . Write ( pt . Column , ConsoleColor . DarkGreen )
        Logger . Write ( '    GridItemPattern.Column: ' )
        Logger . Write ( pt . Column , ConsoleColor . DarkGreen )
    elif isinstance ( pt , TextPattern ) :
        Logger . Write ( '    TextPattern.Text: ' )
        Logger . Write ( pt . DocumentRange . GetText ( 30 ) , ConsoleColor . DarkGreen )
Logger . Write ( '    SupportedPattern:' )
for pt , name in supportedPatterns :
    Logger . Write ( ' ' + name , ConsoleColor . DarkGreen )
Logger . Write ( '\n' )


signature:
def EnumAndLogControl ( control : Control , maxDepth : int = 0xFFFFFFFF , showAllName : bool = True , startDepth : int = 0 ) -> None :
    """Print and log control and its descendants ' propertyies .
 control : ` Control ` or its subclass .
 maxDepth : int , enum depth .
 showAllName : bool , if False , print the first 30 characters of control . Name .
 startDepth : int , control ' s current depth ."""

implementation:
for c , d in WalkControl ( control , True , maxDepth ) :
    LogControl ( c , d + startDepth , showAllName )


signature:
def EnumAndLogControlAncestors ( control : Control , showAllName : bool = True ) -> None :
    """Print and log control and its ancestors ' propertyies .
 control : ` Control ` or its subclass .
 showAllName : bool , if False , print the first 30 characters of control . Name ."""

implementation:
lists = [ ]
while control :
    lists . insert ( 0 , control )
    control = control . GetParentControl ( )
for i , control in enumerate ( lists ) :
    LogControl ( control , i , showAllName )


signature:
def FindControl ( control : Control , compare : Callable , maxDepth : int = 0xFFFFFFFF , findFromSelf : bool = False , foundIndex : int = 1 ) -> Control :
    """control : ` Control ` or its subclass .
 compare : compare function with parameters ( control : Control , depth : int ) which returns bool .
 maxDepth : int , enum depth .
 findFromSelf : bool , if False , do not compare self .
 foundIndex : int , starts with 1 , > = 1.
 Return ` Control ` subclass or None if not find ."""

implementation:
foundCount = 0
if not control :
    control = GetRootControl ( )
traverseCount = 0
for child , depth in WalkControl ( control , findFromSelf , maxDepth ) :
    traverseCount += 1
    if compare ( child , depth ) :
        foundCount += 1
        if foundCount == foundIndex :
            child . traverseCount = traverseCount
            return child


signature:
def WaitHotKeyReleased ( hotkey : tuple ) -> None :
    """hotkey : tuple , two ints tuple ( modifierKey , key )"""

implementation:
mod = { ModifierKey . Alt : Keys . VK_MENU , ModifierKey . Control : Keys . VK_CONTROL , ModifierKey . Shift : Keys . VK_SHIFT , ModifierKey . Win : Keys . VK_LWIN }
while True :
    time . sleep ( 0.05 )
    if IsKeyPressed ( hotkey [ 1 ] ) :
        continue
    for k , v in mod . items ( ) :
        if k & hotkey [ 0 ] :
            if IsKeyPressed ( v ) :
                break
    else :
        break


signature:
def RunByHotKey ( keyFunctions : dict , stopHotKey : tuple = None , exitHotKey : tuple = ( ModifierKey . Control , Keys . VK_D ) , waitHotKeyReleased : bool = True ) -> None :
    """Bind functions with hotkeys , the function will be run or stopped in another thread when the hotkey is pressed .
 keyFunctions : hotkey function dict , like { ( uiautomation . ModifierKey . Control , uiautomation . Keys . VK _ 1 ) : func }
 stopHotKey : hotkey tuple
 exitHotKey : hotkey tuple
 waitHotKeyReleased : bool , if True , hotkey function will be triggered after the hotkey is released
 def main ( stopEvent ) :
 while True :
 if stopEvent . is _ set ( ) : # must check stopEvent . is _ set ( ) if you want to stop when stop hotkey is pressed
 break
 print ( n )
 n + = 1
 stopEvent . wait ( 1)
 print ( ' main exit ' )
 uiautomation . RunByHotKey ( { ( uiautomation . ModifierKey . Control , uiautomation . Keys . VK _ 1 ) : main }
 , ( uiautomation . ModifierKey . Control | uiautomation . ModifierKey . Shift , uiautomation . Keys . VK _ 2 ) )"""

implementation:
from threading import Thread , Event , currentThread
import traceback
def getModName ( theDict , theValue ) :
    name = ''
    for key in theDict :
        if isinstance ( theDict [ key ] , int ) and theValue & theDict [ key ] :
            if name :
                name += '|'
            name += key
    return name
def getKeyName ( theDict , theValue ) :
    for key in theDict :
        if theValue == theDict [ key ] :
            return key
def releaseAllKey ( ) :
    for key , value in Keys . __dict__ . items ( ) :
        if isinstance ( value , int ) and key . startswith ( 'VK' ) :
            if IsKeyPressed ( value ) :
                ReleaseKey ( value )
def threadFunc ( function , stopEvent , hotkey , hotkeyName ) :
    if waitHotKeyReleased :
        WaitHotKeyReleased ( hotkey )
    try :
        function ( stopEvent )
    except Exception as ex :
        Logger . ColorfullyWrite ( 'Catch an exception <Color=Red>{}</Color> in thread for hotkey <Color=DarkCyan>{}</Color>\n' . format ( ex . __class__ . __name__ , hotkeyName ) , writeToFile = False )
        print ( traceback . format_exc ( ) )
    finally :
        releaseAllKey ( )
        # need to release keys if some keys were pressed
        Logger . ColorfullyWrite ( '{} for function <Color=DarkCyan>{}</Color> exits, hotkey <Color=DarkCyan>{}</Color>\n' . format ( currentThread ( ) , function . __name__ , hotkeyName ) , ConsoleColor . DarkYellow , writeToFile = False )
stopHotKeyId = 1
exitHotKeyId = 2
hotKeyId = 3
registed = True
id2HotKey = { }
id2Function = { }
id2Thread = { }
id2Name = { }
for hotkey in keyFunctions :
    id2HotKey [ hotKeyId ] = hotkey
    id2Function [ hotKeyId ] = keyFunctions [ hotkey ]
    id2Thread [ hotKeyId ] = None
    modName = getModName ( ModifierKey . __dict__ , hotkey [ 0 ] )
    keyName = getKeyName ( Keys . __dict__ , hotkey [ 1 ] )
    id2Name [ hotKeyId ] = str ( ( modName , keyName ) )
    if ctypes . windll . user32 . RegisterHotKey ( 0 , hotKeyId , hotkey [ 0 ] , hotkey [ 1 ] ) :
        Logger . ColorfullyWrite ( 'Register hotkey <Color=DarkGreen>{}</Color> successfully\n' . format ( ( modName , keyName ) ) , writeToFile = False )
    else :
        registed = False
        Logger . ColorfullyWrite ( 'Register hotkey <Color=DarkGreen>{}</Color> unsuccessfully, maybe it was allready registered by another program\n' . format ( ( modName , keyName ) ) , writeToFile = False )
    hotKeyId += 1
if stopHotKey and len ( stopHotKey ) == 2 :
    modName = getModName ( ModifierKey . __dict__ , stopHotKey [ 0 ] )
    keyName = getKeyName ( Keys . __dict__ , stopHotKey [ 1 ] )
    if ctypes . windll . user32 . RegisterHotKey ( 0 , stopHotKeyId , stopHotKey [ 0 ] , stopHotKey [ 1 ] ) :
        Logger . ColorfullyWrite ( 'Register stop hotkey <Color=DarkYellow>{}</Color> successfully\n' . format ( ( modName , keyName ) ) , writeToFile = False )
    else :
        registed = False
        Logger . ColorfullyWrite ( 'Register stop hotkey <Color=DarkYellow>{}</Color> unsuccessfully, maybe it was allready registered by another program\n' . format ( ( modName , keyName ) ) , writeToFile = False )
if not registed :
    return
if exitHotKey and len ( exitHotKey ) == 2 :
    modName = getModName ( ModifierKey . __dict__ , exitHotKey [ 0 ] )
    keyName = getKeyName ( Keys . __dict__ , exitHotKey [ 1 ] )
    if ctypes . windll . user32 . RegisterHotKey ( 0 , exitHotKeyId , exitHotKey [ 0 ] , exitHotKey [ 1 ] ) :
        Logger . ColorfullyWrite ( 'Register exit hotkey <Color=DarkYellow>{}</Color> successfully\n' . format ( ( modName , keyName ) ) , writeToFile = False )
    else :
        Logger . ColorfullyWrite ( 'Register exit hotkey <Color=DarkYellow>{}</Color> unsuccessfully\n' . format ( ( modName , keyName ) ) , writeToFile = False )
funcThread = None
livingThreads = [ ]
stopEvent = Event ( )
msg = ctypes . wintypes . MSG ( )
while ctypes . windll . user32 . GetMessageW ( ctypes . byref ( msg ) , ctypes . c_void_p ( 0 ) , 0 , 0 ) != 0 :
    if msg . message == 0x0312 : # WM _ HOTKEY = 0x0312
        if msg . wParam in id2HotKey :
            if msg . lParam & 0x0000FFFF == id2HotKey [ msg . wParam ] [ 0 ] and msg . lParam >> 16 & 0x0000FFFF == id2HotKey [ msg . wParam ] [ 1 ] :
                Logger . ColorfullyWrite ( '----------hotkey <Color=DarkGreen>{}</Color> pressed----------\n' . format ( id2Name [ msg . wParam ] ) , writeToFile = False )
                if not id2Thread [ msg . wParam ] :
                    stopEvent . clear ( )
                    funcThread = Thread ( None , threadFunc , args = ( id2Function [ msg . wParam ] , stopEvent , id2HotKey [ msg . wParam ] , id2Name [ msg . wParam ] ) )
                    funcThread . start ( )
                    id2Thread [ msg . wParam ] = funcThread
                else :
                    if id2Thread [ msg . wParam ] . is_alive ( ) :
                        Logger . WriteLine ( 'There is a {} that is already running for hotkey {}' . format ( id2Thread [ msg . wParam ] , id2Name [ msg . wParam ] ) , ConsoleColor . Yellow , writeToFile = False )
                    else :
                        stopEvent . clear ( )
                        funcThread = Thread ( None , threadFunc , args = ( id2Function [ msg . wParam ] , stopEvent , id2HotKey [ msg . wParam ] , id2Name [ msg . wParam ] ) )
                        funcThread . start ( )
                        id2Thread [ msg . wParam ] = funcThread
        elif stopHotKeyId == msg . wParam :
            if msg . lParam & 0x0000FFFF == stopHotKey [ 0 ] and msg . lParam >> 16 & 0x0000FFFF == stopHotKey [ 1 ] :
                Logger . Write ( '----------stop hotkey pressed----------\n' , ConsoleColor . DarkYellow , writeToFile = False )
                stopEvent . set ( )
                for id_ in id2Thread :
                    if id2Thread [ id_ ] :
                        if id2Thread [ id_ ] . is_alive ( ) :
                            livingThreads . append ( ( id2Thread [ id_ ] , id2Name [ id_ ] ) )
                        id2Thread [ id_ ] = None
        elif exitHotKeyId == msg . wParam :
            if msg . lParam & 0x0000FFFF == exitHotKey [ 0 ] and msg . lParam >> 16 & 0x0000FFFF == exitHotKey [ 1 ] :
                Logger . Write ( 'Exit hotkey pressed. Exit\n' , ConsoleColor . DarkYellow , writeToFile = False )
                stopEvent . set ( )
                for id_ in id2Thread :
                    if id2Thread [ id_ ] :
                        if id2Thread [ id_ ] . is_alive ( ) :
                            livingThreads . append ( ( id2Thread [ id_ ] , id2Name [ id_ ] ) )
                        id2Thread [ id_ ] = None
                break
for thread , hotkeyName in livingThreads :
    if thread . is_alive ( ) :
        Logger . Write ( 'join {} triggered by hotkey {}\n' . format ( thread , hotkeyName ) , ConsoleColor . DarkYellow , writeToFile = False )
        thread . join ( 2 )
os . _exit ( 0 )


signature:
def Write ( log : Any , consoleColor : int = ConsoleColor . Default , writeToFile : bool = True , printToStdout : bool = True , logFile : str = None , printTruncateLen : int = 0 ) -> None :
    """log : any type .
 consoleColor : int , a value in class ` ConsoleColor ` , such as ` ConsoleColor . DarkGreen ` .
 writeToFile : bool .
 printToStdout : bool .
 logFile : str , log file path .
 printTruncateLen : int , if < = 0 , log is not truncated when print ."""

implementation:
if not isinstance ( log , str ) :
    log = str ( log )
if printToStdout and sys . stdout :
    isValidColor = ( consoleColor >= ConsoleColor . Black and consoleColor <= ConsoleColor . White )
    if isValidColor :
        SetConsoleColor ( consoleColor )
    try :
        if printTruncateLen > 0 and len ( log ) > printTruncateLen :
            sys . stdout . write ( log [ : printTruncateLen ] + '...' )
        else :
            sys . stdout . write ( log )
    except Exception as ex :
        SetConsoleColor ( ConsoleColor . Red )
        isValidColor = True
        sys . stdout . write ( ex . __class__ . __name__ + ': can\'t print the log!' )
        if log . endswith ( '\n' ) :
            sys . stdout . write ( '\n' )
    if isValidColor :
        ResetConsoleColor ( )
    sys . stdout . flush ( )
if not writeToFile :
    return
fileName = logFile if logFile else Logger . FileName
try :
    fout = open ( fileName , 'a+' , encoding = 'utf-8' )
    fout . write ( log )
except Exception as ex :
    if sys . stdout :
        sys . stdout . write ( ex . __class__ . __name__ + ': can\'t write the log!' )
finally :
    if fout :
        fout . close ( )


signature:
def WriteLine ( log : Any , consoleColor : int = - 1 , writeToFile : bool = True , printToStdout : bool = True , logFile : str = None ) -> None :
    """log : any type .
 consoleColor : int , a value in class ` ConsoleColor ` , such as ` ConsoleColor . DarkGreen ` .
 writeToFile : bool .
 printToStdout : bool .
 logFile : str , log file path ."""

implementation: Logger . Write ( '{}\n' . format ( log ) , consoleColor , writeToFile , printToStdout , logFile )


signature:
def ColorfullyWrite ( log : str , consoleColor : int = - 1 , writeToFile : bool = True , printToStdout : bool = True , logFile : str = None ) -> None :
    """log : str .
 consoleColor : int , a value in class ` ConsoleColor ` , such as ` ConsoleColor . DarkGreen ` .
 writeToFile : bool .
 printToStdout : bool .
 logFile : str , log file path .
 ColorfullyWrite ( ' Hello < Color = Green > Green < / Color > ! ! ! ' ) , color name must be in Logger . ColorNames ."""

implementation:
text = [ ]
start = 0
while True :
    index1 = log . find ( '<Color=' , start )
    if index1 >= 0 :
        if index1 > start :
            text . append ( ( log [ start : index1 ] , consoleColor ) )
        index2 = log . find ( '>' , index1 )
        colorName = log [ index1 + 7 : index2 ]
        index3 = log . find ( '</Color>' , index2 + 1 )
        text . append ( ( log [ index2 + 1 : index3 ] , Logger . ColorNames [ colorName ] ) )
        start = index3 + 8
    else :
        if start < len ( log ) :
            text . append ( ( log [ start : ] , consoleColor ) )
        break
for t , c in text :
    Logger . Write ( t , c , writeToFile , printToStdout , logFile )


signature:
def ColorfullyWriteLine ( log : str , consoleColor : int = - 1 , writeToFile : bool = True , printToStdout : bool = True , logFile : str = None ) -> None :
    """log : str .
 consoleColor : int , a value in class ` ConsoleColor ` , such as ` ConsoleColor . DarkGreen ` .
 writeToFile : bool .
 printToStdout : bool .
 logFile : str , log file path .
 ColorfullyWriteLine ( ' Hello < Color = Green > Green < / Color > ! ! ! ' ) , color name must be in Logger . ColorNames ."""

implementation: Logger . ColorfullyWrite ( log + '\n' , consoleColor , writeToFile , printToStdout , logFile )


signature:
def Log ( log : Any = '' , consoleColor : int = - 1 , writeToFile : bool = True , printToStdout : bool = True , logFile : str = None ) -> None :
    """log : any type .
 consoleColor : int , a value in class ` ConsoleColor ` , such as ` ConsoleColor . DarkGreen ` .
 writeToFile : bool .
 printToStdout : bool .
 logFile : str , log file path ."""

implementation:
t = datetime . datetime . now ( )
frame = sys . _getframe ( 1 )
log = '{}-{:02}-{:02} {:02}:{:02}:{:02}.{:03} Function: {}, Line: {} -> {}\n' . format ( t . year , t . month , t . day , t . hour , t . minute , t . second , t . microsecond // 1000 , frame . f_code . co_name , frame . f_lineno , log )
Logger . Write ( log , consoleColor , writeToFile , printToStdout , logFile )


signature:
def DeleteLog ( ) -> None :
    """Delete log file ."""

implementation:
if os . path . exists ( Logger . FileName ) :
    os . remove ( Logger . FileName )


signature:
def FromHandle ( self , hwnd : int , left : int = 0 , top : int = 0 , right : int = 0 , bottom : int = 0 ) -> bool :
    """Capture a native window to Bitmap by its handle .
 hwnd : int , the handle of a native window .
 left : int .
 top : int .
 right : int .
 bottom : int .
 left , top , right and bottom are control ' s internal postion ( from 0,0 ) .
 Return bool , True if succeed otherwise False ."""

implementation:
self . Release ( )
root = GetRootControl ( )
rect = ctypes . wintypes . RECT ( )
ctypes . windll . user32 . GetWindowRect ( hwnd , ctypes . byref ( rect ) )
left , top , right , bottom = left + rect . left , top + rect . top , right + rect . left , bottom + rect . top
self . _bitmap = _DllClient . instance ( ) . dll . BitmapFromWindow ( root . NativeWindowHandle , left , top , right , bottom )
self . _getsize ( )
return self . _bitmap > 0


signature:
def FromControl ( self , control : 'Control' , x : int = 0 , y : int = 0 , width : int = 0 , height : int = 0 ) -> bool :
    """Capture a control to Bitmap .
 control : ` Control ` or its subclass .
 x : int .
 y : int .
 width : int .
 height : int .
 x , y : the point in control ' s internal position ( from 0,0)
 width , height : image ' s width and height from x , y , use 0 for entire area ,
 If width ( or height ) < 0 , image size will be control ' s width ( or height ) - width ( or height ) .
 Return bool , True if succeed otherwise False ."""

implementation:
rect = control . BoundingRectangle
while rect . width ( ) == 0 or rect . height ( ) == 0 : # some controls maybe visible but their BoundingRectangle are all 0 , capture its parent util valid
    control = control . GetParentControl ( )
    if not control :
        return False
    rect = control . BoundingRectangle
if width <= 0 :
    width = rect . width ( ) + width
if height <= 0 :
    height = rect . height ( ) + height
handle = control . NativeWindowHandle
if handle :
    left = x
    top = y
    right = left + width
    bottom = top + height
else :
    while True :
        control = control . GetParentControl ( )
        handle = control . NativeWindowHandle
        if handle :
            pRect = control . BoundingRectangle
            left = rect . left - pRect . left + x
            top = rect . top - pRect . top + y
            right = left + width
            bottom = top + height
            break
return self . FromHandle ( handle , left , top , right , bottom )


signature:
def FromFile ( self , filePath : str ) -> bool :
    """Load image from a file .
 filePath : str .
 Return bool , True if succeed otherwise False ."""

implementation:
self . Release ( )
self . _bitmap = _DllClient . instance ( ) . dll . BitmapFromFile ( ctypes . c_wchar_p ( filePath ) )
self . _getsize ( )
return self . _bitmap > 0


signature:
def ToFile ( self , savePath : str ) -> bool :
    """Save to a file .
 savePath : str , should end with . bmp , . jpg , . jpeg , . png , . gif , . tif , . tiff .
 Return bool , True if succeed otherwise False ."""

implementation:
name , ext = os . path . splitext ( savePath )
extMap = { '.bmp' : 'image/bmp' , '.jpg' : 'image/jpeg' , '.jpeg' : 'image/jpeg' , '.gif' : 'image/gif' , '.tif' : 'image/tiff' , '.tiff' : 'image/tiff' , '.png' : 'image/png' }
gdiplusImageFormat = extMap . get ( ext . lower ( ) , 'image/png' )
return bool ( _DllClient . instance ( ) . dll . BitmapToFile ( self . _bitmap , ctypes . c_wchar_p ( savePath ) , ctypes . c_wchar_p ( gdiplusImageFormat ) ) )


signature:
def GetPixelColor ( self , x : int , y : int ) -> int :
    """Get color value of a pixel .
 x : int .
 y : int .
 Return int , argb color .
 b = argb & 0x0000FF
 g = ( argb & 0x00FF00 ) > > 8
 r = ( argb & 0xFF0000 ) > > 16
 a = ( argb & 0xFF0000 ) > > 24"""

implementation: return _DllClient . instance ( ) . dll . BitmapGetPixel ( self . _bitmap , x , y )


signature:
def SetPixelColor ( self , x : int , y : int , argb : int ) -> bool :
    """Set color value of a pixel .
 x : int .
 y : int .
 argb : int , color value .
 Return bool , True if succeed otherwise False ."""

implementation: return _DllClient . instance ( ) . dll . BitmapSetPixel ( self . _bitmap , x , y , argb )


signature:
def GetPixelColorsHorizontally ( self , x : int , y : int , count : int ) -> ctypes . Array :
    """x : int .
 y : int .
 count : int .
 Return ` ctypes . Array ` , an iterable array of int values in argb form point x , y horizontally ."""

implementation:
arrayType = ctypes . c_uint32 * count
values = arrayType ( )
_DllClient . instance ( ) . dll . BitmapGetPixelsHorizontally ( ctypes . c_size_t ( self . _bitmap ) , x , y , values , count )
return values


signature:
def SetPixelColorsHorizontally ( self , x : int , y : int , colors : Iterable ) -> bool :
    """Set pixel colors form x , y horizontally .
 x : int .
 y : int .
 colors : Iterable , an iterable list of int color values in argb .
 Return bool , True if succeed otherwise False ."""

implementation:
count = len ( colors )
arrayType = ctypes . c_uint32 * count
values = arrayType ( * colors )
return _DllClient . instance ( ) . dll . BitmapSetPixelsHorizontally ( ctypes . c_size_t ( self . _bitmap ) , x , y , values , count )


signature:
def GetPixelColorsVertically ( self , x : int , y : int , count : int ) -> ctypes . Array :
    """x : int .
 y : int .
 count : int .
 Return ` ctypes . Array ` , an iterable array of int values in argb form point x , y vertically ."""

implementation:
arrayType = ctypes . c_uint32 * count
values = arrayType ( )
_DllClient . instance ( ) . dll . BitmapGetPixelsVertically ( ctypes . c_size_t ( self . _bitmap ) , x , y , values , count )
return values


signature:
def GetPixelColorsOfRow ( self , y : int ) -> ctypes . Array :
    """y : int , row index .
 Return ` ctypes . Array ` , an iterable array of int values in argb of y row ."""

implementation: return self . GetPixelColorsOfRect ( 0 , y , self . Width , 1 )


signature:
def GetPixelColorsOfColumn ( self , x : int ) -> ctypes . Array :
    """x : int , column index .
 Return ` ctypes . Array ` , an iterable array of int values in argb of x column ."""

implementation: return self . GetPixelColorsOfRect ( x , 0 , 1 , self . Height )


signature:
def GetPixelColorsOfRect ( self , x : int , y : int , width : int , height : int ) -> ctypes . Array :
    """x : int .
 y : int .
 width : int .
 height : int .
 Return ` ctypes . Array ` , an iterable array of int values in argb of the input rect ."""

implementation:
arrayType = ctypes . c_uint32 * ( width * height )
values = arrayType ( )
_DllClient . instance ( ) . dll . BitmapGetPixelsOfRect ( ctypes . c_size_t ( self . _bitmap ) , x , y , width , height , values )
return values


signature:
def SetPixelColorsOfRect ( self , x : int , y : int , width : int , height : int , colors : Iterable ) -> bool :
    """x : int .
 y : int .
 width : int .
 height : int .
 colors : Iterable , an iterable list of int values , it ' s length must equal to width * height .
 Return ` ctypes . Array ` , an iterable array of int values in argb of the input rect ."""

implementation:
arrayType = ctypes . c_uint32 * ( width * height )
values = arrayType ( * colors )
return bool ( _DllClient . instance ( ) . dll . BitmapSetPixelsOfRect ( ctypes . c_size_t ( self . _bitmap ) , x , y , width , height , values ) )


signature:
def GetPixelColorsOfRects ( self , rects : list ) -> list :
    """rects : a list of rects , such as [ ( 0,0,10,10 ) , ( 10,10,20,20 ) , ( x , y , width , height ) ] .
 Return list , a list whose elements are ctypes . Array which is an iterable array of int values in argb ."""

implementation:
rects2 = [ ( x , y , x + width , y + height ) for x , y , width , height in rects ]
left , top , right , bottom = zip ( * rects2 )
left , top , right , bottom = min ( left ) , min ( top ) , max ( right ) , max ( bottom )
width , height = right - left , bottom - top
allColors = self . GetPixelColorsOfRect ( left , top , width , height )
colorsOfRects = [ ]
for x , y , w , h in rects :
    x -= left
    y -= top
    colors = [ ]
    for row in range ( h ) :
        colors . extend ( allColors [ ( y + row ) * width + x : ( y + row ) * width + x + w ] )
    colorsOfRects . append ( colors )
return colorsOfRects


signature:
def GetAllPixelColors ( self ) -> ctypes . Array :
    """Return ` ctypes . Array ` , an iterable array of int values in argb ."""

implementation: return self . GetPixelColorsOfRect ( 0 , 0 , self . Width , self . Height )


signature:
def GetSubBitmap ( self , x : int , y : int , width : int , height : int ) -> 'Bitmap' :
    """x : int .
 y : int .
 width : int .
 height : int .
 Return ` Bitmap ` , a sub bitmap of the input rect ."""

implementation:
colors = self . GetPixelColorsOfRect ( x , y , width , height )
bitmap = Bitmap ( width , height )
bitmap . SetPixelColorsOfRect ( 0 , 0 , width , height , colors )
return bitmap


signature:
def Navigate ( self , direction : int ) -> 'Control' :
    """Call IUIAutomationCustomNavigationPattern : : Navigate .
 Get the next control in the specified direction within the logical UI tree .
 direction : int , a value in class ` NavigateDirection ` .
 Return ` Control ` subclass or None .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationcustomnavigationpattern - navigate"""

implementation:
ele = self . pattern . Navigate ( direction )
return Control . CreateControlFromElement ( ele )


signature:
def SetDockPosition ( self , dockPosition : int , waitTime : float = OPERATION_WAIT_TIME ) -> int :
    """Call IUIAutomationDockPattern : : SetDockPosition .
 dockPosition : int , a value in class ` DockPosition ` .
 waitTime : float .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationdockpattern - setdockposition"""

implementation:
ret = self . pattern . SetDockPosition ( dockPosition )
time . sleep ( waitTime )
return ret


signature:
def GetGrabbedItems ( self ) -> list :
    """Call IUIAutomationDragPattern : : GetCurrentGrabbedItems .
 Return list , a list of ` Control ` subclasses that represent the full set of items
 that the user is dragging as part of a drag operation .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationdragpattern - getcurrentgrabbeditems"""

implementation:
eleArray = self . pattern . GetCurrentGrabbedItems ( )
if eleArray :
    controls = [ ]
    for i in range ( eleArray . Length ) :
        ele = eleArray . GetElement ( i )
        con = Control . CreateControlFromElement ( element = ele )
        if con :
            controls . append ( con )
    return controls
return [ ]


signature:
def Expand ( self , waitTime : float = OPERATION_WAIT_TIME ) -> bool :
    """Call IUIAutomationExpandCollapsePattern : : Expand .
 waitTime : float .
 Return bool , True if succeed otherwise False .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationexpandcollapsepattern - collapse"""

implementation:
ret = self . pattern . Expand ( ) == S_OK
time . sleep ( waitTime )
return ret


signature:
def FindItemByProperty ( control : 'Control' , propertyId : int , propertyValue ) -> 'Control' :
    """Call IUIAutomationItemContainerPattern : : FindItemByProperty .
 control : ` Control ` or its subclass .
 propertyValue : COM VARIANT according to propertyId ? todo .
 propertyId : int , a value in class ` PropertyId ` .
 Return ` Control ` subclass , a control within a containing element , based on a specified property value .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationitemcontainerpattern - finditembyproperty"""

implementation:
ele = self . pattern . FindItemByProperty ( control . Element , propertyId , propertyValue )
return Control . CreateControlFromElement ( ele )


signature:
def GetSelection ( self ) -> list :
    """Call IUIAutomationLegacyIAccessiblePattern : : GetCurrentSelection .
 Return list , a list of ` Control ` subclasses ,
 the Microsoft Active Accessibility property that identifies the selected children of this element .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationlegacyiaccessiblepattern - getcurrentselection"""

implementation:
eleArray = self . pattern . GetCurrentSelection ( )
if eleArray :
    controls = [ ]
    for i in range ( eleArray . Length ) :
        ele = eleArray . GetElement ( i )
        con = Control . CreateControlFromElement ( element = ele )
        if con :
            controls . append ( con )
    return controls
return [ ]


signature:
def SetValue ( self , value : str , waitTime : float = OPERATION_WAIT_TIME ) -> bool :
    """Call IUIAutomationLegacyIAccessiblePattern : : SetValue .
 Set the Microsoft Active Accessibility value property for the element .
 value : str .
 waitTime : float .
 Return bool , True if succeed otherwise False .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationlegacyiaccessiblepattern - setvalue"""

implementation:
ret = self . pattern . SetValue ( value ) == S_OK
time . sleep ( waitTime )
return ret


signature:
def SetView ( self , view : int ) -> bool :
    """Call IUIAutomationMultipleViewPattern : : SetCurrentView .
 Set the view of the control .
 view : int , the control - specific view identifier .
 Return bool , True if succeed otherwise False .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationmultipleviewpattern - getviewname"""

implementation: return self . pattern . SetCurrentView ( view ) == S_OK


signature:
def Scroll ( self , horizontalAmount : int , verticalAmount : int , waitTime : float = OPERATION_WAIT_TIME ) -> bool :
    """Call IUIAutomationScrollPattern : : Scroll .
 Scroll the visible region of the content area horizontally and vertically .
 horizontalAmount : int , a value in ScrollAmount .
 verticalAmount : int , a value in ScrollAmount .
 waitTime : float .
 Return bool , True if succeed otherwise False .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationscrollpattern - scroll"""

implementation:
ret = self . pattern . Scroll ( horizontalAmount , verticalAmount ) == S_OK
time . sleep ( waitTime )
return ret


signature:
def SetScrollPercent ( self , horizontalPercent : float , verticalPercent : float , waitTime : float = OPERATION_WAIT_TIME ) -> bool :
    """Call IUIAutomationScrollPattern : : SetScrollPercent .
 Set the horizontal and vertical scroll positions as a percentage of the total content area within the UI Automation element .
 horizontalPercent : float or int , a value in [ 0 , 100 ] or ScrollPattern . NoScrollValue ( - 1 ) if no scroll .
 verticalPercent : float or int , a value in [ 0 , 100 ] or ScrollPattern . NoScrollValue ( - 1 ) if no scroll .
 waitTime : float .
 Return bool , True if succeed otherwise False .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationscrollpattern - setscrollpercent"""

implementation:
ret = self . pattern . SetScrollPercent ( horizontalPercent , verticalPercent ) == S_OK
time . sleep ( waitTime )
return ret


signature:
def GetAnnotationObjects ( self ) -> list :
    """Call IUIAutomationSelectionPattern : : GetCurrentAnnotationObjects .
 Return list , a list of ` Control ` subclasses representing the annotations associated with this spreadsheet cell .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationspreadsheetitempattern - getcurrentannotationobjects"""

implementation:
eleArray = self . pattern . GetCurrentAnnotationObjects ( )
if eleArray :
    controls = [ ]
    for i in range ( eleArray . Length ) :
        ele = eleArray . GetElement ( i )
        con = Control . CreateControlFromElement ( element = ele )
        if con :
            controls . append ( con )
    return controls
return [ ]


signature:
def GetItemByName ( self , name : str ) -> 'Control' :
    """Call IUIAutomationSpreadsheetPattern : : GetItemByName .
 name : str .
 Return ` Control ` subclass or None , represents the spreadsheet cell that has the specified name . .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationspreadsheetpattern - getitembyname"""

implementation:
ele = self . pattern . GetItemByName ( name )
return Control . CreateControlFromElement ( element = ele )


signature:
def GetColumnHeaderItems ( self ) -> list :
    """Call IUIAutomationTableItemPattern : : GetCurrentColumnHeaderItems .
 Return list , a list of ` Control ` subclasses , the column headers associated with a table item or cell .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationtableitempattern - getcurrentcolumnheaderitems"""

implementation:
eleArray = self . pattern . GetCurrentColumnHeaderItems ( )
if eleArray :
    controls = [ ]
    for i in range ( eleArray . Length ) :
        ele = eleArray . GetElement ( i )
        con = Control . CreateControlFromElement ( element = ele )
        if con :
            controls . append ( con )
    return controls
return [ ]


signature:
def GetRowHeaderItems ( self ) -> list :
    """Call IUIAutomationTableItemPattern : : GetCurrentRowHeaderItems .
 Return list , a list of ` Control ` subclasses , the row headers associated with a table item or cell .
 Refer https : / / docs . microsoft . com / en - us / windows / desktop / api / uiautomationclient / nf - uiautomationclient - iuiautomationtableitempattern - getcurrentrowheaderitems"""

implementation:
eleArray = self . pattern . GetCurrentRowHeaderItems ( )
if eleArray :
    controls = [ ]
    for i in range ( eleArray . Length ) :
        ele = eleArray . GetElement ( i )
        con = Control . CreateControlFromElement ( element = ele )
        if con :
            controls . append ( con )
    return controls
return [ ]