windows-mcp 0.5.7__py3-none-any.whl → 0.5.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- windows_mcp/__main__.py +314 -312
- windows_mcp/analytics.py +175 -171
- windows_mcp/desktop/config.py +20 -20
- windows_mcp/desktop/service.py +457 -457
- windows_mcp/desktop/views.py +57 -57
- windows_mcp/tree/config.py +50 -50
- windows_mcp/tree/service.py +600 -466
- windows_mcp/tree/utils.py +21 -21
- windows_mcp/tree/views.py +115 -115
- windows_mcp/uia/__init__.py +4 -0
- windows_mcp/uia/controls.py +4781 -0
- windows_mcp/uia/core.py +3269 -0
- windows_mcp/uia/enums.py +1963 -0
- windows_mcp/uia/events.py +83 -0
- windows_mcp/uia/patterns.py +2106 -0
- windows_mcp/watchdog/__init__.py +1 -0
- windows_mcp/watchdog/event_handlers.py +51 -0
- windows_mcp/watchdog/service.py +188 -0
- {windows_mcp-0.5.7.dist-info → windows_mcp-0.5.8.dist-info}/METADATA +4 -4
- windows_mcp-0.5.8.dist-info/RECORD +26 -0
- windows_mcp-0.5.7.dist-info/RECORD +0 -17
- {windows_mcp-0.5.7.dist-info → windows_mcp-0.5.8.dist-info}/WHEEL +0 -0
- {windows_mcp-0.5.7.dist-info → windows_mcp-0.5.8.dist-info}/entry_points.txt +0 -0
- {windows_mcp-0.5.7.dist-info → windows_mcp-0.5.8.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -0,0 +1,4781 @@
|
|
|
1
|
+
'''
|
|
2
|
+
uiautomation for Python 3.
|
|
3
|
+
Author: yinkaisheng
|
|
4
|
+
Source: https://github.com/yinkaisheng/Python-UIAutomation-for-Windows
|
|
5
|
+
|
|
6
|
+
This module is for UIAutomation on Windows(Windows XP with SP3, Windows Vista and Windows 7/8/8.1/10).
|
|
7
|
+
It supports UIAutomation for the applications which implmented IUIAutomation, such as MFC, Windows Form, WPF, Modern UI(Metro UI), Qt, Firefox and Chrome.
|
|
8
|
+
Run 'automation.py -h' for help.
|
|
9
|
+
|
|
10
|
+
uiautomation is shared under the Apache Licene 2.0.
|
|
11
|
+
This means that the code can be freely copied and distributed, and costs nothing to use.
|
|
12
|
+
'''
|
|
13
|
+
|
|
14
|
+
import os
|
|
15
|
+
import sys
|
|
16
|
+
import time
|
|
17
|
+
import datetime
|
|
18
|
+
import re
|
|
19
|
+
import shlex
|
|
20
|
+
import struct
|
|
21
|
+
import atexit
|
|
22
|
+
import threading
|
|
23
|
+
import ctypes
|
|
24
|
+
import ctypes.wintypes
|
|
25
|
+
import comtypes
|
|
26
|
+
from io import TextIOWrapper
|
|
27
|
+
from typing import (Any, Callable, Dict, Generator, List, Tuple, Optional, Union, Sequence)
|
|
28
|
+
from .enums import *
|
|
29
|
+
from .core import *
|
|
30
|
+
from .core import _AutomationClient
|
|
31
|
+
from .patterns import *
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
METRO_WINDOW_CLASS_NAME = 'Windows.UI.Core.CoreWindow' # for Windows 8 and 8.1
|
|
35
|
+
SEARCH_INTERVAL = 0.5 # search control interval seconds
|
|
36
|
+
MAX_MOVE_SECOND = 1 # simulate mouse move or drag max seconds
|
|
37
|
+
TIME_OUT_SECOND = 10
|
|
38
|
+
OPERATION_WAIT_TIME = 0.5
|
|
39
|
+
MAX_PATH = 260
|
|
40
|
+
DEBUG_SEARCH_TIME = False
|
|
41
|
+
DEBUG_EXIST_DISAPPEAR = False
|
|
42
|
+
S_OK = 0
|
|
43
|
+
|
|
44
|
+
IsPy38OrHigher = sys.version_info[:2] >= (3, 8)
|
|
45
|
+
IsNT6orHigher = os.sys.getwindowsversion().major >= 6
|
|
46
|
+
CurrentProcessIs64Bit = sys.maxsize > 0xFFFFFFFF
|
|
47
|
+
ProcessTime = time.perf_counter # this returns nearly 0 when first call it if python version <= 3.6
|
|
48
|
+
ProcessTime() # need to call it once if python version <= 3.6
|
|
49
|
+
TreeNode = Any
|
|
50
|
+
|
|
51
|
+
class Control():
|
|
52
|
+
ValidKeys = set(['ControlType', 'ClassName', 'AutomationId', 'Name', 'SubName', 'RegexName', 'Depth', 'Compare'])
|
|
53
|
+
|
|
54
|
+
def __init__(self, searchFromControl: Optional['Control'] = None, searchDepth: int = 0xFFFFFFFF,
|
|
55
|
+
searchInterval: float = SEARCH_INTERVAL, foundIndex: int = 1, element=None,
|
|
56
|
+
ControlType: Optional[int] = None,
|
|
57
|
+
Name: Optional[str] = None,
|
|
58
|
+
SubName: Optional[str] = None,
|
|
59
|
+
RegexName: Optional[str] = None,
|
|
60
|
+
ClassName: Optional[str] = None,
|
|
61
|
+
AutomationId: Optional[str] = None,
|
|
62
|
+
Depth: Optional[int] = None,
|
|
63
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
64
|
+
**searchProperties):
|
|
65
|
+
"""
|
|
66
|
+
searchFromControl: `Control` or its subclass, if it is None, search from root control(Desktop).
|
|
67
|
+
searchDepth: int, max search depth from searchFromControl.
|
|
68
|
+
foundIndex: int, starts with 1, >= 1.
|
|
69
|
+
searchInterval: float, wait searchInterval after every search in self.Refind and self.Exists, the global timeout is TIME_OUT_SECOND.
|
|
70
|
+
element: `ctypes.POINTER(IUIAutomationElement)`, internal use only.
|
|
71
|
+
|
|
72
|
+
ControlType: int, a value in class `ControlType`.
|
|
73
|
+
Name: str.
|
|
74
|
+
SubName: str, a part str in Name.
|
|
75
|
+
RegexName: str, supports regex using re.match.
|
|
76
|
+
You can only use one of Name, SubName, RegexName.
|
|
77
|
+
ClassName: str.
|
|
78
|
+
AutomationId: str.
|
|
79
|
+
Depth: int, only search controls in relative depth from searchFromControl, ignore controls in depth(0~Depth-1),
|
|
80
|
+
if set, searchDepth will be set to Depth too.
|
|
81
|
+
Compare: Callable[[Control, int], bool], custom compare function(control: Control, depth: int) -> bool.
|
|
82
|
+
|
|
83
|
+
searchProperties, other properties specified for the control, only for debug log.
|
|
84
|
+
|
|
85
|
+
`Control` wraps IUIAutomationElement.
|
|
86
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nn-uiautomationclient-iuiautomationelement
|
|
87
|
+
"""
|
|
88
|
+
self._element = element
|
|
89
|
+
self._elementDirectAssign = True if element else False
|
|
90
|
+
self.searchFromControl = searchFromControl
|
|
91
|
+
self.searchDepth = Depth or searchDepth
|
|
92
|
+
self.searchInterval = searchInterval
|
|
93
|
+
self.foundIndex = foundIndex
|
|
94
|
+
self.searchProperties = searchProperties
|
|
95
|
+
if Name is not None:
|
|
96
|
+
searchProperties['Name'] = Name
|
|
97
|
+
if SubName is not None:
|
|
98
|
+
searchProperties['SubName'] = SubName
|
|
99
|
+
if RegexName is not None:
|
|
100
|
+
searchProperties['RegexName'] = RegexName
|
|
101
|
+
self.regexName = re.compile(RegexName)
|
|
102
|
+
else:
|
|
103
|
+
self.regexName = None
|
|
104
|
+
if ClassName is not None:
|
|
105
|
+
searchProperties['ClassName'] = ClassName
|
|
106
|
+
if AutomationId is not None:
|
|
107
|
+
searchProperties['AutomationId'] = AutomationId
|
|
108
|
+
if ControlType is not None:
|
|
109
|
+
searchProperties['ControlType'] = ControlType
|
|
110
|
+
if Depth is not None:
|
|
111
|
+
searchProperties['Depth'] = Depth
|
|
112
|
+
if Compare is not None:
|
|
113
|
+
searchProperties['Compare'] = Compare
|
|
114
|
+
self._supportedPatterns = {}
|
|
115
|
+
|
|
116
|
+
def __str__(self) -> str:
|
|
117
|
+
return 'ControlType: {0} ClassName: {1} AutomationId: {2} Rect: {3} Name: {4} Handle: 0x{5:X}({5})'.format(
|
|
118
|
+
self.ControlTypeName, self.ClassName, self.AutomationId, self.BoundingRectangle, self.Name, self.NativeWindowHandle)
|
|
119
|
+
|
|
120
|
+
def __repr__(self) -> str:
|
|
121
|
+
return '<{0} ClassName={1!r} AutomationId={2} Rect={3} Name={4!r} Handle=0x{5:X}({5})>'.format(
|
|
122
|
+
self.__class__.__name__, self.ClassName, self.AutomationId, self.BoundingRectangle, self.Name, self.NativeWindowHandle)
|
|
123
|
+
|
|
124
|
+
def __getitem__(self, pos: int) -> Optional['Control']:
|
|
125
|
+
if pos == 1:
|
|
126
|
+
return self.GetFirstChildControl()
|
|
127
|
+
elif pos == -1:
|
|
128
|
+
return self.GetLastChildControl()
|
|
129
|
+
elif pos > 1:
|
|
130
|
+
child = self.GetFirstChildControl()
|
|
131
|
+
for _ in range(pos - 1):
|
|
132
|
+
if child is None:
|
|
133
|
+
return None
|
|
134
|
+
child = child.GetNextSiblingControl()
|
|
135
|
+
return child
|
|
136
|
+
elif pos < -1:
|
|
137
|
+
child = self.GetLastChildControl()
|
|
138
|
+
for _ in range(-pos - 1):
|
|
139
|
+
if child is None:
|
|
140
|
+
return None
|
|
141
|
+
child = child.GetPreviousSiblingControl()
|
|
142
|
+
return child
|
|
143
|
+
else:
|
|
144
|
+
raise ValueError
|
|
145
|
+
|
|
146
|
+
@staticmethod
|
|
147
|
+
def CreateControlFromElement(element:'ctypes.POINTER(IUIAutomationElement)') -> Optional['Control']:
|
|
148
|
+
"""
|
|
149
|
+
Create a concreate `Control` from a com type `IUIAutomationElement`.
|
|
150
|
+
element: `ctypes.POINTER(IUIAutomationElement)`.
|
|
151
|
+
Return a subclass of `Control`, an instance of the control's real type.
|
|
152
|
+
"""
|
|
153
|
+
if element:
|
|
154
|
+
controlType = element.CurrentControlType
|
|
155
|
+
if controlType in ControlConstructors:
|
|
156
|
+
return ControlConstructors[controlType](element=element)
|
|
157
|
+
else:
|
|
158
|
+
Logger.WriteLine("element.CurrentControlType returns {}, invalid ControlType!".format(controlType), ConsoleColor.Red) # rarely happens
|
|
159
|
+
return None
|
|
160
|
+
|
|
161
|
+
@staticmethod
|
|
162
|
+
def CreateControlFromControl(control: 'Control') -> Optional['Control']:
|
|
163
|
+
"""
|
|
164
|
+
Create a concreate `Control` from a control instance, copy it.
|
|
165
|
+
control: `Control` or its subclass.
|
|
166
|
+
Return a subclass of `Control`, an instance of the control's real type.
|
|
167
|
+
For example: if control's ControlType is EditControl, return an EditControl.
|
|
168
|
+
"""
|
|
169
|
+
newControl = Control.CreateControlFromElement(control.Element)
|
|
170
|
+
return newControl
|
|
171
|
+
|
|
172
|
+
def SetSearchFromControl(self, searchFromControl: 'Control') -> None:
|
|
173
|
+
"""searchFromControl: `Control` or its subclass"""
|
|
174
|
+
self.searchFromControl = searchFromControl
|
|
175
|
+
|
|
176
|
+
def SetSearchDepth(self, searchDepth: int) -> None:
|
|
177
|
+
self.searchDepth = searchDepth
|
|
178
|
+
|
|
179
|
+
def AddSearchProperties(self, **searchProperties) -> None:
|
|
180
|
+
"""
|
|
181
|
+
Add search properties using `dict.update`.
|
|
182
|
+
searchProperties: dict, same as searchProperties in `Control.__init__`.
|
|
183
|
+
"""
|
|
184
|
+
self.searchProperties.update(searchProperties)
|
|
185
|
+
if 'Depth' in searchProperties:
|
|
186
|
+
self.searchDepth = searchProperties['Depth']
|
|
187
|
+
if 'RegexName' in searchProperties:
|
|
188
|
+
regName = searchProperties['RegexName']
|
|
189
|
+
self.regexName = re.compile(regName) if regName else None
|
|
190
|
+
|
|
191
|
+
def RemoveSearchProperties(self, **searchProperties) -> None:
|
|
192
|
+
"""
|
|
193
|
+
searchProperties: dict, same as searchProperties in `Control.__init__`.
|
|
194
|
+
"""
|
|
195
|
+
for key in searchProperties:
|
|
196
|
+
del self.searchProperties[key]
|
|
197
|
+
if key == 'RegexName':
|
|
198
|
+
self.regexName = None
|
|
199
|
+
|
|
200
|
+
def GetSearchPropertiesStr(self) -> str:
|
|
201
|
+
strs = ['{}: {}'.format(k, ControlTypeNames[v] if k == 'ControlType' else repr(v)) for k, v in self.searchProperties.items()]
|
|
202
|
+
return '{' + ', '.join(strs) + '}'
|
|
203
|
+
|
|
204
|
+
def GetColorfulSearchPropertiesStr(self, keyColor='DarkGreen', valueColor='DarkCyan') -> str:
|
|
205
|
+
"""keyColor, valueColor: str, color name in class ConsoleColor"""
|
|
206
|
+
strs = ['<Color={}>{}</Color>: <Color={}>{}</Color>'.format(keyColor if k in Control.ValidKeys else 'DarkYellow', k, valueColor,
|
|
207
|
+
ControlTypeNames[v] if k == 'ControlType' else repr(v)) for k, v in self.searchProperties.items()]
|
|
208
|
+
return '{' + ', '.join(strs) + '}'
|
|
209
|
+
|
|
210
|
+
def BuildUpdatedCache(self, cacheRequest: 'CacheRequest') -> 'Control':
|
|
211
|
+
"""
|
|
212
|
+
Retrieves a new UI Automation element with an updated cache.
|
|
213
|
+
cacheRequest: CacheRequest.
|
|
214
|
+
Return a subclass of `Control`, an instance of the control's real type.
|
|
215
|
+
"""
|
|
216
|
+
updatedElement = self.Element.BuildUpdatedCache(cacheRequest.check_request)
|
|
217
|
+
return Control.CreateControlFromElement(updatedElement)
|
|
218
|
+
|
|
219
|
+
@property
|
|
220
|
+
def CachedAcceleratorKey(self) -> str:
|
|
221
|
+
"""Get the cached accelerator key."""
|
|
222
|
+
return self.Element.CachedAcceleratorKey
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def CachedAccessKey(self) -> str:
|
|
226
|
+
"""Get the cached access key."""
|
|
227
|
+
return self.Element.CachedAccessKey
|
|
228
|
+
|
|
229
|
+
@property
|
|
230
|
+
def CachedAriaProperties(self) -> str:
|
|
231
|
+
"""Get the cached aria properties."""
|
|
232
|
+
return self.Element.CachedAriaProperties
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def CachedAriaRole(self) -> str:
|
|
236
|
+
"""Get the cached aria role."""
|
|
237
|
+
return self.Element.CachedAriaRole
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def CachedAutomationId(self) -> str:
|
|
241
|
+
"""Get the cached automation id."""
|
|
242
|
+
return self.Element.CachedAutomationId
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def CachedBoundingRectangle(self) -> Any:
|
|
246
|
+
"""Get the cached bounding rectangle."""
|
|
247
|
+
return self.Element.CachedBoundingRectangle
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def CachedClassName(self) -> str:
|
|
251
|
+
"""Get the cached class name."""
|
|
252
|
+
return self.Element.CachedClassName
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def CachedControlType(self) -> int:
|
|
256
|
+
"""Get the cached control type."""
|
|
257
|
+
return self.Element.CachedControlType
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def CachedControllerFor(self) -> Any:
|
|
261
|
+
"""Get the cached controller for."""
|
|
262
|
+
return self.Element.CachedControllerFor
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def CachedCulture(self) -> int:
|
|
266
|
+
"""Get the cached culture."""
|
|
267
|
+
return self.Element.CachedCulture
|
|
268
|
+
|
|
269
|
+
@property
|
|
270
|
+
def CachedDescribedBy(self) -> Any:
|
|
271
|
+
"""Get the cached described by."""
|
|
272
|
+
return self.Element.CachedDescribedBy
|
|
273
|
+
|
|
274
|
+
@property
|
|
275
|
+
def CachedFlowsTo(self) -> Any:
|
|
276
|
+
"""Get the cached flows to."""
|
|
277
|
+
return self.Element.CachedFlowsTo
|
|
278
|
+
|
|
279
|
+
@property
|
|
280
|
+
def CachedFrameworkId(self) -> str:
|
|
281
|
+
"""Get the cached framework id."""
|
|
282
|
+
return self.Element.CachedFrameworkId
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def CachedHasKeyboardFocus(self) -> bool:
|
|
286
|
+
"""Get the cached has keyboard focus."""
|
|
287
|
+
return self.Element.CachedHasKeyboardFocus
|
|
288
|
+
|
|
289
|
+
@property
|
|
290
|
+
def CachedHelpText(self) -> str:
|
|
291
|
+
"""Get the cached help text."""
|
|
292
|
+
return self.Element.CachedHelpText
|
|
293
|
+
|
|
294
|
+
@property
|
|
295
|
+
def CachedIsContentElement(self) -> bool:
|
|
296
|
+
"""Get the cached is content element."""
|
|
297
|
+
return self.Element.CachedIsContentElement
|
|
298
|
+
|
|
299
|
+
@property
|
|
300
|
+
def CachedIsControlElement(self) -> bool:
|
|
301
|
+
"""Get the cached is control element."""
|
|
302
|
+
return self.Element.CachedIsControlElement
|
|
303
|
+
|
|
304
|
+
@property
|
|
305
|
+
def CachedIsDataValidForForm(self) -> bool:
|
|
306
|
+
"""Get the cached is data valid for form."""
|
|
307
|
+
return self.Element.CachedIsDataValidForForm
|
|
308
|
+
|
|
309
|
+
@property
|
|
310
|
+
def CachedIsEnabled(self) -> bool:
|
|
311
|
+
"""Get the cached is enabled."""
|
|
312
|
+
return self.Element.CachedIsEnabled
|
|
313
|
+
|
|
314
|
+
@property
|
|
315
|
+
def CachedIsKeyboardFocusable(self) -> bool:
|
|
316
|
+
"""Get the cached is keyboard focusable."""
|
|
317
|
+
return self.Element.CachedIsKeyboardFocusable
|
|
318
|
+
|
|
319
|
+
@property
|
|
320
|
+
def CachedIsOffscreen(self) -> bool:
|
|
321
|
+
"""Get the cached is offscreen."""
|
|
322
|
+
return self.Element.CachedIsOffscreen
|
|
323
|
+
|
|
324
|
+
@property
|
|
325
|
+
def CachedIsPassword(self) -> bool:
|
|
326
|
+
"""Get the cached is password."""
|
|
327
|
+
return self.Element.CachedIsPassword
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def CachedIsRequiredForForm(self) -> bool:
|
|
331
|
+
"""Get the cached is required for form."""
|
|
332
|
+
return self.Element.CachedIsRequiredForForm
|
|
333
|
+
|
|
334
|
+
@property
|
|
335
|
+
def CachedItemStatus(self) -> str:
|
|
336
|
+
"""Get the cached item status."""
|
|
337
|
+
return self.Element.CachedItemStatus
|
|
338
|
+
|
|
339
|
+
@property
|
|
340
|
+
def CachedItemType(self) -> str:
|
|
341
|
+
"""Get the cached item type."""
|
|
342
|
+
return self.Element.CachedItemType
|
|
343
|
+
|
|
344
|
+
@property
|
|
345
|
+
def CachedLabeledBy(self) -> Any:
|
|
346
|
+
"""Get the cached labeled by."""
|
|
347
|
+
return self.Element.CachedLabeledBy
|
|
348
|
+
|
|
349
|
+
@property
|
|
350
|
+
def CachedLocalizedControlType(self) -> str:
|
|
351
|
+
"""Get the cached localized control type."""
|
|
352
|
+
return self.Element.CachedLocalizedControlType
|
|
353
|
+
|
|
354
|
+
@property
|
|
355
|
+
def CachedName(self) -> str:
|
|
356
|
+
"""Get the cached name."""
|
|
357
|
+
return self.Element.CachedName
|
|
358
|
+
|
|
359
|
+
@property
|
|
360
|
+
def CachedNativeWindowHandle(self) -> int:
|
|
361
|
+
"""Get the cached native window handle."""
|
|
362
|
+
return self.Element.CachedNativeWindowHandle
|
|
363
|
+
|
|
364
|
+
@property
|
|
365
|
+
def CachedOrientation(self) -> int:
|
|
366
|
+
"""Get the cached orientation."""
|
|
367
|
+
return self.Element.CachedOrientation
|
|
368
|
+
|
|
369
|
+
@property
|
|
370
|
+
def CachedProcessId(self) -> int:
|
|
371
|
+
"""Get the cached process id."""
|
|
372
|
+
return self.Element.CachedProcessId
|
|
373
|
+
|
|
374
|
+
@property
|
|
375
|
+
def CachedProviderDescription(self) -> str:
|
|
376
|
+
"""Get the cached provider description."""
|
|
377
|
+
return self.Element.CachedProviderDescription
|
|
378
|
+
|
|
379
|
+
@property
|
|
380
|
+
def AcceleratorKey(self) -> str:
|
|
381
|
+
"""
|
|
382
|
+
Property AcceleratorKey.
|
|
383
|
+
Call IUIAutomationElement::get_CurrentAcceleratorKey.
|
|
384
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentacceleratorkey
|
|
385
|
+
"""
|
|
386
|
+
return self.Element.CurrentAcceleratorKey
|
|
387
|
+
|
|
388
|
+
@property
|
|
389
|
+
def AccessKey(self) -> str:
|
|
390
|
+
"""
|
|
391
|
+
Property AccessKey.
|
|
392
|
+
Call IUIAutomationElement::get_CurrentAccessKey.
|
|
393
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentaccesskey
|
|
394
|
+
"""
|
|
395
|
+
return self.Element.CurrentAccessKey
|
|
396
|
+
|
|
397
|
+
@property
|
|
398
|
+
def AriaProperties(self) -> str:
|
|
399
|
+
"""
|
|
400
|
+
Property AriaProperties.
|
|
401
|
+
Call IUIAutomationElement::get_CurrentAriaProperties.
|
|
402
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentariaproperties
|
|
403
|
+
"""
|
|
404
|
+
return self.Element.CurrentAriaProperties
|
|
405
|
+
|
|
406
|
+
@property
|
|
407
|
+
def AriaRole(self) -> str:
|
|
408
|
+
"""
|
|
409
|
+
Property AriaRole.
|
|
410
|
+
Call IUIAutomationElement::get_CurrentAriaRole.
|
|
411
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentariarole
|
|
412
|
+
"""
|
|
413
|
+
return self.Element.CurrentAriaRole
|
|
414
|
+
|
|
415
|
+
@property
|
|
416
|
+
def AutomationId(self) -> str:
|
|
417
|
+
"""
|
|
418
|
+
Property AutomationId.
|
|
419
|
+
Call IUIAutomationElement::get_CurrentAutomationId.
|
|
420
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentautomationid
|
|
421
|
+
"""
|
|
422
|
+
return self.Element.CurrentAutomationId
|
|
423
|
+
|
|
424
|
+
@property
|
|
425
|
+
def BoundingRectangle(self) -> Rect:
|
|
426
|
+
"""
|
|
427
|
+
Property BoundingRectangle.
|
|
428
|
+
Call IUIAutomationElement::get_CurrentBoundingRectangle.
|
|
429
|
+
Return `Rect`.
|
|
430
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentboundingrectangle
|
|
431
|
+
|
|
432
|
+
rect = control.BoundingRectangle
|
|
433
|
+
print(rect.left, rect.top, rect.right, rect.bottom, rect.width(), rect.height(), rect.xcenter(), rect.ycenter())
|
|
434
|
+
"""
|
|
435
|
+
rect = self.Element.CurrentBoundingRectangle
|
|
436
|
+
return Rect(rect.left, rect.top, rect.right, rect.bottom)
|
|
437
|
+
|
|
438
|
+
@property
|
|
439
|
+
def ClassName(self) -> str:
|
|
440
|
+
"""
|
|
441
|
+
Property ClassName.
|
|
442
|
+
Call IUIAutomationElement::get_CurrentClassName.
|
|
443
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentclassname
|
|
444
|
+
"""
|
|
445
|
+
return self.Element.CurrentClassName
|
|
446
|
+
|
|
447
|
+
@property
|
|
448
|
+
def ControlType(self) -> int:
|
|
449
|
+
"""
|
|
450
|
+
Property ControlType.
|
|
451
|
+
Return int, a value in class `ControlType`.
|
|
452
|
+
Call IUIAutomationElement::get_CurrentControlType.
|
|
453
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentcontroltype
|
|
454
|
+
"""
|
|
455
|
+
return self.Element.CurrentControlType
|
|
456
|
+
|
|
457
|
+
# @property
|
|
458
|
+
# def ControllerFor(self):
|
|
459
|
+
# return self.Element.CurrentControllerFor
|
|
460
|
+
|
|
461
|
+
@property
|
|
462
|
+
def Culture(self) -> int:
|
|
463
|
+
"""
|
|
464
|
+
Property Culture.
|
|
465
|
+
Call IUIAutomationElement::get_CurrentCulture.
|
|
466
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentculture
|
|
467
|
+
"""
|
|
468
|
+
return self.Element.CurrentCulture
|
|
469
|
+
|
|
470
|
+
# @property
|
|
471
|
+
# def DescribedBy(self):
|
|
472
|
+
# return self.Element.CurrentDescribedBy
|
|
473
|
+
|
|
474
|
+
# @property
|
|
475
|
+
# def FlowsTo(self):
|
|
476
|
+
# return self.Element.CurrentFlowsTo
|
|
477
|
+
|
|
478
|
+
@property
|
|
479
|
+
def FrameworkId(self) -> str:
|
|
480
|
+
"""
|
|
481
|
+
Property FrameworkId.
|
|
482
|
+
Call IUIAutomationElement::get_CurrentFrameworkId.
|
|
483
|
+
Return str, such as Win32, WPF...
|
|
484
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentframeworkid
|
|
485
|
+
"""
|
|
486
|
+
return self.Element.CurrentFrameworkId
|
|
487
|
+
|
|
488
|
+
@property
|
|
489
|
+
def HasKeyboardFocus(self) -> bool:
|
|
490
|
+
"""
|
|
491
|
+
Property HasKeyboardFocus.
|
|
492
|
+
Call IUIAutomationElement::get_CurrentHasKeyboardFocus.
|
|
493
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currenthaskeyboardfocus
|
|
494
|
+
"""
|
|
495
|
+
return bool(self.Element.CurrentHasKeyboardFocus)
|
|
496
|
+
|
|
497
|
+
@property
|
|
498
|
+
def HelpText(self) -> str:
|
|
499
|
+
"""
|
|
500
|
+
Property HelpText.
|
|
501
|
+
Call IUIAutomationElement::get_CurrentHelpText.
|
|
502
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currenthelptext
|
|
503
|
+
"""
|
|
504
|
+
return self.Element.CurrentHelpText
|
|
505
|
+
|
|
506
|
+
@property
|
|
507
|
+
def IsContentElement(self) -> bool:
|
|
508
|
+
"""
|
|
509
|
+
Property IsContentElement.
|
|
510
|
+
Call IUIAutomationElement::get_CurrentIsContentElement.
|
|
511
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentiscontentelement
|
|
512
|
+
"""
|
|
513
|
+
return bool(self.Element.CurrentIsContentElement)
|
|
514
|
+
|
|
515
|
+
@property
|
|
516
|
+
def IsControlElement(self) -> bool:
|
|
517
|
+
"""
|
|
518
|
+
Property IsControlElement.
|
|
519
|
+
Call IUIAutomationElement::get_CurrentIsControlElement.
|
|
520
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentiscontrolelement
|
|
521
|
+
"""
|
|
522
|
+
return bool(self.Element.CurrentIsControlElement)
|
|
523
|
+
|
|
524
|
+
@property
|
|
525
|
+
def IsDataValidForForm(self) -> bool:
|
|
526
|
+
"""
|
|
527
|
+
Property IsDataValidForForm.
|
|
528
|
+
Call IUIAutomationElement::get_CurrentIsDataValidForForm.
|
|
529
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentisdatavalidforform
|
|
530
|
+
"""
|
|
531
|
+
return bool(self.Element.CurrentIsDataValidForForm)
|
|
532
|
+
|
|
533
|
+
@property
|
|
534
|
+
def IsEnabled(self) -> bool:
|
|
535
|
+
"""
|
|
536
|
+
Property IsEnabled.
|
|
537
|
+
Call IUIAutomationElement::get_CurrentIsEnabled.
|
|
538
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentisenabled
|
|
539
|
+
"""
|
|
540
|
+
return bool(self.Element.CurrentIsEnabled)
|
|
541
|
+
|
|
542
|
+
@property
|
|
543
|
+
def IsKeyboardFocusable(self) -> bool:
|
|
544
|
+
"""
|
|
545
|
+
Property IsKeyboardFocusable.
|
|
546
|
+
Call IUIAutomationElement::get_CurrentIsKeyboardFocusable.
|
|
547
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentiskeyboardfocusable
|
|
548
|
+
"""
|
|
549
|
+
return bool(self.Element.CurrentIsKeyboardFocusable)
|
|
550
|
+
|
|
551
|
+
@property
|
|
552
|
+
def IsOffscreen(self) -> bool:
|
|
553
|
+
"""
|
|
554
|
+
Property IsOffscreen.
|
|
555
|
+
Call IUIAutomationElement::get_CurrentIsOffscreen.
|
|
556
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentisoffscreen
|
|
557
|
+
"""
|
|
558
|
+
return bool(self.Element.CurrentIsOffscreen)
|
|
559
|
+
|
|
560
|
+
@property
|
|
561
|
+
def IsPassword(self) -> bool:
|
|
562
|
+
"""
|
|
563
|
+
Property IsPassword.
|
|
564
|
+
Call IUIAutomationElement::get_CurrentIsPassword.
|
|
565
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentispassword
|
|
566
|
+
"""
|
|
567
|
+
return bool(self.Element.CurrentIsPassword)
|
|
568
|
+
|
|
569
|
+
@property
|
|
570
|
+
def IsRequiredForForm(self) -> bool:
|
|
571
|
+
"""
|
|
572
|
+
Property IsRequiredForForm.
|
|
573
|
+
Call IUIAutomationElement::get_CurrentIsRequiredForForm.
|
|
574
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentisrequiredforform
|
|
575
|
+
"""
|
|
576
|
+
return bool(self.Element.CurrentIsRequiredForForm)
|
|
577
|
+
|
|
578
|
+
@property
|
|
579
|
+
def ItemStatus(self) -> str:
|
|
580
|
+
"""
|
|
581
|
+
Property ItemStatus.
|
|
582
|
+
Call IUIAutomationElement::get_CurrentItemStatus.
|
|
583
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentitemstatus
|
|
584
|
+
"""
|
|
585
|
+
return self.Element.CurrentItemStatus
|
|
586
|
+
|
|
587
|
+
@property
|
|
588
|
+
def ItemType(self) -> str:
|
|
589
|
+
"""
|
|
590
|
+
Property ItemType.
|
|
591
|
+
Call IUIAutomationElement::get_CurrentItemType.
|
|
592
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentitemtype
|
|
593
|
+
"""
|
|
594
|
+
return self.Element.CurrentItemType
|
|
595
|
+
|
|
596
|
+
# @property
|
|
597
|
+
# def LabeledBy(self):
|
|
598
|
+
# return self.Element.CurrentLabeledBy
|
|
599
|
+
|
|
600
|
+
@property
|
|
601
|
+
def LocalizedControlType(self) -> str:
|
|
602
|
+
"""
|
|
603
|
+
Property LocalizedControlType.
|
|
604
|
+
Call IUIAutomationElement::get_CurrentLocalizedControlType.
|
|
605
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentlocalizedcontroltype
|
|
606
|
+
"""
|
|
607
|
+
return self.Element.CurrentLocalizedControlType
|
|
608
|
+
|
|
609
|
+
@property
|
|
610
|
+
def Name(self) -> str:
|
|
611
|
+
"""
|
|
612
|
+
Property Name.
|
|
613
|
+
Call IUIAutomationElement::get_CurrentName.
|
|
614
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentname
|
|
615
|
+
"""
|
|
616
|
+
return self.Element.CurrentName or '' # CurrentName may be None
|
|
617
|
+
|
|
618
|
+
@property
|
|
619
|
+
def NativeWindowHandle(self) -> int:
|
|
620
|
+
"""
|
|
621
|
+
Property NativeWindowHandle.
|
|
622
|
+
Call IUIAutomationElement::get_CurrentNativeWindowHandle.
|
|
623
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentnativewindowhandle
|
|
624
|
+
"""
|
|
625
|
+
try:
|
|
626
|
+
handle = self.Element.CurrentNativeWindowHandle
|
|
627
|
+
except comtypes.COMError as ex:
|
|
628
|
+
return 0
|
|
629
|
+
return 0 if handle is None else handle
|
|
630
|
+
|
|
631
|
+
@property
|
|
632
|
+
def Orientation(self) -> int:
|
|
633
|
+
"""
|
|
634
|
+
Property Orientation.
|
|
635
|
+
Return int, a value in class `OrientationType`.
|
|
636
|
+
Call IUIAutomationElement::get_CurrentOrientation.
|
|
637
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentorientation
|
|
638
|
+
"""
|
|
639
|
+
return self.Element.CurrentOrientation
|
|
640
|
+
|
|
641
|
+
@property
|
|
642
|
+
def ProcessId(self) -> int:
|
|
643
|
+
"""
|
|
644
|
+
Property ProcessId.
|
|
645
|
+
Call IUIAutomationElement::get_CurrentProcessId.
|
|
646
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentprocessid
|
|
647
|
+
"""
|
|
648
|
+
return self.Element.CurrentProcessId
|
|
649
|
+
|
|
650
|
+
@property
|
|
651
|
+
def ProviderDescription(self) -> str:
|
|
652
|
+
"""
|
|
653
|
+
Property ProviderDescription.
|
|
654
|
+
Call IUIAutomationElement::get_CurrentProviderDescription.
|
|
655
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-get_currentproviderdescription
|
|
656
|
+
"""
|
|
657
|
+
return self.Element.CurrentProviderDescription
|
|
658
|
+
|
|
659
|
+
def FindAll(self, scope: int, condition) -> List['Control']:
|
|
660
|
+
"""
|
|
661
|
+
Find all UI Automation elements that satisfy the specified condition.
|
|
662
|
+
Call IUIAutomationElement::FindAll.
|
|
663
|
+
|
|
664
|
+
scope: int, a value in class `TreeScope`, specifying the scope of the search.
|
|
665
|
+
condition: a condition object from IUIAutomation.CreateTrueCondition() or similar.
|
|
666
|
+
Return List[Control], a list of `Control` subclasses that match the condition.
|
|
667
|
+
|
|
668
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-findall
|
|
669
|
+
"""
|
|
670
|
+
elementArray = self.Element.FindAll(scope, condition)
|
|
671
|
+
if not elementArray:
|
|
672
|
+
return []
|
|
673
|
+
|
|
674
|
+
controls = []
|
|
675
|
+
length = elementArray.Length
|
|
676
|
+
for i in range(length):
|
|
677
|
+
element = elementArray.GetElement(i)
|
|
678
|
+
control = Control.CreateControlFromElement(element)
|
|
679
|
+
if control:
|
|
680
|
+
controls.append(control)
|
|
681
|
+
return controls
|
|
682
|
+
|
|
683
|
+
def FindAllBuildCache(self, scope: int, condition, cacheRequest: 'CacheRequest') -> List['Control']:
|
|
684
|
+
"""
|
|
685
|
+
Find all UI Automation elements that satisfy the specified condition, and cache properties and patterns.
|
|
686
|
+
Call IUIAutomationElement::FindAllBuildCache.
|
|
687
|
+
|
|
688
|
+
scope: int, a value in class `TreeScope`, specifying the scope of the search.
|
|
689
|
+
condition: a condition object from IUIAutomation.CreateTrueCondition() or similar.
|
|
690
|
+
cacheRequest: CacheRequest, specifies the properties and patterns to cache.
|
|
691
|
+
Return List[Control], a list of `Control` subclasses that match the condition with cached data.
|
|
692
|
+
|
|
693
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-findallbuildcache
|
|
694
|
+
"""
|
|
695
|
+
elementArray = self.Element.FindAllBuildCache(scope, condition, cacheRequest.check_request)
|
|
696
|
+
if not elementArray:
|
|
697
|
+
return []
|
|
698
|
+
|
|
699
|
+
controls = []
|
|
700
|
+
length = elementArray.Length
|
|
701
|
+
for i in range(length):
|
|
702
|
+
element = elementArray.GetElement(i)
|
|
703
|
+
control = Control.CreateControlFromElement(element)
|
|
704
|
+
if control:
|
|
705
|
+
controls.append(control)
|
|
706
|
+
return controls
|
|
707
|
+
|
|
708
|
+
def FindFirst(self, scope: int, condition) -> Optional['Control']:
|
|
709
|
+
"""
|
|
710
|
+
Find the first UI Automation element that satisfies the specified condition.
|
|
711
|
+
Call IUIAutomationElement::FindFirst.
|
|
712
|
+
|
|
713
|
+
scope: int, a value in class `TreeScope`, specifying the scope of the search.
|
|
714
|
+
condition: a condition object from IUIAutomation.CreateTrueCondition() or similar.
|
|
715
|
+
Return `Control` subclass or None.
|
|
716
|
+
|
|
717
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-findfirst
|
|
718
|
+
"""
|
|
719
|
+
element = self.Element.FindFirst(scope, condition)
|
|
720
|
+
return Control.CreateControlFromElement(element)
|
|
721
|
+
|
|
722
|
+
def FindFirstBuildCache(self, scope: int, condition, cacheRequest: 'CacheRequest') -> Optional['Control']:
|
|
723
|
+
"""
|
|
724
|
+
Find the first UI Automation element that satisfies the specified condition, and cache properties and patterns.
|
|
725
|
+
Call IUIAutomationElement::FindFirstBuildCache.
|
|
726
|
+
|
|
727
|
+
scope: int, a value in class `TreeScope`, specifying the scope of the search.
|
|
728
|
+
condition: a condition object from IUIAutomation.CreateTrueCondition() or similar.
|
|
729
|
+
cacheRequest: CacheRequest, specifies the properties and patterns to cache.
|
|
730
|
+
Return `Control` subclass or None with cached data.
|
|
731
|
+
|
|
732
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-findfirstbuildcache
|
|
733
|
+
"""
|
|
734
|
+
element = self.Element.FindFirstBuildCache(scope, condition, cacheRequest.check_request)
|
|
735
|
+
return Control.CreateControlFromElement(element)
|
|
736
|
+
|
|
737
|
+
def GetCachedChildren(self) -> List['Control']:
|
|
738
|
+
"""
|
|
739
|
+
Retrieve the cached child elements of this UI Automation element.
|
|
740
|
+
Call IUIAutomationElement::GetCachedChildren.
|
|
741
|
+
|
|
742
|
+
Return List[Control], a list of cached child `Control` subclasses.
|
|
743
|
+
Note: Children are cached only if the scope of the cache request included TreeScope_Subtree,
|
|
744
|
+
TreeScope_Children, or TreeScope_Descendants.
|
|
745
|
+
|
|
746
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcachedchildren
|
|
747
|
+
"""
|
|
748
|
+
try:
|
|
749
|
+
elementArray = self.Element.GetCachedChildren()
|
|
750
|
+
if not elementArray:
|
|
751
|
+
return []
|
|
752
|
+
|
|
753
|
+
controls = []
|
|
754
|
+
length = elementArray.Length
|
|
755
|
+
for i in range(length):
|
|
756
|
+
element = elementArray.GetElement(i)
|
|
757
|
+
control = Control.CreateControlFromElement(element)
|
|
758
|
+
if control:
|
|
759
|
+
controls.append(control)
|
|
760
|
+
return controls
|
|
761
|
+
except comtypes.COMError as ex:
|
|
762
|
+
return []
|
|
763
|
+
|
|
764
|
+
def GetCachedParent(self) -> Optional['Control']:
|
|
765
|
+
"""
|
|
766
|
+
Retrieve the cached parent of this UI Automation element.
|
|
767
|
+
Call IUIAutomationElement::GetCachedParent.
|
|
768
|
+
|
|
769
|
+
Return `Control` subclass or None.
|
|
770
|
+
|
|
771
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcachedparent
|
|
772
|
+
"""
|
|
773
|
+
try:
|
|
774
|
+
element = self.Element.GetCachedParent()
|
|
775
|
+
return Control.CreateControlFromElement(element)
|
|
776
|
+
except comtypes.COMError as ex:
|
|
777
|
+
return None
|
|
778
|
+
|
|
779
|
+
def GetCachedPattern(self, patternId: int):
|
|
780
|
+
"""
|
|
781
|
+
Retrieve a cached pattern interface from this UI Automation element.
|
|
782
|
+
Call IUIAutomationElement::GetCachedPattern.
|
|
783
|
+
|
|
784
|
+
patternId: int, a value in class `PatternId`.
|
|
785
|
+
Return a pattern object if the pattern was cached, else None.
|
|
786
|
+
|
|
787
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcachedpattern
|
|
788
|
+
"""
|
|
789
|
+
try:
|
|
790
|
+
pattern = self.Element.GetCachedPattern(patternId)
|
|
791
|
+
if pattern:
|
|
792
|
+
return CreatePattern(patternId, pattern)
|
|
793
|
+
except comtypes.COMError as ex:
|
|
794
|
+
return None
|
|
795
|
+
|
|
796
|
+
def GetCachedPatternAs(self, patternId: int, riid):
|
|
797
|
+
"""
|
|
798
|
+
Retrieve a cached pattern interface from this UI Automation element, with a specific interface ID.
|
|
799
|
+
Call IUIAutomationElement::GetCachedPatternAs.
|
|
800
|
+
|
|
801
|
+
patternId: int, a value in class `PatternId`.
|
|
802
|
+
riid: GUID, the interface identifier.
|
|
803
|
+
Return a pattern object if the pattern was cached, else None.
|
|
804
|
+
|
|
805
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcachedpatternas
|
|
806
|
+
"""
|
|
807
|
+
try:
|
|
808
|
+
return self.Element.GetCachedPatternAs(patternId, riid)
|
|
809
|
+
except comtypes.COMError as ex:
|
|
810
|
+
return None
|
|
811
|
+
|
|
812
|
+
def GetCachedPropertyValue(self, propertyId: int) -> Any:
|
|
813
|
+
"""
|
|
814
|
+
Retrieve a cached property value from this UI Automation element.
|
|
815
|
+
Call IUIAutomationElement::GetCachedPropertyValue.
|
|
816
|
+
|
|
817
|
+
propertyId: int, a value in class `PropertyId`.
|
|
818
|
+
Return Any, the cached property value corresponding to propertyId.
|
|
819
|
+
|
|
820
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcachedpropertyvalue
|
|
821
|
+
"""
|
|
822
|
+
try:
|
|
823
|
+
return self.Element.GetCachedPropertyValue(propertyId)
|
|
824
|
+
except comtypes.COMError as ex:
|
|
825
|
+
return None
|
|
826
|
+
|
|
827
|
+
def GetCachedPropertyValueEx(self, propertyId: int, ignoreDefaultValue: int) -> Any:
|
|
828
|
+
"""
|
|
829
|
+
Retrieve a cached property value from this UI Automation element, optionally ignoring the default value.
|
|
830
|
+
Call IUIAutomationElement::GetCachedPropertyValueEx.
|
|
831
|
+
|
|
832
|
+
propertyId: int, a value in class `PropertyId`.
|
|
833
|
+
ignoreDefaultValue: int, 0 or 1. If 1, a default value is not returned.
|
|
834
|
+
Return Any, the cached property value corresponding to propertyId.
|
|
835
|
+
|
|
836
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcachedpropertyvalueex
|
|
837
|
+
"""
|
|
838
|
+
try:
|
|
839
|
+
return self.Element.GetCachedPropertyValueEx(propertyId, ignoreDefaultValue)
|
|
840
|
+
except comtypes.COMError as ex:
|
|
841
|
+
return None
|
|
842
|
+
|
|
843
|
+
def GetClickablePoint(self) -> Tuple[int, int, bool]:
|
|
844
|
+
"""
|
|
845
|
+
Call IUIAutomationElement::GetClickablePoint.
|
|
846
|
+
Return Tuple[int, int, bool], three items tuple (x, y, gotClickable), such as (20, 10, True)
|
|
847
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getclickablepoint
|
|
848
|
+
"""
|
|
849
|
+
point, gotClickable = self.Element.GetClickablePoint()
|
|
850
|
+
return (point.x, point.y, bool(gotClickable))
|
|
851
|
+
|
|
852
|
+
def GetPattern(self, patternId: int):
|
|
853
|
+
"""
|
|
854
|
+
Call IUIAutomationElement::GetCurrentPattern.
|
|
855
|
+
Get a new pattern by pattern id if it supports the pattern.
|
|
856
|
+
patternId: int, a value in class `PatternId`.
|
|
857
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcurrentpattern
|
|
858
|
+
"""
|
|
859
|
+
try:
|
|
860
|
+
pattern = self.Element.GetCurrentPattern(patternId)
|
|
861
|
+
if pattern:
|
|
862
|
+
subPattern = CreatePattern(patternId, pattern)
|
|
863
|
+
self._supportedPatterns[patternId] = subPattern
|
|
864
|
+
return subPattern
|
|
865
|
+
except comtypes.COMError as ex:
|
|
866
|
+
pass
|
|
867
|
+
|
|
868
|
+
def GetPatternAs(self, patternId: int, riid):
|
|
869
|
+
"""
|
|
870
|
+
Call IUIAutomationElement::GetCurrentPatternAs.
|
|
871
|
+
Get a new pattern by pattern id if it supports the pattern, todo.
|
|
872
|
+
patternId: int, a value in class `PatternId`.
|
|
873
|
+
riid: GUID.
|
|
874
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcurrentpatternas
|
|
875
|
+
"""
|
|
876
|
+
return self.Element.GetCurrentPatternAs(patternId, riid)
|
|
877
|
+
|
|
878
|
+
def GetPropertyValue(self, propertyId: int) -> Any:
|
|
879
|
+
"""
|
|
880
|
+
Call IUIAutomationElement::GetCurrentPropertyValue.
|
|
881
|
+
propertyId: int, a value in class `PropertyId`.
|
|
882
|
+
Return Any, corresponding type according to propertyId.
|
|
883
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcurrentpropertyvalue
|
|
884
|
+
"""
|
|
885
|
+
return self.Element.GetCurrentPropertyValue(propertyId)
|
|
886
|
+
|
|
887
|
+
def GetPropertyValueEx(self, propertyId: int, ignoreDefaultValue: int) -> Any:
|
|
888
|
+
"""
|
|
889
|
+
Call IUIAutomationElement::GetCurrentPropertyValueEx.
|
|
890
|
+
propertyId: int, a value in class `PropertyId`.
|
|
891
|
+
ignoreDefaultValue: int, 0 or 1.
|
|
892
|
+
Return Any, corresponding type according to propertyId.
|
|
893
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getcurrentpropertyvalueex
|
|
894
|
+
"""
|
|
895
|
+
return self.Element.GetCurrentPropertyValueEx(propertyId, ignoreDefaultValue)
|
|
896
|
+
|
|
897
|
+
def GetRuntimeId(self) -> List[int]:
|
|
898
|
+
"""
|
|
899
|
+
Call IUIAutomationElement::GetRuntimeId.
|
|
900
|
+
Return List[int], a list of int.
|
|
901
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-getruntimeid
|
|
902
|
+
"""
|
|
903
|
+
return self.Element.GetRuntimeId()
|
|
904
|
+
|
|
905
|
+
# QueryInterface
|
|
906
|
+
# Release
|
|
907
|
+
|
|
908
|
+
def SetFocus(self) -> bool:
|
|
909
|
+
"""
|
|
910
|
+
Call IUIAutomationElement::SetFocus.
|
|
911
|
+
Refer https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationelement-setfocus
|
|
912
|
+
"""
|
|
913
|
+
try:
|
|
914
|
+
return self.Element.SetFocus() == S_OK
|
|
915
|
+
except comtypes.COMError as ex:
|
|
916
|
+
return False
|
|
917
|
+
|
|
918
|
+
@property
|
|
919
|
+
def Element(self):
|
|
920
|
+
"""
|
|
921
|
+
Property Element.
|
|
922
|
+
Return `ctypes.POINTER(IUIAutomationElement)`.
|
|
923
|
+
"""
|
|
924
|
+
if not self._element:
|
|
925
|
+
self.Refind(maxSearchSeconds=TIME_OUT_SECOND, searchIntervalSeconds=self.searchInterval)
|
|
926
|
+
return self._element
|
|
927
|
+
|
|
928
|
+
@property
|
|
929
|
+
def ControlTypeName(self) -> str:
|
|
930
|
+
"""
|
|
931
|
+
Property ControlTypeName.
|
|
932
|
+
"""
|
|
933
|
+
return ControlTypeNames[self.ControlType]
|
|
934
|
+
|
|
935
|
+
def GetCachedPattern(self, patternId: int, cache: bool):
|
|
936
|
+
"""
|
|
937
|
+
Get a pattern by patternId.
|
|
938
|
+
patternId: int, a value in class `PatternId`.
|
|
939
|
+
Return a pattern if it supports the pattern else None.
|
|
940
|
+
cache: bool, if True, store the pattern for later use, if False, get a new pattern by `self.GetPattern`.
|
|
941
|
+
"""
|
|
942
|
+
if cache:
|
|
943
|
+
pattern = self._supportedPatterns.get(patternId, None)
|
|
944
|
+
if pattern:
|
|
945
|
+
return pattern
|
|
946
|
+
else:
|
|
947
|
+
pattern = self.GetPattern(patternId)
|
|
948
|
+
if pattern:
|
|
949
|
+
self._supportedPatterns[patternId] = pattern
|
|
950
|
+
return pattern
|
|
951
|
+
else:
|
|
952
|
+
pattern = self.GetPattern(patternId)
|
|
953
|
+
if pattern:
|
|
954
|
+
self._supportedPatterns[patternId] = pattern
|
|
955
|
+
return pattern
|
|
956
|
+
|
|
957
|
+
def GetLegacyIAccessiblePattern(self) -> LegacyIAccessiblePattern:
|
|
958
|
+
"""
|
|
959
|
+
Return `LegacyIAccessiblePattern` if it supports the pattern else None.
|
|
960
|
+
"""
|
|
961
|
+
return self.GetPattern(PatternId.LegacyIAccessiblePattern)
|
|
962
|
+
|
|
963
|
+
def GetAncestorControl(self, condition: Callable[['Control', int], bool]) -> Optional['Control']:
|
|
964
|
+
"""
|
|
965
|
+
Get an ancestor control that matches the condition.
|
|
966
|
+
condition: Callable[[Control, int], bool], function(control: Control, depth: int) -> bool,
|
|
967
|
+
depth starts with -1 and decreses when search goes up.
|
|
968
|
+
Return `Control` subclass or None.
|
|
969
|
+
"""
|
|
970
|
+
ancestor = self
|
|
971
|
+
depth = 0
|
|
972
|
+
while ancestor is not None:
|
|
973
|
+
ancestor = ancestor.GetParentControl()
|
|
974
|
+
depth -= 1
|
|
975
|
+
if ancestor:
|
|
976
|
+
if condition(ancestor, depth):
|
|
977
|
+
return ancestor
|
|
978
|
+
return None
|
|
979
|
+
|
|
980
|
+
def GetParentControl(self) -> Optional['Control']:
|
|
981
|
+
"""
|
|
982
|
+
Return `Control` subclass or None.
|
|
983
|
+
"""
|
|
984
|
+
ele = _AutomationClient.instance().ViewWalker.GetParentElement(self.Element)
|
|
985
|
+
return Control.CreateControlFromElement(ele)
|
|
986
|
+
|
|
987
|
+
def GetFirstChildControl(self) -> Optional['Control']:
|
|
988
|
+
"""
|
|
989
|
+
Return `Control` subclass or None.
|
|
990
|
+
"""
|
|
991
|
+
ele = _AutomationClient.instance().ViewWalker.GetFirstChildElement(self.Element)
|
|
992
|
+
return Control.CreateControlFromElement(ele)
|
|
993
|
+
|
|
994
|
+
def GetLastChildControl(self) -> Optional['Control']:
|
|
995
|
+
"""
|
|
996
|
+
Return `Control` subclass or None.
|
|
997
|
+
"""
|
|
998
|
+
ele = _AutomationClient.instance().ViewWalker.GetLastChildElement(self.Element)
|
|
999
|
+
return Control.CreateControlFromElement(ele)
|
|
1000
|
+
|
|
1001
|
+
def GetNextSiblingControl(self) -> Optional['Control']:
|
|
1002
|
+
"""
|
|
1003
|
+
Return `Control` subclass or None.
|
|
1004
|
+
"""
|
|
1005
|
+
ele = _AutomationClient.instance().ViewWalker.GetNextSiblingElement(self.Element)
|
|
1006
|
+
return Control.CreateControlFromElement(ele)
|
|
1007
|
+
|
|
1008
|
+
def GetPreviousSiblingControl(self) -> Optional['Control']:
|
|
1009
|
+
"""
|
|
1010
|
+
Return `Control` subclass or None.
|
|
1011
|
+
"""
|
|
1012
|
+
ele = _AutomationClient.instance().ViewWalker.GetPreviousSiblingElement(self.Element)
|
|
1013
|
+
return Control.CreateControlFromElement(ele)
|
|
1014
|
+
|
|
1015
|
+
def GetSiblingControl(self, condition: Callable[['Control'], bool], forward: bool = True) -> Optional['Control']:
|
|
1016
|
+
"""
|
|
1017
|
+
Get a sibling control that matches the condition.
|
|
1018
|
+
forward: bool, if True, only search next siblings, if False, search pervious siblings first, then search next siblings.
|
|
1019
|
+
condition: Callable[[Control], bool], function(control: Control) -> bool.
|
|
1020
|
+
Return `Control` subclass or None.
|
|
1021
|
+
"""
|
|
1022
|
+
if not forward:
|
|
1023
|
+
prev = self
|
|
1024
|
+
while True:
|
|
1025
|
+
prev = prev.GetPreviousSiblingControl()
|
|
1026
|
+
if prev:
|
|
1027
|
+
if condition(prev):
|
|
1028
|
+
return prev
|
|
1029
|
+
else:
|
|
1030
|
+
break
|
|
1031
|
+
next_ = self
|
|
1032
|
+
while True:
|
|
1033
|
+
next_ = next_.GetNextSiblingControl()
|
|
1034
|
+
if next_:
|
|
1035
|
+
if condition(next_):
|
|
1036
|
+
return next_
|
|
1037
|
+
else:
|
|
1038
|
+
break
|
|
1039
|
+
|
|
1040
|
+
def GetChildren(self) -> List['Control']:
|
|
1041
|
+
"""
|
|
1042
|
+
Return List[Control], a list of `Control` subclasses.
|
|
1043
|
+
"""
|
|
1044
|
+
children = []
|
|
1045
|
+
child = self.GetFirstChildControl()
|
|
1046
|
+
while child:
|
|
1047
|
+
children.append(child)
|
|
1048
|
+
child = child.GetNextSiblingControl()
|
|
1049
|
+
return children
|
|
1050
|
+
|
|
1051
|
+
def _CompareFunction(self, control: 'Control', depth: int) -> bool:
|
|
1052
|
+
"""
|
|
1053
|
+
Define how to search.
|
|
1054
|
+
control: `Control` or its subclass.
|
|
1055
|
+
depth: int, tree depth from searchFromControl.
|
|
1056
|
+
Return bool.
|
|
1057
|
+
"""
|
|
1058
|
+
compareFunc = None
|
|
1059
|
+
for key, value in self.searchProperties.items():
|
|
1060
|
+
if 'ControlType' == key:
|
|
1061
|
+
if value != control.ControlType:
|
|
1062
|
+
return False
|
|
1063
|
+
elif 'ClassName' == key:
|
|
1064
|
+
if value != control.ClassName:
|
|
1065
|
+
return False
|
|
1066
|
+
elif 'AutomationId' == key:
|
|
1067
|
+
if value != control.AutomationId:
|
|
1068
|
+
return False
|
|
1069
|
+
elif 'Depth' == key:
|
|
1070
|
+
if value != depth:
|
|
1071
|
+
return False
|
|
1072
|
+
elif 'Name' == key:
|
|
1073
|
+
if value != control.Name:
|
|
1074
|
+
return False
|
|
1075
|
+
elif 'SubName' == key:
|
|
1076
|
+
if value not in control.Name:
|
|
1077
|
+
return False
|
|
1078
|
+
elif 'RegexName' == key:
|
|
1079
|
+
if not self.regexName.match(control.Name):
|
|
1080
|
+
return False
|
|
1081
|
+
elif 'Compare' == key:
|
|
1082
|
+
compareFunc = value
|
|
1083
|
+
# use Compare at last
|
|
1084
|
+
if compareFunc and not compareFunc(control, depth):
|
|
1085
|
+
return False
|
|
1086
|
+
return True
|
|
1087
|
+
|
|
1088
|
+
def Exists(self, maxSearchSeconds: float = 5, searchIntervalSeconds: float = SEARCH_INTERVAL, printIfNotExist: bool = False) -> bool:
|
|
1089
|
+
"""
|
|
1090
|
+
maxSearchSeconds: float
|
|
1091
|
+
searchIntervalSeconds: float
|
|
1092
|
+
Find control every searchIntervalSeconds seconds in maxSearchSeconds seconds.
|
|
1093
|
+
Return bool, True if find
|
|
1094
|
+
"""
|
|
1095
|
+
if self._element and self._elementDirectAssign:
|
|
1096
|
+
# if element is directly assigned, not by searching, just check whether self._element is valid
|
|
1097
|
+
# but I can't find an API in UIAutomation that can directly check
|
|
1098
|
+
rootElement = _AutomationClient.instance().IUIAutomation.GetRootElement()
|
|
1099
|
+
if _AutomationClient.instance().IUIAutomation.CompareElements(self._element, rootElement):
|
|
1100
|
+
return True
|
|
1101
|
+
else:
|
|
1102
|
+
parentElement = _AutomationClient.instance().ViewWalker.GetParentElement(self._element)
|
|
1103
|
+
if parentElement:
|
|
1104
|
+
return True
|
|
1105
|
+
else:
|
|
1106
|
+
return False
|
|
1107
|
+
# find the element
|
|
1108
|
+
if not self.searchProperties:
|
|
1109
|
+
raise LookupError("control's searchProperties must not be empty!")
|
|
1110
|
+
self._element = None
|
|
1111
|
+
startTime = ProcessTime()
|
|
1112
|
+
# Use same timeout(s) parameters for resolve all parents
|
|
1113
|
+
prev = self.searchFromControl
|
|
1114
|
+
if prev and not prev._element and not prev.Exists(maxSearchSeconds, searchIntervalSeconds):
|
|
1115
|
+
if printIfNotExist or DEBUG_EXIST_DISAPPEAR:
|
|
1116
|
+
Logger.ColorfullyLog(self.GetColorfulSearchPropertiesStr() + '<Color=Red> does not exist.</Color>')
|
|
1117
|
+
return False
|
|
1118
|
+
startTime2 = ProcessTime()
|
|
1119
|
+
if DEBUG_SEARCH_TIME:
|
|
1120
|
+
startDateTime = datetime.datetime.now()
|
|
1121
|
+
while True:
|
|
1122
|
+
control = FindControl(self.searchFromControl, self._CompareFunction, self.searchDepth, False, self.foundIndex)
|
|
1123
|
+
if control:
|
|
1124
|
+
self._element = control.Element
|
|
1125
|
+
control._element = 0 # control will be destroyed, but the element needs to be stored in self._element
|
|
1126
|
+
if DEBUG_SEARCH_TIME:
|
|
1127
|
+
Logger.ColorfullyLog('{} TraverseControls: <Color=Cyan>{}</Color>, SearchTime: <Color=Cyan>{:.3f}</Color>s[{} - {}]'.format(
|
|
1128
|
+
self.GetColorfulSearchPropertiesStr(), control.traverseCount, ProcessTime() - startTime2,
|
|
1129
|
+
startDateTime.time(), datetime.datetime.now().time()))
|
|
1130
|
+
return True
|
|
1131
|
+
else:
|
|
1132
|
+
remain = startTime + maxSearchSeconds - ProcessTime()
|
|
1133
|
+
if remain > 0:
|
|
1134
|
+
time.sleep(min(remain, searchIntervalSeconds))
|
|
1135
|
+
else:
|
|
1136
|
+
if printIfNotExist or DEBUG_EXIST_DISAPPEAR:
|
|
1137
|
+
Logger.ColorfullyLog(self.GetColorfulSearchPropertiesStr() + '<Color=Red> does not exist.</Color>')
|
|
1138
|
+
return False
|
|
1139
|
+
|
|
1140
|
+
def Disappears(self, maxSearchSeconds: float = 5, searchIntervalSeconds: float = SEARCH_INTERVAL, printIfNotDisappear: bool = False) -> bool:
|
|
1141
|
+
"""
|
|
1142
|
+
maxSearchSeconds: float
|
|
1143
|
+
searchIntervalSeconds: float
|
|
1144
|
+
Check if control disappears every searchIntervalSeconds seconds in maxSearchSeconds seconds.
|
|
1145
|
+
Return bool, True if control disappears.
|
|
1146
|
+
"""
|
|
1147
|
+
global DEBUG_EXIST_DISAPPEAR
|
|
1148
|
+
start = ProcessTime()
|
|
1149
|
+
while True:
|
|
1150
|
+
temp = DEBUG_EXIST_DISAPPEAR
|
|
1151
|
+
DEBUG_EXIST_DISAPPEAR = False # do not print for Exists
|
|
1152
|
+
if not self.Exists(0, 0, False):
|
|
1153
|
+
DEBUG_EXIST_DISAPPEAR = temp
|
|
1154
|
+
return True
|
|
1155
|
+
DEBUG_EXIST_DISAPPEAR = temp
|
|
1156
|
+
remain = start + maxSearchSeconds - ProcessTime()
|
|
1157
|
+
if remain > 0:
|
|
1158
|
+
time.sleep(min(remain, searchIntervalSeconds))
|
|
1159
|
+
else:
|
|
1160
|
+
if printIfNotDisappear or DEBUG_EXIST_DISAPPEAR:
|
|
1161
|
+
Logger.ColorfullyLog(self.GetColorfulSearchPropertiesStr() + '<Color=Red> does not disappear.</Color>')
|
|
1162
|
+
return False
|
|
1163
|
+
|
|
1164
|
+
def Refind(self, maxSearchSeconds: float = TIME_OUT_SECOND, searchIntervalSeconds: float = SEARCH_INTERVAL, raiseException: bool = True) -> bool:
|
|
1165
|
+
"""
|
|
1166
|
+
Refind the control every searchIntervalSeconds seconds in maxSearchSeconds seconds.
|
|
1167
|
+
maxSearchSeconds: float.
|
|
1168
|
+
searchIntervalSeconds: float.
|
|
1169
|
+
raiseException: bool, if True, raise a LookupError if timeout.
|
|
1170
|
+
Return bool, True if find.
|
|
1171
|
+
"""
|
|
1172
|
+
if not self.Exists(maxSearchSeconds, searchIntervalSeconds, False if raiseException else DEBUG_EXIST_DISAPPEAR):
|
|
1173
|
+
if raiseException:
|
|
1174
|
+
Logger.ColorfullyLog('<Color=Red>Find Control Timeout({}s): </Color>{}'.format(maxSearchSeconds, self.GetColorfulSearchPropertiesStr()))
|
|
1175
|
+
raise LookupError('Find Control Timeout({}s): {}'.format(maxSearchSeconds, self.GetSearchPropertiesStr()))
|
|
1176
|
+
else:
|
|
1177
|
+
return False
|
|
1178
|
+
return True
|
|
1179
|
+
|
|
1180
|
+
def GetPosition(self, ratioX: float = 0.5, ratioY: float = 0.5) -> Optional[Tuple[int, int]]:
|
|
1181
|
+
"""
|
|
1182
|
+
Gets the position of the center of the control.
|
|
1183
|
+
ratioX: float.
|
|
1184
|
+
ratioY: float.
|
|
1185
|
+
Return Tuple[int, int], two ints tuple (x, y), the cursor positon relative to screen(0, 0)
|
|
1186
|
+
"""
|
|
1187
|
+
rect = self.BoundingRectangle
|
|
1188
|
+
if rect.width() == 0 or rect.height() == 0:
|
|
1189
|
+
Logger.ColorfullyLog('<Color=Yellow>Can not move cursor</Color>. {}\'s BoundingRectangle is {}. SearchProperties: {}'.format(
|
|
1190
|
+
self.ControlTypeName, rect, self.GetColorfulSearchPropertiesStr()))
|
|
1191
|
+
return None
|
|
1192
|
+
x = rect.left + int(rect.width() * ratioX)
|
|
1193
|
+
y = rect.top + int(rect.height() * ratioY)
|
|
1194
|
+
return x, y
|
|
1195
|
+
|
|
1196
|
+
def MoveCursorToInnerPos(self, x: Optional[int] = None, y: Optional[int] = None, ratioX: float = 0.5, ratioY: float = 0.5, simulateMove: bool = True) -> Optional[Tuple[int, int]]:
|
|
1197
|
+
"""
|
|
1198
|
+
Move cursor to control's internal position, default to center.
|
|
1199
|
+
x: int, if < 0, move to self.BoundingRectangle.right + x, if not None, ignore ratioX.
|
|
1200
|
+
y: int, if < 0, move to self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
|
|
1201
|
+
ratioX: float.
|
|
1202
|
+
ratioY: float.
|
|
1203
|
+
simulateMove: bool.
|
|
1204
|
+
Return Tuple[int, int], two ints tuple (x, y), the cursor positon relative to screen(0, 0)
|
|
1205
|
+
after moving or None if control's width or height is 0.
|
|
1206
|
+
"""
|
|
1207
|
+
rect = self.BoundingRectangle
|
|
1208
|
+
if rect.width() == 0 or rect.height() == 0:
|
|
1209
|
+
Logger.ColorfullyLog('<Color=Yellow>Can not move cursor</Color>. {}\'s BoundingRectangle is {}. SearchProperties: {}'.format(
|
|
1210
|
+
self.ControlTypeName, rect, self.GetColorfulSearchPropertiesStr()))
|
|
1211
|
+
return None
|
|
1212
|
+
if x is None:
|
|
1213
|
+
x = rect.left + int(rect.width() * ratioX)
|
|
1214
|
+
else:
|
|
1215
|
+
x = (rect.left if x >= 0 else rect.right) + x
|
|
1216
|
+
if y is None:
|
|
1217
|
+
y = rect.top + int(rect.height() * ratioY)
|
|
1218
|
+
else:
|
|
1219
|
+
y = (rect.top if y >= 0 else rect.bottom) + y
|
|
1220
|
+
if simulateMove and MAX_MOVE_SECOND > 0:
|
|
1221
|
+
MoveTo(x, y, waitTime=0)
|
|
1222
|
+
else:
|
|
1223
|
+
SetCursorPos(x, y)
|
|
1224
|
+
return x, y
|
|
1225
|
+
|
|
1226
|
+
def MoveCursorToMyCenter(self, simulateMove: bool = True) -> Optional[Tuple[int, int]]:
|
|
1227
|
+
"""
|
|
1228
|
+
Move cursor to control's center.
|
|
1229
|
+
Return Tuple[int, int], two ints tuple (x, y), the cursor positon relative to screen(0, 0) after moving.
|
|
1230
|
+
"""
|
|
1231
|
+
return self.MoveCursorToInnerPos(simulateMove=simulateMove)
|
|
1232
|
+
|
|
1233
|
+
def Click(self, x: Optional[int] = None, y: Optional[int] = None, ratioX: float = 0.5, ratioY: float = 0.5, simulateMove: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
1234
|
+
"""
|
|
1235
|
+
x: int, if < 0, click self.BoundingRectangle.right + x, if not None, ignore ratioX.
|
|
1236
|
+
y: int, if < 0, click self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
|
|
1237
|
+
ratioX: float.
|
|
1238
|
+
ratioY: float.
|
|
1239
|
+
simulateMove: bool, if True, first move cursor to control smoothly.
|
|
1240
|
+
waitTime: float.
|
|
1241
|
+
|
|
1242
|
+
Click(), Click(ratioX=0.5, ratioY=0.5): click center.
|
|
1243
|
+
Click(10, 10): click left+10, top+10.
|
|
1244
|
+
Click(-10, -10): click right-10, bottom-10.
|
|
1245
|
+
"""
|
|
1246
|
+
point = self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove)
|
|
1247
|
+
if point:
|
|
1248
|
+
Click(point[0], point[1], waitTime)
|
|
1249
|
+
|
|
1250
|
+
def MiddleClick(self, x: Optional[int] = None, y: Optional[int] = None, ratioX: float = 0.5, ratioY: float = 0.5, simulateMove: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
1251
|
+
"""
|
|
1252
|
+
x: int, if < 0, middle click self.BoundingRectangle.right + x, if not None, ignore ratioX.
|
|
1253
|
+
y: int, if < 0, middle click self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
|
|
1254
|
+
ratioX: float.
|
|
1255
|
+
ratioY: float.
|
|
1256
|
+
simulateMove: bool, if True, first move cursor to control smoothly.
|
|
1257
|
+
waitTime: float.
|
|
1258
|
+
|
|
1259
|
+
MiddleClick(), MiddleClick(ratioX=0.5, ratioY=0.5): middle click center.
|
|
1260
|
+
MiddleClick(10, 10): middle click left+10, top+10.
|
|
1261
|
+
MiddleClick(-10, -10): middle click right-10, bottom-10.
|
|
1262
|
+
"""
|
|
1263
|
+
point = self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove)
|
|
1264
|
+
if point:
|
|
1265
|
+
MiddleClick(point[0], point[1], waitTime)
|
|
1266
|
+
|
|
1267
|
+
def RightClick(self, x: Optional[int] = None, y: Optional[int] = None, ratioX: float = 0.5, ratioY: float = 0.5, simulateMove: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
1268
|
+
"""
|
|
1269
|
+
x: int, if < 0, right click self.BoundingRectangle.right + x, if not None, ignore ratioX.
|
|
1270
|
+
y: int, if < 0, right click self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
|
|
1271
|
+
ratioX: float.
|
|
1272
|
+
ratioY: float.
|
|
1273
|
+
simulateMove: bool, if True, first move cursor to control smoothly.
|
|
1274
|
+
waitTime: float.
|
|
1275
|
+
|
|
1276
|
+
RightClick(), RightClick(ratioX=0.5, ratioY=0.5): right click center.
|
|
1277
|
+
RightClick(10, 10): right click left+10, top+10.
|
|
1278
|
+
RightClick(-10, -10): right click right-10, bottom-10.
|
|
1279
|
+
"""
|
|
1280
|
+
point = self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove)
|
|
1281
|
+
if point:
|
|
1282
|
+
RightClick(point[0], point[1], waitTime)
|
|
1283
|
+
|
|
1284
|
+
def DoubleClick(self, x: Optional[int] = None, y: Optional[int] = None, ratioX: float = 0.5, ratioY: float = 0.5, simulateMove: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
1285
|
+
"""
|
|
1286
|
+
x: int, if < 0, right click self.BoundingRectangle.right + x, if not None, ignore ratioX.
|
|
1287
|
+
y: int, if < 0, right click self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
|
|
1288
|
+
ratioX: float.
|
|
1289
|
+
ratioY: float.
|
|
1290
|
+
simulateMove: bool, if True, first move cursor to control smoothly.
|
|
1291
|
+
waitTime: float.
|
|
1292
|
+
|
|
1293
|
+
DoubleClick(), DoubleClick(ratioX=0.5, ratioY=0.5): double click center.
|
|
1294
|
+
DoubleClick(10, 10): double click left+10, top+10.
|
|
1295
|
+
DoubleClick(-10, -10): double click right-10, bottom-10.
|
|
1296
|
+
"""
|
|
1297
|
+
x, y = self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove)
|
|
1298
|
+
Click(x, y, GetDoubleClickTime() * 1.0 / 2000)
|
|
1299
|
+
Click(x, y, waitTime)
|
|
1300
|
+
|
|
1301
|
+
def DragDrop(self, x1: int, y1: int, x2: int, y2: int, moveSpeed: float = 1, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
1302
|
+
rect = self.BoundingRectangle
|
|
1303
|
+
if rect.width() == 0 or rect.height() == 0:
|
|
1304
|
+
Logger.ColorfullyLog('<Color=Yellow>Can not move cursor</Color>. {}\'s BoundingRectangle is {}. SearchProperties: {}'.format(
|
|
1305
|
+
self.ControlTypeName, rect, self.GetColorfulSearchPropertiesStr()))
|
|
1306
|
+
return
|
|
1307
|
+
x1 = (rect.left if x1 >= 0 else rect.right) + x1
|
|
1308
|
+
y1 = (rect.top if y1 >= 0 else rect.bottom) + y1
|
|
1309
|
+
x2 = (rect.left if x2 >= 0 else rect.right) + x2
|
|
1310
|
+
y2 = (rect.top if y2 >= 0 else rect.bottom) + y2
|
|
1311
|
+
DragDrop(x1, y1, x2, y2, moveSpeed, waitTime)
|
|
1312
|
+
|
|
1313
|
+
def RightDragDrop(self, x1: int, y1: int, x2: int, y2: int, moveSpeed: float = 1, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
1314
|
+
rect = self.BoundingRectangle
|
|
1315
|
+
if rect.width() == 0 or rect.height() == 0:
|
|
1316
|
+
Logger.ColorfullyLog('<Color=Yellow>Can not move cursor</Color>. {}\'s BoundingRectangle is {}. SearchProperties: {}'.format(
|
|
1317
|
+
self.ControlTypeName, rect, self.GetColorfulSearchPropertiesStr()))
|
|
1318
|
+
return
|
|
1319
|
+
x1 = (rect.left if x1 >= 0 else rect.right) + x1
|
|
1320
|
+
y1 = (rect.top if y1 >= 0 else rect.bottom) + y1
|
|
1321
|
+
x2 = (rect.left if x2 >= 0 else rect.right) + x2
|
|
1322
|
+
y2 = (rect.top if y2 >= 0 else rect.bottom) + y2
|
|
1323
|
+
RightDragDrop(x1, y1, x2, y2, moveSpeed, waitTime)
|
|
1324
|
+
|
|
1325
|
+
def WheelDown(self, x: Optional[int] = None, y: Optional[int] = None, ratioX: float = 0.5, ratioY: float = 0.5, wheelTimes: int = 1, interval: float = 0.05, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
1326
|
+
"""
|
|
1327
|
+
Make control have focus first, move cursor to the specified position and mouse wheel down.
|
|
1328
|
+
x: int, if < 0, move x cursor to self.BoundingRectangle.right + x, if not None, ignore ratioX.
|
|
1329
|
+
y: int, if < 0, move y cursor to self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
|
|
1330
|
+
ratioX: float.
|
|
1331
|
+
ratioY: float.
|
|
1332
|
+
wheelTimes: int.
|
|
1333
|
+
interval: float.
|
|
1334
|
+
waitTime: float.
|
|
1335
|
+
"""
|
|
1336
|
+
cursorX, cursorY = GetCursorPos()
|
|
1337
|
+
self.SetFocus()
|
|
1338
|
+
self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove=False)
|
|
1339
|
+
WheelDown(wheelTimes, interval, waitTime)
|
|
1340
|
+
SetCursorPos(cursorX, cursorY)
|
|
1341
|
+
|
|
1342
|
+
def WheelUp(self, x: Optional[int] = None, y: Optional[int] = None, ratioX: float = 0.5, ratioY: float = 0.5, wheelTimes: int = 1, interval: float = 0.05, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
1343
|
+
"""
|
|
1344
|
+
Make control have focus first, move cursor to the specified position and mouse wheel up.
|
|
1345
|
+
x: int, if < 0, move x cursor to self.BoundingRectangle.right + x, if not None, ignore ratioX.
|
|
1346
|
+
y: int, if < 0, move y cursor to self.BoundingRectangle.bottom + y, if not None, ignore ratioY.
|
|
1347
|
+
ratioX: float.
|
|
1348
|
+
ratioY: float.
|
|
1349
|
+
wheelTimes: int.
|
|
1350
|
+
interval: float.
|
|
1351
|
+
waitTime: float.
|
|
1352
|
+
"""
|
|
1353
|
+
cursorX, cursorY = GetCursorPos()
|
|
1354
|
+
self.SetFocus()
|
|
1355
|
+
self.MoveCursorToInnerPos(x, y, ratioX, ratioY, simulateMove=False)
|
|
1356
|
+
WheelUp(wheelTimes, interval, waitTime)
|
|
1357
|
+
SetCursorPos(cursorX, cursorY)
|
|
1358
|
+
|
|
1359
|
+
def ShowWindow(self, cmdShow: int, waitTime: float = OPERATION_WAIT_TIME) -> Optional[bool]:
|
|
1360
|
+
"""
|
|
1361
|
+
Get a native handle from self or ancestors until valid and call native `ShowWindow` with cmdShow.
|
|
1362
|
+
cmdShow: int, a value in in class `SW`.
|
|
1363
|
+
waitTime: float.
|
|
1364
|
+
Return bool, True if succeed otherwise False and None if the handle could not be gotten.
|
|
1365
|
+
"""
|
|
1366
|
+
handle = self.NativeWindowHandle
|
|
1367
|
+
if not handle:
|
|
1368
|
+
control = self
|
|
1369
|
+
while not handle and control:
|
|
1370
|
+
control = control.GetParentControl()
|
|
1371
|
+
if control:
|
|
1372
|
+
handle = control.NativeWindowHandle
|
|
1373
|
+
else:
|
|
1374
|
+
handle = 0
|
|
1375
|
+
break
|
|
1376
|
+
if handle:
|
|
1377
|
+
ret = ShowWindow(handle, cmdShow)
|
|
1378
|
+
time.sleep(waitTime)
|
|
1379
|
+
return ret
|
|
1380
|
+
return None
|
|
1381
|
+
|
|
1382
|
+
def Show(self, waitTime: float = OPERATION_WAIT_TIME) -> Optional[bool]:
|
|
1383
|
+
"""
|
|
1384
|
+
Call native `ShowWindow(SW.Show)`.
|
|
1385
|
+
Return bool, True if succeed otherwise False and None if the handle could not be gotten.
|
|
1386
|
+
"""
|
|
1387
|
+
return self.ShowWindow(SW.Show, waitTime)
|
|
1388
|
+
|
|
1389
|
+
def Hide(self, waitTime: float = OPERATION_WAIT_TIME) -> Optional[bool]:
|
|
1390
|
+
"""
|
|
1391
|
+
Call native `ShowWindow(SW.Hide)`.
|
|
1392
|
+
waitTime: float
|
|
1393
|
+
Return bool, True if succeed otherwise False and None if the handle could not be gotten.
|
|
1394
|
+
"""
|
|
1395
|
+
return self.ShowWindow(SW.Hide, waitTime)
|
|
1396
|
+
|
|
1397
|
+
def MoveWindow(self, x: int, y: int, width: int, height: int, repaint: bool = True) -> bool:
|
|
1398
|
+
"""
|
|
1399
|
+
Call native MoveWindow if control has a valid native handle.
|
|
1400
|
+
x: int.
|
|
1401
|
+
y: int.
|
|
1402
|
+
width: int.
|
|
1403
|
+
height: int.
|
|
1404
|
+
repaint: bool.
|
|
1405
|
+
Return bool, True if succeed otherwise False.
|
|
1406
|
+
"""
|
|
1407
|
+
handle = self.NativeWindowHandle
|
|
1408
|
+
if handle:
|
|
1409
|
+
return MoveWindow(handle, x, y, width, height, int(repaint))
|
|
1410
|
+
return False
|
|
1411
|
+
|
|
1412
|
+
def GetWindowText(self) -> Optional[str]:
|
|
1413
|
+
"""
|
|
1414
|
+
Call native GetWindowText if control has a valid native handle.
|
|
1415
|
+
"""
|
|
1416
|
+
handle = self.NativeWindowHandle
|
|
1417
|
+
if handle:
|
|
1418
|
+
return GetWindowText(handle)
|
|
1419
|
+
return None
|
|
1420
|
+
|
|
1421
|
+
def SetWindowText(self, text: str) -> bool:
|
|
1422
|
+
"""
|
|
1423
|
+
Call native SetWindowText if control has a valid native handle.
|
|
1424
|
+
"""
|
|
1425
|
+
handle = self.NativeWindowHandle
|
|
1426
|
+
if handle:
|
|
1427
|
+
return SetWindowText(handle, text)
|
|
1428
|
+
return False
|
|
1429
|
+
|
|
1430
|
+
def SendKey(self, key: int, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
1431
|
+
"""
|
|
1432
|
+
Make control have focus first and type a key.
|
|
1433
|
+
`self.SetFocus` may not work for some controls, you may need to click it to make it have focus.
|
|
1434
|
+
key: int, a key code value in class Keys.
|
|
1435
|
+
waitTime: float.
|
|
1436
|
+
"""
|
|
1437
|
+
self.SetFocus()
|
|
1438
|
+
SendKey(key, waitTime)
|
|
1439
|
+
|
|
1440
|
+
def SendKeys(self, text: str, interval: float = 0.01, waitTime: float = OPERATION_WAIT_TIME, charMode: bool = True) -> None:
|
|
1441
|
+
"""
|
|
1442
|
+
Make control have focus first and type keys.
|
|
1443
|
+
`self.SetFocus` may not work for some controls, you may need to click it to make it have focus.
|
|
1444
|
+
text: str, keys to type, see the docstring of `SendKeys`.
|
|
1445
|
+
interval: float, seconds between keys.
|
|
1446
|
+
waitTime: float.
|
|
1447
|
+
charMode: bool, if False, the text typied is depend on the input method if a input method is on.
|
|
1448
|
+
"""
|
|
1449
|
+
self.SetFocus()
|
|
1450
|
+
SendKeys(text, interval, waitTime, charMode)
|
|
1451
|
+
|
|
1452
|
+
def GetPixelColor(self, x: int, y: int) -> Optional[int]:
|
|
1453
|
+
"""
|
|
1454
|
+
Call native `GetPixelColor` if control has a valid native handle.
|
|
1455
|
+
Use `self.ToBitmap` if control doesn't have a valid native handle or you get many pixels.
|
|
1456
|
+
x: int, internal x position.
|
|
1457
|
+
y: int, internal y position.
|
|
1458
|
+
Return int, a color value in bgr.
|
|
1459
|
+
r = bgr & 0x0000FF
|
|
1460
|
+
g = (bgr & 0x00FF00) >> 8
|
|
1461
|
+
b = (bgr & 0xFF0000) >> 16
|
|
1462
|
+
"""
|
|
1463
|
+
handle = self.NativeWindowHandle
|
|
1464
|
+
if handle:
|
|
1465
|
+
return GetPixelColor(x, y, handle)
|
|
1466
|
+
return None
|
|
1467
|
+
|
|
1468
|
+
def ToBitmap(self, x: int = 0, y: int = 0, width: int = 0, height: int = 0,
|
|
1469
|
+
captureCursor: bool = False) -> Optional[Bitmap]:
|
|
1470
|
+
"""
|
|
1471
|
+
Capture control to a `Bitmap` object.
|
|
1472
|
+
x, y: int, the point in control's internal position(from 0,0).
|
|
1473
|
+
width, height: int, image's width and height from x, y, use 0 for entire area.
|
|
1474
|
+
If width(or height) < 0, image size will be control's width(or height) - width(or height).
|
|
1475
|
+
"""
|
|
1476
|
+
return Bitmap.FromControl(self, x, y, width, height, captureCursor)
|
|
1477
|
+
|
|
1478
|
+
def CaptureToImage(self, savePath: str, x: int = 0, y: int = 0, width: int = 0, height: int = 0,
|
|
1479
|
+
captureCursor: bool = False) -> bool:
|
|
1480
|
+
"""
|
|
1481
|
+
Capture control to a image file.
|
|
1482
|
+
savePath: str, should end with .bmp, .jpg, .jpeg, .png, .gif, .tif, .tiff.
|
|
1483
|
+
x, y: int, the point in control's internal position(from 0,0).
|
|
1484
|
+
width, height: int, image's width and height from x, y, use 0 for entire area.
|
|
1485
|
+
If width(or height) < 0, image size will be control's width(or height) - width(or height).
|
|
1486
|
+
Return bool, True if succeed otherwise False.
|
|
1487
|
+
"""
|
|
1488
|
+
bitmap = Bitmap.FromControl(self, x, y, width, height, captureCursor)
|
|
1489
|
+
if bitmap:
|
|
1490
|
+
with bitmap:
|
|
1491
|
+
return bitmap.ToFile(savePath)
|
|
1492
|
+
return False
|
|
1493
|
+
|
|
1494
|
+
def IsTopLevel(self) -> bool:
|
|
1495
|
+
"""Determine whether current control is top level."""
|
|
1496
|
+
handle = self.NativeWindowHandle
|
|
1497
|
+
if handle:
|
|
1498
|
+
return GetAncestor(handle, GAFlag.Root) == handle
|
|
1499
|
+
return False
|
|
1500
|
+
|
|
1501
|
+
def GetTopLevelControl(self) -> Optional['Control']:
|
|
1502
|
+
"""
|
|
1503
|
+
Get the top level control which current control lays.
|
|
1504
|
+
If current control is top level, return self.
|
|
1505
|
+
If current control is root control, return None.
|
|
1506
|
+
Return `PaneControl` or `WindowControl` or None.
|
|
1507
|
+
"""
|
|
1508
|
+
handle = self.NativeWindowHandle
|
|
1509
|
+
if handle:
|
|
1510
|
+
topHandle = GetAncestor(handle, GAFlag.Root)
|
|
1511
|
+
if topHandle:
|
|
1512
|
+
if topHandle == handle:
|
|
1513
|
+
return self
|
|
1514
|
+
else:
|
|
1515
|
+
return ControlFromHandle(topHandle)
|
|
1516
|
+
else:
|
|
1517
|
+
# self is root control
|
|
1518
|
+
pass
|
|
1519
|
+
else:
|
|
1520
|
+
control = self
|
|
1521
|
+
while True:
|
|
1522
|
+
control = control.GetParentControl()
|
|
1523
|
+
if not control:
|
|
1524
|
+
break
|
|
1525
|
+
handle = control.NativeWindowHandle
|
|
1526
|
+
if handle:
|
|
1527
|
+
topHandle = GetAncestor(handle, GAFlag.Root)
|
|
1528
|
+
return ControlFromHandle(topHandle)
|
|
1529
|
+
return None
|
|
1530
|
+
|
|
1531
|
+
def Control(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1532
|
+
Name: Optional[str] = None,
|
|
1533
|
+
SubName: Optional[str] = None,
|
|
1534
|
+
RegexName: Optional[str] = None,
|
|
1535
|
+
ClassName: Optional[str] = None,
|
|
1536
|
+
AutomationId: Optional[str] = None,
|
|
1537
|
+
Depth: Optional[int] = None,
|
|
1538
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1539
|
+
**searchProperties) -> 'Control':
|
|
1540
|
+
return Control(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1541
|
+
foundIndex=foundIndex, element=element,
|
|
1542
|
+
Name=Name,
|
|
1543
|
+
SubName=SubName,
|
|
1544
|
+
RegexName=RegexName,
|
|
1545
|
+
ClassName=ClassName,
|
|
1546
|
+
AutomationId=AutomationId,
|
|
1547
|
+
Depth=Depth,
|
|
1548
|
+
Compare=Compare,
|
|
1549
|
+
**searchProperties)
|
|
1550
|
+
|
|
1551
|
+
def ButtonControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1552
|
+
Name: Optional[str] = None,
|
|
1553
|
+
SubName: Optional[str] = None,
|
|
1554
|
+
RegexName: Optional[str] = None,
|
|
1555
|
+
ClassName: Optional[str] = None,
|
|
1556
|
+
AutomationId: Optional[str] = None,
|
|
1557
|
+
Depth: Optional[int] = None,
|
|
1558
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1559
|
+
**searchProperties) -> 'ButtonControl':
|
|
1560
|
+
return ButtonControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1561
|
+
foundIndex=foundIndex, element=element,
|
|
1562
|
+
Name=Name,
|
|
1563
|
+
SubName=SubName,
|
|
1564
|
+
RegexName=RegexName,
|
|
1565
|
+
ClassName=ClassName,
|
|
1566
|
+
AutomationId=AutomationId,
|
|
1567
|
+
Depth=Depth,
|
|
1568
|
+
Compare=Compare,
|
|
1569
|
+
**searchProperties)
|
|
1570
|
+
|
|
1571
|
+
def CalendarControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1572
|
+
Name: Optional[str] = None,
|
|
1573
|
+
SubName: Optional[str] = None,
|
|
1574
|
+
RegexName: Optional[str] = None,
|
|
1575
|
+
ClassName: Optional[str] = None,
|
|
1576
|
+
AutomationId: Optional[str] = None,
|
|
1577
|
+
Depth: Optional[int] = None,
|
|
1578
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1579
|
+
**searchProperties) -> 'CalendarControl':
|
|
1580
|
+
return CalendarControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1581
|
+
foundIndex=foundIndex, element=element,
|
|
1582
|
+
Name=Name,
|
|
1583
|
+
SubName=SubName,
|
|
1584
|
+
RegexName=RegexName,
|
|
1585
|
+
ClassName=ClassName,
|
|
1586
|
+
AutomationId=AutomationId,
|
|
1587
|
+
Depth=Depth,
|
|
1588
|
+
Compare=Compare,
|
|
1589
|
+
**searchProperties)
|
|
1590
|
+
|
|
1591
|
+
def CheckBoxControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1592
|
+
Name: Optional[str] = None,
|
|
1593
|
+
SubName: Optional[str] = None,
|
|
1594
|
+
RegexName: Optional[str] = None,
|
|
1595
|
+
ClassName: Optional[str] = None,
|
|
1596
|
+
AutomationId: Optional[str] = None,
|
|
1597
|
+
Depth: Optional[int] = None,
|
|
1598
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1599
|
+
**searchProperties) -> 'CheckBoxControl':
|
|
1600
|
+
return CheckBoxControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1601
|
+
foundIndex=foundIndex, element=element,
|
|
1602
|
+
Name=Name,
|
|
1603
|
+
SubName=SubName,
|
|
1604
|
+
RegexName=RegexName,
|
|
1605
|
+
ClassName=ClassName,
|
|
1606
|
+
AutomationId=AutomationId,
|
|
1607
|
+
Depth=Depth,
|
|
1608
|
+
Compare=Compare,
|
|
1609
|
+
**searchProperties)
|
|
1610
|
+
|
|
1611
|
+
def ComboBoxControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1612
|
+
Name: Optional[str] = None,
|
|
1613
|
+
SubName: Optional[str] = None,
|
|
1614
|
+
RegexName: Optional[str] = None,
|
|
1615
|
+
ClassName: Optional[str] = None,
|
|
1616
|
+
AutomationId: Optional[str] = None,
|
|
1617
|
+
Depth: Optional[int] = None,
|
|
1618
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1619
|
+
**searchProperties) -> 'ComboBoxControl':
|
|
1620
|
+
return ComboBoxControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1621
|
+
foundIndex=foundIndex, element=element,
|
|
1622
|
+
Name=Name,
|
|
1623
|
+
SubName=SubName,
|
|
1624
|
+
RegexName=RegexName,
|
|
1625
|
+
ClassName=ClassName,
|
|
1626
|
+
AutomationId=AutomationId,
|
|
1627
|
+
Depth=Depth,
|
|
1628
|
+
Compare=Compare,
|
|
1629
|
+
**searchProperties)
|
|
1630
|
+
|
|
1631
|
+
def CustomControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1632
|
+
Name: Optional[str] = None,
|
|
1633
|
+
SubName: Optional[str] = None,
|
|
1634
|
+
RegexName: Optional[str] = None,
|
|
1635
|
+
ClassName: Optional[str] = None,
|
|
1636
|
+
AutomationId: Optional[str] = None,
|
|
1637
|
+
Depth: Optional[int] = None,
|
|
1638
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1639
|
+
**searchProperties) -> 'CustomControl':
|
|
1640
|
+
return CustomControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1641
|
+
foundIndex=foundIndex, element=element,
|
|
1642
|
+
Name=Name,
|
|
1643
|
+
SubName=SubName,
|
|
1644
|
+
RegexName=RegexName,
|
|
1645
|
+
ClassName=ClassName,
|
|
1646
|
+
AutomationId=AutomationId,
|
|
1647
|
+
Depth=Depth,
|
|
1648
|
+
Compare=Compare,
|
|
1649
|
+
**searchProperties)
|
|
1650
|
+
|
|
1651
|
+
def DataGridControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1652
|
+
Name: Optional[str] = None,
|
|
1653
|
+
SubName: Optional[str] = None,
|
|
1654
|
+
RegexName: Optional[str] = None,
|
|
1655
|
+
ClassName: Optional[str] = None,
|
|
1656
|
+
AutomationId: Optional[str] = None,
|
|
1657
|
+
Depth: Optional[int] = None,
|
|
1658
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1659
|
+
**searchProperties) -> 'DataGridControl':
|
|
1660
|
+
return DataGridControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1661
|
+
foundIndex=foundIndex, element=element,
|
|
1662
|
+
Name=Name,
|
|
1663
|
+
SubName=SubName,
|
|
1664
|
+
RegexName=RegexName,
|
|
1665
|
+
ClassName=ClassName,
|
|
1666
|
+
AutomationId=AutomationId,
|
|
1667
|
+
Depth=Depth,
|
|
1668
|
+
Compare=Compare,
|
|
1669
|
+
**searchProperties)
|
|
1670
|
+
|
|
1671
|
+
def DataItemControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1672
|
+
Name: Optional[str] = None,
|
|
1673
|
+
SubName: Optional[str] = None,
|
|
1674
|
+
RegexName: Optional[str] = None,
|
|
1675
|
+
ClassName: Optional[str] = None,
|
|
1676
|
+
AutomationId: Optional[str] = None,
|
|
1677
|
+
Depth: Optional[int] = None,
|
|
1678
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1679
|
+
**searchProperties) -> 'DataItemControl':
|
|
1680
|
+
return DataItemControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1681
|
+
foundIndex=foundIndex, element=element,
|
|
1682
|
+
Name=Name,
|
|
1683
|
+
SubName=SubName,
|
|
1684
|
+
RegexName=RegexName,
|
|
1685
|
+
ClassName=ClassName,
|
|
1686
|
+
AutomationId=AutomationId,
|
|
1687
|
+
Depth=Depth,
|
|
1688
|
+
Compare=Compare,
|
|
1689
|
+
**searchProperties)
|
|
1690
|
+
|
|
1691
|
+
def DocumentControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1692
|
+
Name: Optional[str] = None,
|
|
1693
|
+
SubName: Optional[str] = None,
|
|
1694
|
+
RegexName: Optional[str] = None,
|
|
1695
|
+
ClassName: Optional[str] = None,
|
|
1696
|
+
AutomationId: Optional[str] = None,
|
|
1697
|
+
Depth: Optional[int] = None,
|
|
1698
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1699
|
+
**searchProperties) -> 'DocumentControl':
|
|
1700
|
+
return DocumentControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1701
|
+
foundIndex=foundIndex, element=element,
|
|
1702
|
+
Name=Name,
|
|
1703
|
+
SubName=SubName,
|
|
1704
|
+
RegexName=RegexName,
|
|
1705
|
+
ClassName=ClassName,
|
|
1706
|
+
AutomationId=AutomationId,
|
|
1707
|
+
Depth=Depth,
|
|
1708
|
+
Compare=Compare,
|
|
1709
|
+
**searchProperties)
|
|
1710
|
+
|
|
1711
|
+
def EditControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1712
|
+
Name: Optional[str] = None,
|
|
1713
|
+
SubName: Optional[str] = None,
|
|
1714
|
+
RegexName: Optional[str] = None,
|
|
1715
|
+
ClassName: Optional[str] = None,
|
|
1716
|
+
AutomationId: Optional[str] = None,
|
|
1717
|
+
Depth: Optional[int] = None,
|
|
1718
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1719
|
+
**searchProperties) -> 'EditControl':
|
|
1720
|
+
return EditControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1721
|
+
foundIndex=foundIndex, element=element,
|
|
1722
|
+
Name=Name,
|
|
1723
|
+
SubName=SubName,
|
|
1724
|
+
RegexName=RegexName,
|
|
1725
|
+
ClassName=ClassName,
|
|
1726
|
+
AutomationId=AutomationId,
|
|
1727
|
+
Depth=Depth,
|
|
1728
|
+
Compare=Compare,
|
|
1729
|
+
**searchProperties)
|
|
1730
|
+
|
|
1731
|
+
def GroupControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1732
|
+
Name: Optional[str] = None,
|
|
1733
|
+
SubName: Optional[str] = None,
|
|
1734
|
+
RegexName: Optional[str] = None,
|
|
1735
|
+
ClassName: Optional[str] = None,
|
|
1736
|
+
AutomationId: Optional[str] = None,
|
|
1737
|
+
Depth: Optional[int] = None,
|
|
1738
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1739
|
+
**searchProperties) -> 'GroupControl':
|
|
1740
|
+
return GroupControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1741
|
+
foundIndex=foundIndex, element=element,
|
|
1742
|
+
Name=Name,
|
|
1743
|
+
SubName=SubName,
|
|
1744
|
+
RegexName=RegexName,
|
|
1745
|
+
ClassName=ClassName,
|
|
1746
|
+
AutomationId=AutomationId,
|
|
1747
|
+
Depth=Depth,
|
|
1748
|
+
Compare=Compare,
|
|
1749
|
+
**searchProperties)
|
|
1750
|
+
|
|
1751
|
+
def HeaderControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1752
|
+
Name: Optional[str] = None,
|
|
1753
|
+
SubName: Optional[str] = None,
|
|
1754
|
+
RegexName: Optional[str] = None,
|
|
1755
|
+
ClassName: Optional[str] = None,
|
|
1756
|
+
AutomationId: Optional[str] = None,
|
|
1757
|
+
Depth: Optional[int] = None,
|
|
1758
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1759
|
+
**searchProperties) -> 'HeaderControl':
|
|
1760
|
+
return HeaderControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1761
|
+
foundIndex=foundIndex, element=element,
|
|
1762
|
+
Name=Name,
|
|
1763
|
+
SubName=SubName,
|
|
1764
|
+
RegexName=RegexName,
|
|
1765
|
+
ClassName=ClassName,
|
|
1766
|
+
AutomationId=AutomationId,
|
|
1767
|
+
Depth=Depth,
|
|
1768
|
+
Compare=Compare,
|
|
1769
|
+
**searchProperties)
|
|
1770
|
+
|
|
1771
|
+
def HeaderItemControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1772
|
+
Name: Optional[str] = None,
|
|
1773
|
+
SubName: Optional[str] = None,
|
|
1774
|
+
RegexName: Optional[str] = None,
|
|
1775
|
+
ClassName: Optional[str] = None,
|
|
1776
|
+
AutomationId: Optional[str] = None,
|
|
1777
|
+
Depth: Optional[int] = None,
|
|
1778
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1779
|
+
**searchProperties) -> 'HeaderItemControl':
|
|
1780
|
+
return HeaderItemControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1781
|
+
foundIndex=foundIndex, element=element,
|
|
1782
|
+
Name=Name,
|
|
1783
|
+
SubName=SubName,
|
|
1784
|
+
RegexName=RegexName,
|
|
1785
|
+
ClassName=ClassName,
|
|
1786
|
+
AutomationId=AutomationId,
|
|
1787
|
+
Depth=Depth,
|
|
1788
|
+
Compare=Compare,
|
|
1789
|
+
**searchProperties)
|
|
1790
|
+
|
|
1791
|
+
def HyperlinkControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1792
|
+
Name: Optional[str] = None,
|
|
1793
|
+
SubName: Optional[str] = None,
|
|
1794
|
+
RegexName: Optional[str] = None,
|
|
1795
|
+
ClassName: Optional[str] = None,
|
|
1796
|
+
AutomationId: Optional[str] = None,
|
|
1797
|
+
Depth: Optional[int] = None,
|
|
1798
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1799
|
+
**searchProperties) -> 'HyperlinkControl':
|
|
1800
|
+
return HyperlinkControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1801
|
+
foundIndex=foundIndex, element=element,
|
|
1802
|
+
Name=Name,
|
|
1803
|
+
SubName=SubName,
|
|
1804
|
+
RegexName=RegexName,
|
|
1805
|
+
ClassName=ClassName,
|
|
1806
|
+
AutomationId=AutomationId,
|
|
1807
|
+
Depth=Depth,
|
|
1808
|
+
Compare=Compare,
|
|
1809
|
+
**searchProperties)
|
|
1810
|
+
|
|
1811
|
+
def ImageControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1812
|
+
Name: Optional[str] = None,
|
|
1813
|
+
SubName: Optional[str] = None,
|
|
1814
|
+
RegexName: Optional[str] = None,
|
|
1815
|
+
ClassName: Optional[str] = None,
|
|
1816
|
+
AutomationId: Optional[str] = None,
|
|
1817
|
+
Depth: Optional[int] = None,
|
|
1818
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1819
|
+
**searchProperties) -> 'ImageControl':
|
|
1820
|
+
return ImageControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1821
|
+
foundIndex=foundIndex, element=element,
|
|
1822
|
+
Name=Name,
|
|
1823
|
+
SubName=SubName,
|
|
1824
|
+
RegexName=RegexName,
|
|
1825
|
+
ClassName=ClassName,
|
|
1826
|
+
AutomationId=AutomationId,
|
|
1827
|
+
Depth=Depth,
|
|
1828
|
+
Compare=Compare,
|
|
1829
|
+
**searchProperties)
|
|
1830
|
+
|
|
1831
|
+
def ListControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1832
|
+
Name: Optional[str] = None,
|
|
1833
|
+
SubName: Optional[str] = None,
|
|
1834
|
+
RegexName: Optional[str] = None,
|
|
1835
|
+
ClassName: Optional[str] = None,
|
|
1836
|
+
AutomationId: Optional[str] = None,
|
|
1837
|
+
Depth: Optional[int] = None,
|
|
1838
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1839
|
+
**searchProperties) -> 'ListControl':
|
|
1840
|
+
return ListControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1841
|
+
foundIndex=foundIndex, element=element,
|
|
1842
|
+
Name=Name,
|
|
1843
|
+
SubName=SubName,
|
|
1844
|
+
RegexName=RegexName,
|
|
1845
|
+
ClassName=ClassName,
|
|
1846
|
+
AutomationId=AutomationId,
|
|
1847
|
+
Depth=Depth,
|
|
1848
|
+
Compare=Compare,
|
|
1849
|
+
**searchProperties)
|
|
1850
|
+
|
|
1851
|
+
def ListItemControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1852
|
+
Name: Optional[str] = None,
|
|
1853
|
+
SubName: Optional[str] = None,
|
|
1854
|
+
RegexName: Optional[str] = None,
|
|
1855
|
+
ClassName: Optional[str] = None,
|
|
1856
|
+
AutomationId: Optional[str] = None,
|
|
1857
|
+
Depth: Optional[int] = None,
|
|
1858
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1859
|
+
**searchProperties) -> 'ListItemControl':
|
|
1860
|
+
return ListItemControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1861
|
+
foundIndex=foundIndex, element=element,
|
|
1862
|
+
Name=Name,
|
|
1863
|
+
SubName=SubName,
|
|
1864
|
+
RegexName=RegexName,
|
|
1865
|
+
ClassName=ClassName,
|
|
1866
|
+
AutomationId=AutomationId,
|
|
1867
|
+
Depth=Depth,
|
|
1868
|
+
Compare=Compare,
|
|
1869
|
+
**searchProperties)
|
|
1870
|
+
|
|
1871
|
+
def MenuControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1872
|
+
Name: Optional[str] = None,
|
|
1873
|
+
SubName: Optional[str] = None,
|
|
1874
|
+
RegexName: Optional[str] = None,
|
|
1875
|
+
ClassName: Optional[str] = None,
|
|
1876
|
+
AutomationId: Optional[str] = None,
|
|
1877
|
+
Depth: Optional[int] = None,
|
|
1878
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1879
|
+
**searchProperties) -> 'MenuControl':
|
|
1880
|
+
return MenuControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1881
|
+
foundIndex=foundIndex, element=element,
|
|
1882
|
+
Name=Name,
|
|
1883
|
+
SubName=SubName,
|
|
1884
|
+
RegexName=RegexName,
|
|
1885
|
+
ClassName=ClassName,
|
|
1886
|
+
AutomationId=AutomationId,
|
|
1887
|
+
Depth=Depth,
|
|
1888
|
+
Compare=Compare,
|
|
1889
|
+
**searchProperties)
|
|
1890
|
+
|
|
1891
|
+
def MenuBarControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1892
|
+
Name: Optional[str] = None,
|
|
1893
|
+
SubName: Optional[str] = None,
|
|
1894
|
+
RegexName: Optional[str] = None,
|
|
1895
|
+
ClassName: Optional[str] = None,
|
|
1896
|
+
AutomationId: Optional[str] = None,
|
|
1897
|
+
Depth: Optional[int] = None,
|
|
1898
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1899
|
+
**searchProperties) -> 'MenuBarControl':
|
|
1900
|
+
return MenuBarControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1901
|
+
foundIndex=foundIndex, element=element,
|
|
1902
|
+
Name=Name,
|
|
1903
|
+
SubName=SubName,
|
|
1904
|
+
RegexName=RegexName,
|
|
1905
|
+
ClassName=ClassName,
|
|
1906
|
+
AutomationId=AutomationId,
|
|
1907
|
+
Depth=Depth,
|
|
1908
|
+
Compare=Compare,
|
|
1909
|
+
**searchProperties)
|
|
1910
|
+
|
|
1911
|
+
def MenuItemControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1912
|
+
Name: Optional[str] = None,
|
|
1913
|
+
SubName: Optional[str] = None,
|
|
1914
|
+
RegexName: Optional[str] = None,
|
|
1915
|
+
ClassName: Optional[str] = None,
|
|
1916
|
+
AutomationId: Optional[str] = None,
|
|
1917
|
+
Depth: Optional[int] = None,
|
|
1918
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1919
|
+
**searchProperties) -> 'MenuItemControl':
|
|
1920
|
+
return MenuItemControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1921
|
+
foundIndex=foundIndex, element=element,
|
|
1922
|
+
Name=Name,
|
|
1923
|
+
SubName=SubName,
|
|
1924
|
+
RegexName=RegexName,
|
|
1925
|
+
ClassName=ClassName,
|
|
1926
|
+
AutomationId=AutomationId,
|
|
1927
|
+
Depth=Depth,
|
|
1928
|
+
Compare=Compare,
|
|
1929
|
+
**searchProperties)
|
|
1930
|
+
|
|
1931
|
+
def PaneControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1932
|
+
Name: Optional[str] = None,
|
|
1933
|
+
SubName: Optional[str] = None,
|
|
1934
|
+
RegexName: Optional[str] = None,
|
|
1935
|
+
ClassName: Optional[str] = None,
|
|
1936
|
+
AutomationId: Optional[str] = None,
|
|
1937
|
+
Depth: Optional[int] = None,
|
|
1938
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1939
|
+
**searchProperties) -> 'PaneControl':
|
|
1940
|
+
return PaneControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1941
|
+
foundIndex=foundIndex, element=element,
|
|
1942
|
+
Name=Name,
|
|
1943
|
+
SubName=SubName,
|
|
1944
|
+
RegexName=RegexName,
|
|
1945
|
+
ClassName=ClassName,
|
|
1946
|
+
AutomationId=AutomationId,
|
|
1947
|
+
Depth=Depth,
|
|
1948
|
+
Compare=Compare,
|
|
1949
|
+
**searchProperties)
|
|
1950
|
+
|
|
1951
|
+
def ProgressBarControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1952
|
+
Name: Optional[str] = None,
|
|
1953
|
+
SubName: Optional[str] = None,
|
|
1954
|
+
RegexName: Optional[str] = None,
|
|
1955
|
+
ClassName: Optional[str] = None,
|
|
1956
|
+
AutomationId: Optional[str] = None,
|
|
1957
|
+
Depth: Optional[int] = None,
|
|
1958
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1959
|
+
**searchProperties) -> 'ProgressBarControl':
|
|
1960
|
+
return ProgressBarControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1961
|
+
foundIndex=foundIndex, element=element,
|
|
1962
|
+
Name=Name,
|
|
1963
|
+
SubName=SubName,
|
|
1964
|
+
RegexName=RegexName,
|
|
1965
|
+
ClassName=ClassName,
|
|
1966
|
+
AutomationId=AutomationId,
|
|
1967
|
+
Depth=Depth,
|
|
1968
|
+
Compare=Compare,
|
|
1969
|
+
**searchProperties)
|
|
1970
|
+
|
|
1971
|
+
def RadioButtonControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1972
|
+
Name: Optional[str] = None,
|
|
1973
|
+
SubName: Optional[str] = None,
|
|
1974
|
+
RegexName: Optional[str] = None,
|
|
1975
|
+
ClassName: Optional[str] = None,
|
|
1976
|
+
AutomationId: Optional[str] = None,
|
|
1977
|
+
Depth: Optional[int] = None,
|
|
1978
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1979
|
+
**searchProperties) -> 'RadioButtonControl':
|
|
1980
|
+
return RadioButtonControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
1981
|
+
foundIndex=foundIndex, element=element,
|
|
1982
|
+
Name=Name,
|
|
1983
|
+
SubName=SubName,
|
|
1984
|
+
RegexName=RegexName,
|
|
1985
|
+
ClassName=ClassName,
|
|
1986
|
+
AutomationId=AutomationId,
|
|
1987
|
+
Depth=Depth,
|
|
1988
|
+
Compare=Compare,
|
|
1989
|
+
**searchProperties)
|
|
1990
|
+
|
|
1991
|
+
def ScrollBarControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
1992
|
+
Name: Optional[str] = None,
|
|
1993
|
+
SubName: Optional[str] = None,
|
|
1994
|
+
RegexName: Optional[str] = None,
|
|
1995
|
+
ClassName: Optional[str] = None,
|
|
1996
|
+
AutomationId: Optional[str] = None,
|
|
1997
|
+
Depth: Optional[int] = None,
|
|
1998
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
1999
|
+
**searchProperties) -> 'ScrollBarControl':
|
|
2000
|
+
return ScrollBarControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2001
|
+
foundIndex=foundIndex, element=element,
|
|
2002
|
+
Name=Name,
|
|
2003
|
+
SubName=SubName,
|
|
2004
|
+
RegexName=RegexName,
|
|
2005
|
+
ClassName=ClassName,
|
|
2006
|
+
AutomationId=AutomationId,
|
|
2007
|
+
Depth=Depth,
|
|
2008
|
+
Compare=Compare,
|
|
2009
|
+
**searchProperties)
|
|
2010
|
+
|
|
2011
|
+
def SemanticZoomControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2012
|
+
Name: Optional[str] = None,
|
|
2013
|
+
SubName: Optional[str] = None,
|
|
2014
|
+
RegexName: Optional[str] = None,
|
|
2015
|
+
ClassName: Optional[str] = None,
|
|
2016
|
+
AutomationId: Optional[str] = None,
|
|
2017
|
+
Depth: Optional[int] = None,
|
|
2018
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2019
|
+
**searchProperties) -> 'SemanticZoomControl':
|
|
2020
|
+
return SemanticZoomControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2021
|
+
foundIndex=foundIndex, element=element,
|
|
2022
|
+
Name=Name,
|
|
2023
|
+
SubName=SubName,
|
|
2024
|
+
RegexName=RegexName,
|
|
2025
|
+
ClassName=ClassName,
|
|
2026
|
+
AutomationId=AutomationId,
|
|
2027
|
+
Depth=Depth,
|
|
2028
|
+
Compare=Compare,
|
|
2029
|
+
**searchProperties)
|
|
2030
|
+
|
|
2031
|
+
def SeparatorControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2032
|
+
Name: Optional[str] = None,
|
|
2033
|
+
SubName: Optional[str] = None,
|
|
2034
|
+
RegexName: Optional[str] = None,
|
|
2035
|
+
ClassName: Optional[str] = None,
|
|
2036
|
+
AutomationId: Optional[str] = None,
|
|
2037
|
+
Depth: Optional[int] = None,
|
|
2038
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2039
|
+
**searchProperties) -> 'SeparatorControl':
|
|
2040
|
+
return SeparatorControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2041
|
+
foundIndex=foundIndex, element=element,
|
|
2042
|
+
Name=Name,
|
|
2043
|
+
SubName=SubName,
|
|
2044
|
+
RegexName=RegexName,
|
|
2045
|
+
ClassName=ClassName,
|
|
2046
|
+
AutomationId=AutomationId,
|
|
2047
|
+
Depth=Depth,
|
|
2048
|
+
Compare=Compare,
|
|
2049
|
+
**searchProperties)
|
|
2050
|
+
|
|
2051
|
+
def SliderControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2052
|
+
Name: Optional[str] = None,
|
|
2053
|
+
SubName: Optional[str] = None,
|
|
2054
|
+
RegexName: Optional[str] = None,
|
|
2055
|
+
ClassName: Optional[str] = None,
|
|
2056
|
+
AutomationId: Optional[str] = None,
|
|
2057
|
+
Depth: Optional[int] = None,
|
|
2058
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2059
|
+
**searchProperties) -> 'SliderControl':
|
|
2060
|
+
return SliderControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2061
|
+
foundIndex=foundIndex, element=element,
|
|
2062
|
+
Name=Name,
|
|
2063
|
+
SubName=SubName,
|
|
2064
|
+
RegexName=RegexName,
|
|
2065
|
+
ClassName=ClassName,
|
|
2066
|
+
AutomationId=AutomationId,
|
|
2067
|
+
Depth=Depth,
|
|
2068
|
+
Compare=Compare,
|
|
2069
|
+
**searchProperties)
|
|
2070
|
+
|
|
2071
|
+
def SpinnerControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2072
|
+
Name: Optional[str] = None,
|
|
2073
|
+
SubName: Optional[str] = None,
|
|
2074
|
+
RegexName: Optional[str] = None,
|
|
2075
|
+
ClassName: Optional[str] = None,
|
|
2076
|
+
AutomationId: Optional[str] = None,
|
|
2077
|
+
Depth: Optional[int] = None,
|
|
2078
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2079
|
+
**searchProperties) -> 'SpinnerControl':
|
|
2080
|
+
return SpinnerControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2081
|
+
foundIndex=foundIndex, element=element,
|
|
2082
|
+
Name=Name,
|
|
2083
|
+
SubName=SubName,
|
|
2084
|
+
RegexName=RegexName,
|
|
2085
|
+
ClassName=ClassName,
|
|
2086
|
+
AutomationId=AutomationId,
|
|
2087
|
+
Depth=Depth,
|
|
2088
|
+
Compare=Compare,
|
|
2089
|
+
**searchProperties)
|
|
2090
|
+
|
|
2091
|
+
def SplitButtonControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2092
|
+
Name: Optional[str] = None,
|
|
2093
|
+
SubName: Optional[str] = None,
|
|
2094
|
+
RegexName: Optional[str] = None,
|
|
2095
|
+
ClassName: Optional[str] = None,
|
|
2096
|
+
AutomationId: Optional[str] = None,
|
|
2097
|
+
Depth: Optional[int] = None,
|
|
2098
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2099
|
+
**searchProperties) -> 'SplitButtonControl':
|
|
2100
|
+
return SplitButtonControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2101
|
+
foundIndex=foundIndex, element=element,
|
|
2102
|
+
Name=Name,
|
|
2103
|
+
SubName=SubName,
|
|
2104
|
+
RegexName=RegexName,
|
|
2105
|
+
ClassName=ClassName,
|
|
2106
|
+
AutomationId=AutomationId,
|
|
2107
|
+
Depth=Depth,
|
|
2108
|
+
Compare=Compare,
|
|
2109
|
+
**searchProperties)
|
|
2110
|
+
|
|
2111
|
+
def StatusBarControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2112
|
+
Name: Optional[str] = None,
|
|
2113
|
+
SubName: Optional[str] = None,
|
|
2114
|
+
RegexName: Optional[str] = None,
|
|
2115
|
+
ClassName: Optional[str] = None,
|
|
2116
|
+
AutomationId: Optional[str] = None,
|
|
2117
|
+
Depth: Optional[int] = None,
|
|
2118
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2119
|
+
**searchProperties) -> 'StatusBarControl':
|
|
2120
|
+
return StatusBarControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2121
|
+
foundIndex=foundIndex, element=element,
|
|
2122
|
+
Name=Name,
|
|
2123
|
+
SubName=SubName,
|
|
2124
|
+
RegexName=RegexName,
|
|
2125
|
+
ClassName=ClassName,
|
|
2126
|
+
AutomationId=AutomationId,
|
|
2127
|
+
Depth=Depth,
|
|
2128
|
+
Compare=Compare,
|
|
2129
|
+
**searchProperties)
|
|
2130
|
+
|
|
2131
|
+
def TabControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2132
|
+
Name: Optional[str] = None,
|
|
2133
|
+
SubName: Optional[str] = None,
|
|
2134
|
+
RegexName: Optional[str] = None,
|
|
2135
|
+
ClassName: Optional[str] = None,
|
|
2136
|
+
AutomationId: Optional[str] = None,
|
|
2137
|
+
Depth: Optional[int] = None,
|
|
2138
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2139
|
+
**searchProperties) -> 'TabControl':
|
|
2140
|
+
return TabControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2141
|
+
foundIndex=foundIndex, element=element,
|
|
2142
|
+
Name=Name,
|
|
2143
|
+
SubName=SubName,
|
|
2144
|
+
RegexName=RegexName,
|
|
2145
|
+
ClassName=ClassName,
|
|
2146
|
+
AutomationId=AutomationId,
|
|
2147
|
+
Depth=Depth,
|
|
2148
|
+
Compare=Compare,
|
|
2149
|
+
**searchProperties)
|
|
2150
|
+
|
|
2151
|
+
def TabItemControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2152
|
+
Name: Optional[str] = None,
|
|
2153
|
+
SubName: Optional[str] = None,
|
|
2154
|
+
RegexName: Optional[str] = None,
|
|
2155
|
+
ClassName: Optional[str] = None,
|
|
2156
|
+
AutomationId: Optional[str] = None,
|
|
2157
|
+
Depth: Optional[int] = None,
|
|
2158
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2159
|
+
**searchProperties) -> 'TabItemControl':
|
|
2160
|
+
return TabItemControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2161
|
+
foundIndex=foundIndex, element=element,
|
|
2162
|
+
Name=Name,
|
|
2163
|
+
SubName=SubName,
|
|
2164
|
+
RegexName=RegexName,
|
|
2165
|
+
ClassName=ClassName,
|
|
2166
|
+
AutomationId=AutomationId,
|
|
2167
|
+
Depth=Depth,
|
|
2168
|
+
Compare=Compare,
|
|
2169
|
+
**searchProperties)
|
|
2170
|
+
|
|
2171
|
+
def TableControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2172
|
+
Name: Optional[str] = None,
|
|
2173
|
+
SubName: Optional[str] = None,
|
|
2174
|
+
RegexName: Optional[str] = None,
|
|
2175
|
+
ClassName: Optional[str] = None,
|
|
2176
|
+
AutomationId: Optional[str] = None,
|
|
2177
|
+
Depth: Optional[int] = None,
|
|
2178
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2179
|
+
**searchProperties) -> 'TableControl':
|
|
2180
|
+
return TableControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2181
|
+
foundIndex=foundIndex, element=element,
|
|
2182
|
+
Name=Name,
|
|
2183
|
+
SubName=SubName,
|
|
2184
|
+
RegexName=RegexName,
|
|
2185
|
+
ClassName=ClassName,
|
|
2186
|
+
AutomationId=AutomationId,
|
|
2187
|
+
Depth=Depth,
|
|
2188
|
+
Compare=Compare,
|
|
2189
|
+
**searchProperties)
|
|
2190
|
+
|
|
2191
|
+
def TextControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2192
|
+
Name: Optional[str] = None,
|
|
2193
|
+
SubName: Optional[str] = None,
|
|
2194
|
+
RegexName: Optional[str] = None,
|
|
2195
|
+
ClassName: Optional[str] = None,
|
|
2196
|
+
AutomationId: Optional[str] = None,
|
|
2197
|
+
Depth: Optional[int] = None,
|
|
2198
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2199
|
+
**searchProperties) -> 'TextControl':
|
|
2200
|
+
return TextControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2201
|
+
foundIndex=foundIndex, element=element,
|
|
2202
|
+
Name=Name,
|
|
2203
|
+
SubName=SubName,
|
|
2204
|
+
RegexName=RegexName,
|
|
2205
|
+
ClassName=ClassName,
|
|
2206
|
+
AutomationId=AutomationId,
|
|
2207
|
+
Depth=Depth,
|
|
2208
|
+
Compare=Compare,
|
|
2209
|
+
**searchProperties)
|
|
2210
|
+
|
|
2211
|
+
def ThumbControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2212
|
+
Name: Optional[str] = None,
|
|
2213
|
+
SubName: Optional[str] = None,
|
|
2214
|
+
RegexName: Optional[str] = None,
|
|
2215
|
+
ClassName: Optional[str] = None,
|
|
2216
|
+
AutomationId: Optional[str] = None,
|
|
2217
|
+
Depth: Optional[int] = None,
|
|
2218
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2219
|
+
**searchProperties) -> 'ThumbControl':
|
|
2220
|
+
return ThumbControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2221
|
+
foundIndex=foundIndex, element=element,
|
|
2222
|
+
Name=Name,
|
|
2223
|
+
SubName=SubName,
|
|
2224
|
+
RegexName=RegexName,
|
|
2225
|
+
ClassName=ClassName,
|
|
2226
|
+
AutomationId=AutomationId,
|
|
2227
|
+
Depth=Depth,
|
|
2228
|
+
Compare=Compare,
|
|
2229
|
+
**searchProperties)
|
|
2230
|
+
|
|
2231
|
+
def TitleBarControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2232
|
+
Name: Optional[str] = None,
|
|
2233
|
+
SubName: Optional[str] = None,
|
|
2234
|
+
RegexName: Optional[str] = None,
|
|
2235
|
+
ClassName: Optional[str] = None,
|
|
2236
|
+
AutomationId: Optional[str] = None,
|
|
2237
|
+
Depth: Optional[int] = None,
|
|
2238
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2239
|
+
**searchProperties) -> 'TitleBarControl':
|
|
2240
|
+
return TitleBarControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2241
|
+
foundIndex=foundIndex, element=element,
|
|
2242
|
+
Name=Name,
|
|
2243
|
+
SubName=SubName,
|
|
2244
|
+
RegexName=RegexName,
|
|
2245
|
+
ClassName=ClassName,
|
|
2246
|
+
AutomationId=AutomationId,
|
|
2247
|
+
Depth=Depth,
|
|
2248
|
+
Compare=Compare,
|
|
2249
|
+
**searchProperties)
|
|
2250
|
+
|
|
2251
|
+
def ToolBarControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2252
|
+
Name: Optional[str] = None,
|
|
2253
|
+
SubName: Optional[str] = None,
|
|
2254
|
+
RegexName: Optional[str] = None,
|
|
2255
|
+
ClassName: Optional[str] = None,
|
|
2256
|
+
AutomationId: Optional[str] = None,
|
|
2257
|
+
Depth: Optional[int] = None,
|
|
2258
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2259
|
+
**searchProperties) -> 'ToolBarControl':
|
|
2260
|
+
return ToolBarControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2261
|
+
foundIndex=foundIndex, element=element,
|
|
2262
|
+
Name=Name,
|
|
2263
|
+
SubName=SubName,
|
|
2264
|
+
RegexName=RegexName,
|
|
2265
|
+
ClassName=ClassName,
|
|
2266
|
+
AutomationId=AutomationId,
|
|
2267
|
+
Depth=Depth,
|
|
2268
|
+
Compare=Compare,
|
|
2269
|
+
**searchProperties)
|
|
2270
|
+
|
|
2271
|
+
def ToolTipControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2272
|
+
Name: Optional[str] = None,
|
|
2273
|
+
SubName: Optional[str] = None,
|
|
2274
|
+
RegexName: Optional[str] = None,
|
|
2275
|
+
ClassName: Optional[str] = None,
|
|
2276
|
+
AutomationId: Optional[str] = None,
|
|
2277
|
+
Depth: Optional[int] = None,
|
|
2278
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2279
|
+
**searchProperties) -> 'ToolTipControl':
|
|
2280
|
+
return ToolTipControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2281
|
+
foundIndex=foundIndex, element=element,
|
|
2282
|
+
Name=Name,
|
|
2283
|
+
SubName=SubName,
|
|
2284
|
+
RegexName=RegexName,
|
|
2285
|
+
ClassName=ClassName,
|
|
2286
|
+
AutomationId=AutomationId,
|
|
2287
|
+
Depth=Depth,
|
|
2288
|
+
Compare=Compare,
|
|
2289
|
+
**searchProperties)
|
|
2290
|
+
|
|
2291
|
+
def TreeControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2292
|
+
Name: Optional[str] = None,
|
|
2293
|
+
SubName: Optional[str] = None,
|
|
2294
|
+
RegexName: Optional[str] = None,
|
|
2295
|
+
ClassName: Optional[str] = None,
|
|
2296
|
+
AutomationId: Optional[str] = None,
|
|
2297
|
+
Depth: Optional[int] = None,
|
|
2298
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2299
|
+
**searchProperties) -> 'TreeControl':
|
|
2300
|
+
return TreeControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2301
|
+
foundIndex=foundIndex, element=element,
|
|
2302
|
+
Name=Name,
|
|
2303
|
+
SubName=SubName,
|
|
2304
|
+
RegexName=RegexName,
|
|
2305
|
+
ClassName=ClassName,
|
|
2306
|
+
AutomationId=AutomationId,
|
|
2307
|
+
Depth=Depth,
|
|
2308
|
+
Compare=Compare,
|
|
2309
|
+
**searchProperties)
|
|
2310
|
+
|
|
2311
|
+
def TreeItemControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2312
|
+
Name: Optional[str] = None,
|
|
2313
|
+
SubName: Optional[str] = None,
|
|
2314
|
+
RegexName: Optional[str] = None,
|
|
2315
|
+
ClassName: Optional[str] = None,
|
|
2316
|
+
AutomationId: Optional[str] = None,
|
|
2317
|
+
Depth: Optional[int] = None,
|
|
2318
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2319
|
+
**searchProperties) -> 'TreeItemControl':
|
|
2320
|
+
return TreeItemControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2321
|
+
foundIndex=foundIndex, element=element,
|
|
2322
|
+
Name=Name,
|
|
2323
|
+
SubName=SubName,
|
|
2324
|
+
RegexName=RegexName,
|
|
2325
|
+
ClassName=ClassName,
|
|
2326
|
+
AutomationId=AutomationId,
|
|
2327
|
+
Depth=Depth,
|
|
2328
|
+
Compare=Compare,
|
|
2329
|
+
**searchProperties)
|
|
2330
|
+
|
|
2331
|
+
def WindowControl(self, searchDepth=0xFFFFFFFF, searchInterval=SEARCH_INTERVAL, foundIndex=1, element=0,
|
|
2332
|
+
Name: Optional[str] = None,
|
|
2333
|
+
SubName: Optional[str] = None,
|
|
2334
|
+
RegexName: Optional[str] = None,
|
|
2335
|
+
ClassName: Optional[str] = None,
|
|
2336
|
+
AutomationId: Optional[str] = None,
|
|
2337
|
+
Depth: Optional[int] = None,
|
|
2338
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2339
|
+
**searchProperties) -> 'WindowControl':
|
|
2340
|
+
return WindowControl(searchFromControl=self, searchDepth=searchDepth, searchInterval=searchInterval,
|
|
2341
|
+
foundIndex=foundIndex, element=element,
|
|
2342
|
+
Name=Name,
|
|
2343
|
+
SubName=SubName,
|
|
2344
|
+
RegexName=RegexName,
|
|
2345
|
+
ClassName=ClassName,
|
|
2346
|
+
AutomationId=AutomationId,
|
|
2347
|
+
Depth=Depth,
|
|
2348
|
+
Compare=Compare,
|
|
2349
|
+
**searchProperties)
|
|
2350
|
+
|
|
2351
|
+
|
|
2352
|
+
class AppBarControl(Control):
|
|
2353
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2354
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2355
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2356
|
+
foundIndex: int = 1,
|
|
2357
|
+
element=None,
|
|
2358
|
+
Name: Optional[str] = None,
|
|
2359
|
+
SubName: Optional[str] = None,
|
|
2360
|
+
RegexName: Optional[str] = None,
|
|
2361
|
+
ClassName: Optional[str] = None,
|
|
2362
|
+
AutomationId: Optional[str] = None,
|
|
2363
|
+
Depth: Optional[int] = None,
|
|
2364
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2365
|
+
**searchProperties):
|
|
2366
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2367
|
+
ControlType=ControlType.AppBarControl,
|
|
2368
|
+
Name=Name,
|
|
2369
|
+
SubName=SubName,
|
|
2370
|
+
RegexName=RegexName,
|
|
2371
|
+
ClassName=ClassName,
|
|
2372
|
+
AutomationId=AutomationId,
|
|
2373
|
+
Depth=Depth,
|
|
2374
|
+
Compare=Compare,
|
|
2375
|
+
**searchProperties)
|
|
2376
|
+
|
|
2377
|
+
|
|
2378
|
+
class ButtonControl(Control):
|
|
2379
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2380
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2381
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2382
|
+
foundIndex: int = 1,
|
|
2383
|
+
element=None,
|
|
2384
|
+
Name: Optional[str] = None,
|
|
2385
|
+
SubName: Optional[str] = None,
|
|
2386
|
+
RegexName: Optional[str] = None,
|
|
2387
|
+
ClassName: Optional[str] = None,
|
|
2388
|
+
AutomationId: Optional[str] = None,
|
|
2389
|
+
Depth: Optional[int] = None,
|
|
2390
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2391
|
+
**searchProperties):
|
|
2392
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2393
|
+
ControlType=ControlType.ButtonControl,
|
|
2394
|
+
Name=Name,
|
|
2395
|
+
SubName=SubName,
|
|
2396
|
+
RegexName=RegexName,
|
|
2397
|
+
ClassName=ClassName,
|
|
2398
|
+
AutomationId=AutomationId,
|
|
2399
|
+
Depth=Depth,
|
|
2400
|
+
Compare=Compare,
|
|
2401
|
+
**searchProperties)
|
|
2402
|
+
|
|
2403
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
2404
|
+
"""
|
|
2405
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2406
|
+
"""
|
|
2407
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
2408
|
+
|
|
2409
|
+
def GetInvokePattern(self) -> InvokePattern:
|
|
2410
|
+
"""
|
|
2411
|
+
Return `InvokePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2412
|
+
"""
|
|
2413
|
+
return self.GetPattern(PatternId.InvokePattern)
|
|
2414
|
+
|
|
2415
|
+
def GetTogglePattern(self) -> TogglePattern:
|
|
2416
|
+
"""
|
|
2417
|
+
Return `TogglePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2418
|
+
"""
|
|
2419
|
+
return self.GetPattern(PatternId.TogglePattern)
|
|
2420
|
+
|
|
2421
|
+
|
|
2422
|
+
class CalendarControl(Control):
|
|
2423
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2424
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2425
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2426
|
+
foundIndex: int = 1,
|
|
2427
|
+
element=None,
|
|
2428
|
+
Name: Optional[str] = None,
|
|
2429
|
+
SubName: Optional[str] = None,
|
|
2430
|
+
RegexName: Optional[str] = None,
|
|
2431
|
+
ClassName: Optional[str] = None,
|
|
2432
|
+
AutomationId: Optional[str] = None,
|
|
2433
|
+
Depth: Optional[int] = None,
|
|
2434
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2435
|
+
**searchProperties):
|
|
2436
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2437
|
+
ControlType=ControlType.CalendarControl,
|
|
2438
|
+
Name=Name,
|
|
2439
|
+
SubName=SubName,
|
|
2440
|
+
RegexName=RegexName,
|
|
2441
|
+
ClassName=ClassName,
|
|
2442
|
+
AutomationId=AutomationId,
|
|
2443
|
+
Depth=Depth,
|
|
2444
|
+
Compare=Compare,
|
|
2445
|
+
**searchProperties)
|
|
2446
|
+
|
|
2447
|
+
def GetGridPattern(self) -> GridPattern:
|
|
2448
|
+
"""
|
|
2449
|
+
Return `GridPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
2450
|
+
"""
|
|
2451
|
+
return self.GetPattern(PatternId.GridPattern)
|
|
2452
|
+
|
|
2453
|
+
def GetTablePattern(self) -> TablePattern:
|
|
2454
|
+
"""
|
|
2455
|
+
Return `TablePattern` if it supports the pattern else None(Must support according to MSDN).
|
|
2456
|
+
"""
|
|
2457
|
+
return self.GetPattern(PatternId.TablePattern)
|
|
2458
|
+
|
|
2459
|
+
def GetScrollPattern(self) -> ScrollPattern:
|
|
2460
|
+
"""
|
|
2461
|
+
Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2462
|
+
"""
|
|
2463
|
+
return self.GetPattern(PatternId.ScrollPattern)
|
|
2464
|
+
|
|
2465
|
+
def GetSelectionPattern(self) -> SelectionPattern:
|
|
2466
|
+
"""
|
|
2467
|
+
Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2468
|
+
"""
|
|
2469
|
+
return self.GetPattern(PatternId.SelectionPattern)
|
|
2470
|
+
|
|
2471
|
+
|
|
2472
|
+
class CheckBoxControl(Control):
|
|
2473
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2474
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2475
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2476
|
+
foundIndex: int = 1,
|
|
2477
|
+
element=None,
|
|
2478
|
+
Name: Optional[str] = None,
|
|
2479
|
+
SubName: Optional[str] = None,
|
|
2480
|
+
RegexName: Optional[str] = None,
|
|
2481
|
+
ClassName: Optional[str] = None,
|
|
2482
|
+
AutomationId: Optional[str] = None,
|
|
2483
|
+
Depth: Optional[int] = None,
|
|
2484
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2485
|
+
**searchProperties):
|
|
2486
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2487
|
+
ControlType=ControlType.CheckBoxControl,
|
|
2488
|
+
Name=Name,
|
|
2489
|
+
SubName=SubName,
|
|
2490
|
+
RegexName=RegexName,
|
|
2491
|
+
ClassName=ClassName,
|
|
2492
|
+
AutomationId=AutomationId,
|
|
2493
|
+
Depth=Depth,
|
|
2494
|
+
Compare=Compare,
|
|
2495
|
+
**searchProperties)
|
|
2496
|
+
|
|
2497
|
+
def GetTogglePattern(self) -> TogglePattern:
|
|
2498
|
+
"""
|
|
2499
|
+
Return `TogglePattern` if it supports the pattern else None(Must support according to MSDN).
|
|
2500
|
+
"""
|
|
2501
|
+
return self.GetPattern(PatternId.TogglePattern)
|
|
2502
|
+
|
|
2503
|
+
def SetChecked(self, checked: bool) -> bool:
|
|
2504
|
+
'''Return True if set successfully'''
|
|
2505
|
+
tp = self.GetTogglePattern()
|
|
2506
|
+
if tp:
|
|
2507
|
+
return tp.SetToggleState(ToggleState.On if checked else ToggleState.Off)
|
|
2508
|
+
return False
|
|
2509
|
+
|
|
2510
|
+
|
|
2511
|
+
class ComboBoxControl(Control):
|
|
2512
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2513
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2514
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2515
|
+
foundIndex: int = 1,
|
|
2516
|
+
element=None,
|
|
2517
|
+
Name: Optional[str] = None,
|
|
2518
|
+
SubName: Optional[str] = None,
|
|
2519
|
+
RegexName: Optional[str] = None,
|
|
2520
|
+
ClassName: Optional[str] = None,
|
|
2521
|
+
AutomationId: Optional[str] = None,
|
|
2522
|
+
Depth: Optional[int] = None,
|
|
2523
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2524
|
+
**searchProperties):
|
|
2525
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2526
|
+
ControlType=ControlType.ComboBoxControl,
|
|
2527
|
+
Name=Name,
|
|
2528
|
+
SubName=SubName,
|
|
2529
|
+
RegexName=RegexName,
|
|
2530
|
+
ClassName=ClassName,
|
|
2531
|
+
AutomationId=AutomationId,
|
|
2532
|
+
Depth=Depth,
|
|
2533
|
+
Compare=Compare,
|
|
2534
|
+
**searchProperties)
|
|
2535
|
+
|
|
2536
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
2537
|
+
"""
|
|
2538
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Must support according to MSDN).
|
|
2539
|
+
"""
|
|
2540
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
2541
|
+
|
|
2542
|
+
def GetSelectionPattern(self) -> SelectionPattern:
|
|
2543
|
+
"""
|
|
2544
|
+
Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2545
|
+
"""
|
|
2546
|
+
return self.GetPattern(PatternId.SelectionPattern)
|
|
2547
|
+
|
|
2548
|
+
def GetValuePattern(self) -> ValuePattern:
|
|
2549
|
+
"""
|
|
2550
|
+
Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2551
|
+
"""
|
|
2552
|
+
return self.GetPattern(PatternId.ValuePattern)
|
|
2553
|
+
|
|
2554
|
+
def Select(self, itemName: str = '', condition: Optional[Callable[[str], bool]] = None, simulateMove: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> bool:
|
|
2555
|
+
"""
|
|
2556
|
+
Show combobox's popup menu and select a item by name.
|
|
2557
|
+
itemName: str.
|
|
2558
|
+
condition: Callable[[str], bool], function(comboBoxItemName: str) -> bool, if condition is valid, ignore itemName.
|
|
2559
|
+
waitTime: float.
|
|
2560
|
+
Some comboboxs doesn't support SelectionPattern, here is a workaround.
|
|
2561
|
+
This method tries to add selection support.
|
|
2562
|
+
It may not work for some comboboxes, such as comboboxes in older Qt version.
|
|
2563
|
+
If it doesn't work, you should write your own version Select, or it doesn't support selection at all.
|
|
2564
|
+
"""
|
|
2565
|
+
expandCollapsePattern = self.GetExpandCollapsePattern()
|
|
2566
|
+
if expandCollapsePattern:
|
|
2567
|
+
expandCollapsePattern.Expand()
|
|
2568
|
+
else:
|
|
2569
|
+
# Windows Form's ComboBoxControl doesn't support ExpandCollapsePattern
|
|
2570
|
+
self.Click(x=-10, ratioY=0.5, simulateMove=simulateMove)
|
|
2571
|
+
find = False
|
|
2572
|
+
if condition:
|
|
2573
|
+
listItemControl = self.ListItemControl(Compare=lambda c, d: condition(c.Name))
|
|
2574
|
+
else:
|
|
2575
|
+
listItemControl = self.ListItemControl(Name=itemName)
|
|
2576
|
+
if listItemControl.Exists(1):
|
|
2577
|
+
scrollItemPattern = listItemControl.GetScrollItemPattern()
|
|
2578
|
+
if scrollItemPattern:
|
|
2579
|
+
scrollItemPattern.ScrollIntoView(waitTime=0.1)
|
|
2580
|
+
listItemControl.Click(simulateMove=simulateMove, waitTime=waitTime)
|
|
2581
|
+
find = True
|
|
2582
|
+
else:
|
|
2583
|
+
# some ComboBox's popup window is a child of root control
|
|
2584
|
+
listControl = ListControl(searchDepth=1)
|
|
2585
|
+
if listControl.Exists(1):
|
|
2586
|
+
if condition:
|
|
2587
|
+
listItemControl = listControl.ListItemControl(Compare=lambda c, d: condition(c.Name))
|
|
2588
|
+
else:
|
|
2589
|
+
listItemControl = listControl.ListItemControl(Name=itemName)
|
|
2590
|
+
if listItemControl.Exists(0, 0):
|
|
2591
|
+
scrollItemPattern = listItemControl.GetScrollItemPattern()
|
|
2592
|
+
if scrollItemPattern:
|
|
2593
|
+
scrollItemPattern.ScrollIntoView(waitTime=0.1)
|
|
2594
|
+
listItemControl.Click(simulateMove=simulateMove, waitTime=waitTime)
|
|
2595
|
+
find = True
|
|
2596
|
+
if not find:
|
|
2597
|
+
Logger.ColorfullyLog('Can\'t find <Color=Cyan>{}</Color> in ComboBoxControl or it does not support selection.'.format(itemName), ConsoleColor.Yellow)
|
|
2598
|
+
if expandCollapsePattern:
|
|
2599
|
+
expandCollapsePattern.Collapse(waitTime)
|
|
2600
|
+
else:
|
|
2601
|
+
self.Click(x=-10, ratioY=0.5, simulateMove=simulateMove, waitTime=waitTime)
|
|
2602
|
+
return find
|
|
2603
|
+
|
|
2604
|
+
|
|
2605
|
+
class CustomControl(Control):
|
|
2606
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2607
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2608
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2609
|
+
foundIndex: int = 1,
|
|
2610
|
+
element=None,
|
|
2611
|
+
Name: Optional[str] = None,
|
|
2612
|
+
SubName: Optional[str] = None,
|
|
2613
|
+
RegexName: Optional[str] = None,
|
|
2614
|
+
ClassName: Optional[str] = None,
|
|
2615
|
+
AutomationId: Optional[str] = None,
|
|
2616
|
+
Depth: Optional[int] = None,
|
|
2617
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2618
|
+
**searchProperties):
|
|
2619
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2620
|
+
ControlType=ControlType.CustomControl,
|
|
2621
|
+
Name=Name,
|
|
2622
|
+
SubName=SubName,
|
|
2623
|
+
RegexName=RegexName,
|
|
2624
|
+
ClassName=ClassName,
|
|
2625
|
+
AutomationId=AutomationId,
|
|
2626
|
+
Depth=Depth,
|
|
2627
|
+
Compare=Compare,
|
|
2628
|
+
**searchProperties)
|
|
2629
|
+
|
|
2630
|
+
|
|
2631
|
+
class DataGridControl(Control):
|
|
2632
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2633
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2634
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2635
|
+
foundIndex: int = 1,
|
|
2636
|
+
element=None,
|
|
2637
|
+
Name: Optional[str] = None,
|
|
2638
|
+
SubName: Optional[str] = None,
|
|
2639
|
+
RegexName: Optional[str] = None,
|
|
2640
|
+
ClassName: Optional[str] = None,
|
|
2641
|
+
AutomationId: Optional[str] = None,
|
|
2642
|
+
Depth: Optional[int] = None,
|
|
2643
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2644
|
+
**searchProperties):
|
|
2645
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2646
|
+
ControlType=ControlType.DataGridControl,
|
|
2647
|
+
Name=Name,
|
|
2648
|
+
SubName=SubName,
|
|
2649
|
+
RegexName=RegexName,
|
|
2650
|
+
ClassName=ClassName,
|
|
2651
|
+
AutomationId=AutomationId,
|
|
2652
|
+
Depth=Depth,
|
|
2653
|
+
Compare=Compare,
|
|
2654
|
+
**searchProperties)
|
|
2655
|
+
|
|
2656
|
+
def GetGridPattern(self) -> GridPattern:
|
|
2657
|
+
"""
|
|
2658
|
+
Return `GridPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
2659
|
+
"""
|
|
2660
|
+
return self.GetPattern(PatternId.GridPattern)
|
|
2661
|
+
|
|
2662
|
+
def GetScrollPattern(self) -> ScrollPattern:
|
|
2663
|
+
"""
|
|
2664
|
+
Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2665
|
+
"""
|
|
2666
|
+
return self.GetPattern(PatternId.ScrollPattern)
|
|
2667
|
+
|
|
2668
|
+
def GetSelectionPattern(self) -> SelectionPattern:
|
|
2669
|
+
"""
|
|
2670
|
+
Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2671
|
+
"""
|
|
2672
|
+
return self.GetPattern(PatternId.SelectionPattern)
|
|
2673
|
+
|
|
2674
|
+
def GetTablePattern(self) -> TablePattern:
|
|
2675
|
+
"""
|
|
2676
|
+
Return `TablePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2677
|
+
"""
|
|
2678
|
+
return self.GetPattern(PatternId.TablePattern)
|
|
2679
|
+
|
|
2680
|
+
|
|
2681
|
+
class DataItemControl(Control):
|
|
2682
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2683
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2684
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2685
|
+
foundIndex: int = 1,
|
|
2686
|
+
element=None,
|
|
2687
|
+
Name: Optional[str] = None,
|
|
2688
|
+
SubName: Optional[str] = None,
|
|
2689
|
+
RegexName: Optional[str] = None,
|
|
2690
|
+
ClassName: Optional[str] = None,
|
|
2691
|
+
AutomationId: Optional[str] = None,
|
|
2692
|
+
Depth: Optional[int] = None,
|
|
2693
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2694
|
+
**searchProperties):
|
|
2695
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2696
|
+
ControlType=ControlType.DataItemControl,
|
|
2697
|
+
Name=Name,
|
|
2698
|
+
SubName=SubName,
|
|
2699
|
+
RegexName=RegexName,
|
|
2700
|
+
ClassName=ClassName,
|
|
2701
|
+
AutomationId=AutomationId,
|
|
2702
|
+
Depth=Depth,
|
|
2703
|
+
Compare=Compare,
|
|
2704
|
+
**searchProperties)
|
|
2705
|
+
|
|
2706
|
+
def GetSelectionItemPattern(self) -> SelectionItemPattern:
|
|
2707
|
+
"""
|
|
2708
|
+
Return `SelectionItemPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
2709
|
+
"""
|
|
2710
|
+
return self.GetPattern(PatternId.SelectionItemPattern)
|
|
2711
|
+
|
|
2712
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
2713
|
+
"""
|
|
2714
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2715
|
+
"""
|
|
2716
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
2717
|
+
|
|
2718
|
+
def GetGridItemPattern(self) -> GridItemPattern:
|
|
2719
|
+
"""
|
|
2720
|
+
Return `GridItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2721
|
+
"""
|
|
2722
|
+
return self.GetPattern(PatternId.GridItemPattern)
|
|
2723
|
+
|
|
2724
|
+
def GetScrollItemPattern(self) -> ScrollItemPattern:
|
|
2725
|
+
"""
|
|
2726
|
+
Return `ScrollItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2727
|
+
"""
|
|
2728
|
+
return self.GetPattern(PatternId.ScrollItemPattern)
|
|
2729
|
+
|
|
2730
|
+
def GetTableItemPattern(self) -> TableItemPattern:
|
|
2731
|
+
"""
|
|
2732
|
+
Return `TableItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2733
|
+
"""
|
|
2734
|
+
return self.GetPattern(PatternId.TableItemPattern)
|
|
2735
|
+
|
|
2736
|
+
def GetTogglePattern(self) -> TogglePattern:
|
|
2737
|
+
"""
|
|
2738
|
+
Return `TogglePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2739
|
+
"""
|
|
2740
|
+
return self.GetPattern(PatternId.TogglePattern)
|
|
2741
|
+
|
|
2742
|
+
def GetValuePattern(self) -> ValuePattern:
|
|
2743
|
+
"""
|
|
2744
|
+
Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2745
|
+
"""
|
|
2746
|
+
return self.GetPattern(PatternId.ValuePattern)
|
|
2747
|
+
|
|
2748
|
+
|
|
2749
|
+
class DocumentControl(Control):
|
|
2750
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2751
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2752
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2753
|
+
foundIndex: int = 1,
|
|
2754
|
+
element=None,
|
|
2755
|
+
Name: Optional[str] = None,
|
|
2756
|
+
SubName: Optional[str] = None,
|
|
2757
|
+
RegexName: Optional[str] = None,
|
|
2758
|
+
ClassName: Optional[str] = None,
|
|
2759
|
+
AutomationId: Optional[str] = None,
|
|
2760
|
+
Depth: Optional[int] = None,
|
|
2761
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2762
|
+
**searchProperties):
|
|
2763
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2764
|
+
ControlType=ControlType.DocumentControl,
|
|
2765
|
+
Name=Name,
|
|
2766
|
+
SubName=SubName,
|
|
2767
|
+
RegexName=RegexName,
|
|
2768
|
+
ClassName=ClassName,
|
|
2769
|
+
AutomationId=AutomationId,
|
|
2770
|
+
Depth=Depth,
|
|
2771
|
+
Compare=Compare,
|
|
2772
|
+
**searchProperties)
|
|
2773
|
+
|
|
2774
|
+
def GetTextPattern(self) -> TextPattern:
|
|
2775
|
+
"""
|
|
2776
|
+
Return `TextPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
2777
|
+
"""
|
|
2778
|
+
return self.GetPattern(PatternId.TextPattern)
|
|
2779
|
+
|
|
2780
|
+
def GetScrollPattern(self) -> ScrollPattern:
|
|
2781
|
+
"""
|
|
2782
|
+
Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2783
|
+
"""
|
|
2784
|
+
return self.GetPattern(PatternId.ScrollPattern)
|
|
2785
|
+
|
|
2786
|
+
def GetValuePattern(self) -> ValuePattern:
|
|
2787
|
+
"""
|
|
2788
|
+
Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2789
|
+
"""
|
|
2790
|
+
return self.GetPattern(PatternId.ValuePattern)
|
|
2791
|
+
|
|
2792
|
+
|
|
2793
|
+
class EditControl(Control):
|
|
2794
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2795
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2796
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2797
|
+
foundIndex: int = 1,
|
|
2798
|
+
element=None,
|
|
2799
|
+
Name: Optional[str] = None,
|
|
2800
|
+
SubName: Optional[str] = None,
|
|
2801
|
+
RegexName: Optional[str] = None,
|
|
2802
|
+
ClassName: Optional[str] = None,
|
|
2803
|
+
AutomationId: Optional[str] = None,
|
|
2804
|
+
Depth: Optional[int] = None,
|
|
2805
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2806
|
+
**searchProperties):
|
|
2807
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2808
|
+
ControlType=ControlType.EditControl,
|
|
2809
|
+
Name=Name,
|
|
2810
|
+
SubName=SubName,
|
|
2811
|
+
RegexName=RegexName,
|
|
2812
|
+
ClassName=ClassName,
|
|
2813
|
+
AutomationId=AutomationId,
|
|
2814
|
+
Depth=Depth,
|
|
2815
|
+
Compare=Compare,
|
|
2816
|
+
**searchProperties)
|
|
2817
|
+
|
|
2818
|
+
def GetRangeValuePattern(self) -> RangeValuePattern:
|
|
2819
|
+
"""
|
|
2820
|
+
Return `RangeValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2821
|
+
"""
|
|
2822
|
+
return self.GetPattern(PatternId.RangeValuePattern)
|
|
2823
|
+
|
|
2824
|
+
def GetTextPattern(self) -> TextPattern:
|
|
2825
|
+
"""
|
|
2826
|
+
Return `TextPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2827
|
+
"""
|
|
2828
|
+
return self.GetPattern(PatternId.TextPattern)
|
|
2829
|
+
|
|
2830
|
+
def GetValuePattern(self) -> ValuePattern:
|
|
2831
|
+
"""
|
|
2832
|
+
Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2833
|
+
"""
|
|
2834
|
+
return self.GetPattern(PatternId.ValuePattern)
|
|
2835
|
+
|
|
2836
|
+
|
|
2837
|
+
class GroupControl(Control):
|
|
2838
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2839
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2840
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2841
|
+
foundIndex: int = 1,
|
|
2842
|
+
element=None,
|
|
2843
|
+
Name: Optional[str] = None,
|
|
2844
|
+
SubName: Optional[str] = None,
|
|
2845
|
+
RegexName: Optional[str] = None,
|
|
2846
|
+
ClassName: Optional[str] = None,
|
|
2847
|
+
AutomationId: Optional[str] = None,
|
|
2848
|
+
Depth: Optional[int] = None,
|
|
2849
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2850
|
+
**searchProperties):
|
|
2851
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2852
|
+
ControlType=ControlType.GroupControl,
|
|
2853
|
+
Name=Name,
|
|
2854
|
+
SubName=SubName,
|
|
2855
|
+
RegexName=RegexName,
|
|
2856
|
+
ClassName=ClassName,
|
|
2857
|
+
AutomationId=AutomationId,
|
|
2858
|
+
Depth=Depth,
|
|
2859
|
+
Compare=Compare,
|
|
2860
|
+
**searchProperties)
|
|
2861
|
+
|
|
2862
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
2863
|
+
"""
|
|
2864
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2865
|
+
"""
|
|
2866
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
2867
|
+
|
|
2868
|
+
|
|
2869
|
+
class HeaderControl(Control):
|
|
2870
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2871
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2872
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2873
|
+
foundIndex: int = 1,
|
|
2874
|
+
element=None,
|
|
2875
|
+
Name: Optional[str] = None,
|
|
2876
|
+
SubName: Optional[str] = None,
|
|
2877
|
+
RegexName: Optional[str] = None,
|
|
2878
|
+
ClassName: Optional[str] = None,
|
|
2879
|
+
AutomationId: Optional[str] = None,
|
|
2880
|
+
Depth: Optional[int] = None,
|
|
2881
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2882
|
+
**searchProperties):
|
|
2883
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2884
|
+
ControlType=ControlType.HeaderControl,
|
|
2885
|
+
Name=Name,
|
|
2886
|
+
SubName=SubName,
|
|
2887
|
+
RegexName=RegexName,
|
|
2888
|
+
ClassName=ClassName,
|
|
2889
|
+
AutomationId=AutomationId,
|
|
2890
|
+
Depth=Depth,
|
|
2891
|
+
Compare=Compare,
|
|
2892
|
+
**searchProperties)
|
|
2893
|
+
|
|
2894
|
+
def GetTransformPattern(self) -> TransformPattern:
|
|
2895
|
+
"""
|
|
2896
|
+
Return `TransformPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2897
|
+
"""
|
|
2898
|
+
return self.GetPattern(PatternId.TransformPattern)
|
|
2899
|
+
|
|
2900
|
+
|
|
2901
|
+
class HeaderItemControl(Control):
|
|
2902
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2903
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2904
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2905
|
+
foundIndex: int = 1,
|
|
2906
|
+
element=None,
|
|
2907
|
+
Name: Optional[str] = None,
|
|
2908
|
+
SubName: Optional[str] = None,
|
|
2909
|
+
RegexName: Optional[str] = None,
|
|
2910
|
+
ClassName: Optional[str] = None,
|
|
2911
|
+
AutomationId: Optional[str] = None,
|
|
2912
|
+
Depth: Optional[int] = None,
|
|
2913
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2914
|
+
**searchProperties):
|
|
2915
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2916
|
+
ControlType=ControlType.HeaderItemControl,
|
|
2917
|
+
Name=Name,
|
|
2918
|
+
SubName=SubName,
|
|
2919
|
+
RegexName=RegexName,
|
|
2920
|
+
ClassName=ClassName,
|
|
2921
|
+
AutomationId=AutomationId,
|
|
2922
|
+
Depth=Depth,
|
|
2923
|
+
Compare=Compare,
|
|
2924
|
+
**searchProperties)
|
|
2925
|
+
|
|
2926
|
+
def GetInvokePattern(self) -> InvokePattern:
|
|
2927
|
+
"""
|
|
2928
|
+
Return `InvokePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2929
|
+
"""
|
|
2930
|
+
return self.GetPattern(PatternId.InvokePattern)
|
|
2931
|
+
|
|
2932
|
+
def GetTransformPattern(self) -> TransformPattern:
|
|
2933
|
+
"""
|
|
2934
|
+
Return `TransformPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2935
|
+
"""
|
|
2936
|
+
return self.GetPattern(PatternId.TransformPattern)
|
|
2937
|
+
|
|
2938
|
+
|
|
2939
|
+
class HyperlinkControl(Control):
|
|
2940
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2941
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2942
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2943
|
+
foundIndex: int = 1,
|
|
2944
|
+
element=None,
|
|
2945
|
+
Name: Optional[str] = None,
|
|
2946
|
+
SubName: Optional[str] = None,
|
|
2947
|
+
RegexName: Optional[str] = None,
|
|
2948
|
+
ClassName: Optional[str] = None,
|
|
2949
|
+
AutomationId: Optional[str] = None,
|
|
2950
|
+
Depth: Optional[int] = None,
|
|
2951
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2952
|
+
**searchProperties):
|
|
2953
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2954
|
+
ControlType=ControlType.HyperlinkControl,
|
|
2955
|
+
Name=Name,
|
|
2956
|
+
SubName=SubName,
|
|
2957
|
+
RegexName=RegexName,
|
|
2958
|
+
ClassName=ClassName,
|
|
2959
|
+
AutomationId=AutomationId,
|
|
2960
|
+
Depth=Depth,
|
|
2961
|
+
Compare=Compare,
|
|
2962
|
+
**searchProperties)
|
|
2963
|
+
|
|
2964
|
+
def GetInvokePattern(self) -> InvokePattern:
|
|
2965
|
+
"""
|
|
2966
|
+
Return `InvokePattern` if it supports the pattern else None(Must support according to MSDN).
|
|
2967
|
+
"""
|
|
2968
|
+
return self.GetPattern(PatternId.InvokePattern)
|
|
2969
|
+
|
|
2970
|
+
def GetValuePattern(self) -> ValuePattern:
|
|
2971
|
+
"""
|
|
2972
|
+
Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
2973
|
+
"""
|
|
2974
|
+
return self.GetPattern(PatternId.ValuePattern)
|
|
2975
|
+
|
|
2976
|
+
|
|
2977
|
+
class ImageControl(Control):
|
|
2978
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
2979
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
2980
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
2981
|
+
foundIndex: int = 1,
|
|
2982
|
+
element=None,
|
|
2983
|
+
Name: Optional[str] = None,
|
|
2984
|
+
SubName: Optional[str] = None,
|
|
2985
|
+
RegexName: Optional[str] = None,
|
|
2986
|
+
ClassName: Optional[str] = None,
|
|
2987
|
+
AutomationId: Optional[str] = None,
|
|
2988
|
+
Depth: Optional[int] = None,
|
|
2989
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
2990
|
+
**searchProperties):
|
|
2991
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
2992
|
+
ControlType=ControlType.ImageControl,
|
|
2993
|
+
Name=Name,
|
|
2994
|
+
SubName=SubName,
|
|
2995
|
+
RegexName=RegexName,
|
|
2996
|
+
ClassName=ClassName,
|
|
2997
|
+
AutomationId=AutomationId,
|
|
2998
|
+
Depth=Depth,
|
|
2999
|
+
Compare=Compare,
|
|
3000
|
+
**searchProperties)
|
|
3001
|
+
|
|
3002
|
+
def GetGridItemPattern(self) -> GridItemPattern:
|
|
3003
|
+
"""
|
|
3004
|
+
Return `GridItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3005
|
+
"""
|
|
3006
|
+
return self.GetPattern(PatternId.GridItemPattern)
|
|
3007
|
+
|
|
3008
|
+
def GetTableItemPattern(self) -> TableItemPattern:
|
|
3009
|
+
"""
|
|
3010
|
+
Return `TableItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3011
|
+
"""
|
|
3012
|
+
return self.GetPattern(PatternId.TableItemPattern)
|
|
3013
|
+
|
|
3014
|
+
|
|
3015
|
+
class ListControl(Control):
|
|
3016
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3017
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3018
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3019
|
+
foundIndex: int = 1,
|
|
3020
|
+
element=None,
|
|
3021
|
+
Name: Optional[str] = None,
|
|
3022
|
+
SubName: Optional[str] = None,
|
|
3023
|
+
RegexName: Optional[str] = None,
|
|
3024
|
+
ClassName: Optional[str] = None,
|
|
3025
|
+
AutomationId: Optional[str] = None,
|
|
3026
|
+
Depth: Optional[int] = None,
|
|
3027
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3028
|
+
**searchProperties):
|
|
3029
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3030
|
+
ControlType=ControlType.ListControl,
|
|
3031
|
+
Name=Name,
|
|
3032
|
+
SubName=SubName,
|
|
3033
|
+
RegexName=RegexName,
|
|
3034
|
+
ClassName=ClassName,
|
|
3035
|
+
AutomationId=AutomationId,
|
|
3036
|
+
Depth=Depth,
|
|
3037
|
+
Compare=Compare,
|
|
3038
|
+
**searchProperties)
|
|
3039
|
+
|
|
3040
|
+
def GetGridPattern(self) -> GridPattern:
|
|
3041
|
+
"""
|
|
3042
|
+
Return `GridPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3043
|
+
"""
|
|
3044
|
+
return self.GetPattern(PatternId.GridPattern)
|
|
3045
|
+
|
|
3046
|
+
def GetMultipleViewPattern(self) -> MultipleViewPattern:
|
|
3047
|
+
"""
|
|
3048
|
+
Return `MultipleViewPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3049
|
+
"""
|
|
3050
|
+
return self.GetPattern(PatternId.MultipleViewPattern)
|
|
3051
|
+
|
|
3052
|
+
def GetScrollPattern(self) -> ScrollPattern:
|
|
3053
|
+
"""
|
|
3054
|
+
Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3055
|
+
"""
|
|
3056
|
+
return self.GetPattern(PatternId.ScrollPattern)
|
|
3057
|
+
|
|
3058
|
+
def GetSelectionPattern(self) -> SelectionPattern:
|
|
3059
|
+
"""
|
|
3060
|
+
Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3061
|
+
"""
|
|
3062
|
+
return self.GetPattern(PatternId.SelectionPattern)
|
|
3063
|
+
|
|
3064
|
+
|
|
3065
|
+
class ListItemControl(Control):
|
|
3066
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3067
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3068
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3069
|
+
foundIndex: int = 1,
|
|
3070
|
+
element=None,
|
|
3071
|
+
Name: Optional[str] = None,
|
|
3072
|
+
SubName: Optional[str] = None,
|
|
3073
|
+
RegexName: Optional[str] = None,
|
|
3074
|
+
ClassName: Optional[str] = None,
|
|
3075
|
+
AutomationId: Optional[str] = None,
|
|
3076
|
+
Depth: Optional[int] = None,
|
|
3077
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3078
|
+
**searchProperties):
|
|
3079
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3080
|
+
ControlType=ControlType.ListItemControl,
|
|
3081
|
+
Name=Name,
|
|
3082
|
+
SubName=SubName,
|
|
3083
|
+
RegexName=RegexName,
|
|
3084
|
+
ClassName=ClassName,
|
|
3085
|
+
AutomationId=AutomationId,
|
|
3086
|
+
Depth=Depth,
|
|
3087
|
+
Compare=Compare,
|
|
3088
|
+
**searchProperties)
|
|
3089
|
+
|
|
3090
|
+
def GetSelectionItemPattern(self) -> SelectionItemPattern:
|
|
3091
|
+
"""
|
|
3092
|
+
Return `SelectionItemPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3093
|
+
"""
|
|
3094
|
+
return self.GetPattern(PatternId.SelectionItemPattern)
|
|
3095
|
+
|
|
3096
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
3097
|
+
"""
|
|
3098
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3099
|
+
"""
|
|
3100
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
3101
|
+
|
|
3102
|
+
def GetGridItemPattern(self) -> GridItemPattern:
|
|
3103
|
+
"""
|
|
3104
|
+
Return `GridItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3105
|
+
"""
|
|
3106
|
+
return self.GetPattern(PatternId.GridItemPattern)
|
|
3107
|
+
|
|
3108
|
+
def GetInvokePattern(self) -> InvokePattern:
|
|
3109
|
+
"""
|
|
3110
|
+
Return `InvokePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3111
|
+
"""
|
|
3112
|
+
return self.GetPattern(PatternId.InvokePattern)
|
|
3113
|
+
|
|
3114
|
+
def GetScrollItemPattern(self) -> ScrollItemPattern:
|
|
3115
|
+
"""
|
|
3116
|
+
Return `ScrollItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3117
|
+
"""
|
|
3118
|
+
return self.GetPattern(PatternId.ScrollItemPattern)
|
|
3119
|
+
|
|
3120
|
+
def GetTogglePattern(self) -> TogglePattern:
|
|
3121
|
+
"""
|
|
3122
|
+
Return `TogglePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3123
|
+
"""
|
|
3124
|
+
return self.GetPattern(PatternId.TogglePattern)
|
|
3125
|
+
|
|
3126
|
+
def GetValuePattern(self) -> ValuePattern:
|
|
3127
|
+
"""
|
|
3128
|
+
Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3129
|
+
"""
|
|
3130
|
+
return self.GetPattern(PatternId.ValuePattern)
|
|
3131
|
+
|
|
3132
|
+
|
|
3133
|
+
class MenuControl(Control):
|
|
3134
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3135
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3136
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3137
|
+
foundIndex: int = 1,
|
|
3138
|
+
element=None,
|
|
3139
|
+
Name: Optional[str] = None,
|
|
3140
|
+
SubName: Optional[str] = None,
|
|
3141
|
+
RegexName: Optional[str] = None,
|
|
3142
|
+
ClassName: Optional[str] = None,
|
|
3143
|
+
AutomationId: Optional[str] = None,
|
|
3144
|
+
Depth: Optional[int] = None,
|
|
3145
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3146
|
+
**searchProperties):
|
|
3147
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3148
|
+
ControlType=ControlType.MenuControl,
|
|
3149
|
+
Name=Name,
|
|
3150
|
+
SubName=SubName,
|
|
3151
|
+
RegexName=RegexName,
|
|
3152
|
+
ClassName=ClassName,
|
|
3153
|
+
AutomationId=AutomationId,
|
|
3154
|
+
Depth=Depth,
|
|
3155
|
+
Compare=Compare,
|
|
3156
|
+
**searchProperties)
|
|
3157
|
+
|
|
3158
|
+
|
|
3159
|
+
class MenuBarControl(Control):
|
|
3160
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3161
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3162
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3163
|
+
foundIndex: int = 1,
|
|
3164
|
+
element=None,
|
|
3165
|
+
Name: Optional[str] = None,
|
|
3166
|
+
SubName: Optional[str] = None,
|
|
3167
|
+
RegexName: Optional[str] = None,
|
|
3168
|
+
ClassName: Optional[str] = None,
|
|
3169
|
+
AutomationId: Optional[str] = None,
|
|
3170
|
+
Depth: Optional[int] = None,
|
|
3171
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3172
|
+
**searchProperties):
|
|
3173
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3174
|
+
ControlType=ControlType.MenuBarControl,
|
|
3175
|
+
Name=Name,
|
|
3176
|
+
SubName=SubName,
|
|
3177
|
+
RegexName=RegexName,
|
|
3178
|
+
ClassName=ClassName,
|
|
3179
|
+
AutomationId=AutomationId,
|
|
3180
|
+
Depth=Depth,
|
|
3181
|
+
Compare=Compare,
|
|
3182
|
+
**searchProperties)
|
|
3183
|
+
|
|
3184
|
+
def GetDockPattern(self) -> DockPattern:
|
|
3185
|
+
"""
|
|
3186
|
+
Return `DockPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3187
|
+
"""
|
|
3188
|
+
return self.GetPattern(PatternId.DockPattern)
|
|
3189
|
+
|
|
3190
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
3191
|
+
"""
|
|
3192
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3193
|
+
"""
|
|
3194
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
3195
|
+
|
|
3196
|
+
def GetTransformPattern(self) -> TransformPattern:
|
|
3197
|
+
"""
|
|
3198
|
+
Return `TransformPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3199
|
+
"""
|
|
3200
|
+
return self.GetPattern(PatternId.TransformPattern)
|
|
3201
|
+
|
|
3202
|
+
|
|
3203
|
+
class MenuItemControl(Control):
|
|
3204
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3205
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3206
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3207
|
+
foundIndex: int = 1,
|
|
3208
|
+
element=None,
|
|
3209
|
+
Name: Optional[str] = None,
|
|
3210
|
+
SubName: Optional[str] = None,
|
|
3211
|
+
RegexName: Optional[str] = None,
|
|
3212
|
+
ClassName: Optional[str] = None,
|
|
3213
|
+
AutomationId: Optional[str] = None,
|
|
3214
|
+
Depth: Optional[int] = None,
|
|
3215
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3216
|
+
**searchProperties):
|
|
3217
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3218
|
+
ControlType=ControlType.MenuItemControl,
|
|
3219
|
+
Name=Name,
|
|
3220
|
+
SubName=SubName,
|
|
3221
|
+
RegexName=RegexName,
|
|
3222
|
+
ClassName=ClassName,
|
|
3223
|
+
AutomationId=AutomationId,
|
|
3224
|
+
Depth=Depth,
|
|
3225
|
+
Compare=Compare,
|
|
3226
|
+
**searchProperties)
|
|
3227
|
+
|
|
3228
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
3229
|
+
"""
|
|
3230
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3231
|
+
"""
|
|
3232
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
3233
|
+
|
|
3234
|
+
def GetInvokePattern(self) -> InvokePattern:
|
|
3235
|
+
"""
|
|
3236
|
+
Return `InvokePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3237
|
+
"""
|
|
3238
|
+
return self.GetPattern(PatternId.InvokePattern)
|
|
3239
|
+
|
|
3240
|
+
def GetSelectionItemPattern(self) -> SelectionItemPattern:
|
|
3241
|
+
"""
|
|
3242
|
+
Return `SelectionItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3243
|
+
"""
|
|
3244
|
+
return self.GetPattern(PatternId.SelectionItemPattern)
|
|
3245
|
+
|
|
3246
|
+
def GetTogglePattern(self) -> TogglePattern:
|
|
3247
|
+
"""
|
|
3248
|
+
Return `TogglePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3249
|
+
"""
|
|
3250
|
+
return self.GetPattern(PatternId.TogglePattern)
|
|
3251
|
+
|
|
3252
|
+
|
|
3253
|
+
class TopLevel():
|
|
3254
|
+
"""Class TopLevel"""
|
|
3255
|
+
|
|
3256
|
+
def SetTopmost(self, isTopmost: bool = True, waitTime: float = OPERATION_WAIT_TIME) -> bool:
|
|
3257
|
+
"""
|
|
3258
|
+
Set top level window topmost.
|
|
3259
|
+
isTopmost: bool.
|
|
3260
|
+
waitTime: float.
|
|
3261
|
+
"""
|
|
3262
|
+
if self.IsTopLevel():
|
|
3263
|
+
ret = SetWindowTopmost(self.NativeWindowHandle, isTopmost)
|
|
3264
|
+
time.sleep(waitTime)
|
|
3265
|
+
return ret
|
|
3266
|
+
return False
|
|
3267
|
+
|
|
3268
|
+
def IsTopmost(self) -> bool:
|
|
3269
|
+
if self.IsTopLevel():
|
|
3270
|
+
WS_EX_TOPMOST = 0x00000008
|
|
3271
|
+
return bool(GetWindowLong(self.NativeWindowHandle, GWL.ExStyle) & WS_EX_TOPMOST)
|
|
3272
|
+
return False
|
|
3273
|
+
|
|
3274
|
+
def SwitchToThisWindow(self, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
3275
|
+
if self.IsTopLevel():
|
|
3276
|
+
SwitchToThisWindow(self.NativeWindowHandle)
|
|
3277
|
+
time.sleep(waitTime)
|
|
3278
|
+
|
|
3279
|
+
def Maximize(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:
|
|
3280
|
+
"""
|
|
3281
|
+
Set top level window maximize.
|
|
3282
|
+
"""
|
|
3283
|
+
if self.IsTopLevel():
|
|
3284
|
+
return self.ShowWindow(SW.ShowMaximized, waitTime)
|
|
3285
|
+
return False
|
|
3286
|
+
|
|
3287
|
+
def IsMaximize(self) -> bool:
|
|
3288
|
+
if self.IsTopLevel():
|
|
3289
|
+
return bool(IsZoomed(self.NativeWindowHandle))
|
|
3290
|
+
return False
|
|
3291
|
+
|
|
3292
|
+
def Minimize(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:
|
|
3293
|
+
if self.IsTopLevel():
|
|
3294
|
+
return self.ShowWindow(SW.Minimize, waitTime)
|
|
3295
|
+
return False
|
|
3296
|
+
|
|
3297
|
+
def IsMinimize(self) -> bool:
|
|
3298
|
+
if self.IsTopLevel():
|
|
3299
|
+
return bool(IsIconic(self.NativeWindowHandle))
|
|
3300
|
+
return False
|
|
3301
|
+
|
|
3302
|
+
def Restore(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:
|
|
3303
|
+
"""
|
|
3304
|
+
Restore window to normal state.
|
|
3305
|
+
Similar to SwitchToThisWindow.
|
|
3306
|
+
"""
|
|
3307
|
+
if self.IsTopLevel():
|
|
3308
|
+
return self.ShowWindow(SW.Restore, waitTime)
|
|
3309
|
+
return False
|
|
3310
|
+
|
|
3311
|
+
def MoveToCenter(self) -> bool:
|
|
3312
|
+
"""
|
|
3313
|
+
Move window to screen center.
|
|
3314
|
+
"""
|
|
3315
|
+
if self.IsTopLevel():
|
|
3316
|
+
rect = self.BoundingRectangle
|
|
3317
|
+
screenWidth, screenHeight = GetScreenSize()
|
|
3318
|
+
x, y = (screenWidth - rect.width()) // 2, (screenHeight - rect.height()) // 2
|
|
3319
|
+
if x < 0:
|
|
3320
|
+
x = 0
|
|
3321
|
+
if y < 0:
|
|
3322
|
+
y = 0
|
|
3323
|
+
return SetWindowPos(self.NativeWindowHandle, SWP.HWND_Top, x, y, 0, 0, SWP.SWP_NoSize)
|
|
3324
|
+
return False
|
|
3325
|
+
|
|
3326
|
+
def SetActive(self, waitTime: float = OPERATION_WAIT_TIME) -> bool:
|
|
3327
|
+
"""Set top level window active."""
|
|
3328
|
+
if self.IsTopLevel():
|
|
3329
|
+
handle = self.NativeWindowHandle
|
|
3330
|
+
if IsIconic(handle):
|
|
3331
|
+
ret = ShowWindow(handle, SW.Restore)
|
|
3332
|
+
elif not IsWindowVisible(handle):
|
|
3333
|
+
ret = ShowWindow(handle, SW.Show)
|
|
3334
|
+
ret = SetForegroundWindow(handle) # may fail if foreground windows's process is not python
|
|
3335
|
+
time.sleep(waitTime)
|
|
3336
|
+
return ret
|
|
3337
|
+
return False
|
|
3338
|
+
|
|
3339
|
+
|
|
3340
|
+
class PaneControl(Control, TopLevel):
|
|
3341
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3342
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3343
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3344
|
+
foundIndex: int = 1,
|
|
3345
|
+
element=None,
|
|
3346
|
+
Name: Optional[str] = None,
|
|
3347
|
+
SubName: Optional[str] = None,
|
|
3348
|
+
RegexName: Optional[str] = None,
|
|
3349
|
+
ClassName: Optional[str] = None,
|
|
3350
|
+
AutomationId: Optional[str] = None,
|
|
3351
|
+
Depth: Optional[int] = None,
|
|
3352
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3353
|
+
**searchProperties):
|
|
3354
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3355
|
+
ControlType=ControlType.PaneControl,
|
|
3356
|
+
Name=Name,
|
|
3357
|
+
SubName=SubName,
|
|
3358
|
+
RegexName=RegexName,
|
|
3359
|
+
ClassName=ClassName,
|
|
3360
|
+
AutomationId=AutomationId,
|
|
3361
|
+
Depth=Depth,
|
|
3362
|
+
Compare=Compare,
|
|
3363
|
+
**searchProperties)
|
|
3364
|
+
|
|
3365
|
+
def GetDockPattern(self) -> DockPattern:
|
|
3366
|
+
"""
|
|
3367
|
+
Return `DockPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3368
|
+
"""
|
|
3369
|
+
return self.GetPattern(PatternId.DockPattern)
|
|
3370
|
+
|
|
3371
|
+
def GetScrollPattern(self) -> ScrollPattern:
|
|
3372
|
+
"""
|
|
3373
|
+
Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3374
|
+
"""
|
|
3375
|
+
return self.GetPattern(PatternId.ScrollPattern)
|
|
3376
|
+
|
|
3377
|
+
def GetTransformPattern(self) -> TransformPattern:
|
|
3378
|
+
"""
|
|
3379
|
+
Return `TransformPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3380
|
+
"""
|
|
3381
|
+
return self.GetPattern(PatternId.TransformPattern)
|
|
3382
|
+
|
|
3383
|
+
|
|
3384
|
+
class ProgressBarControl(Control):
|
|
3385
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3386
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3387
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3388
|
+
foundIndex: int = 1,
|
|
3389
|
+
element=None,
|
|
3390
|
+
Name: Optional[str] = None,
|
|
3391
|
+
SubName: Optional[str] = None,
|
|
3392
|
+
RegexName: Optional[str] = None,
|
|
3393
|
+
ClassName: Optional[str] = None,
|
|
3394
|
+
AutomationId: Optional[str] = None,
|
|
3395
|
+
Depth: Optional[int] = None,
|
|
3396
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3397
|
+
**searchProperties):
|
|
3398
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3399
|
+
ControlType=ControlType.ProgressBarControl,
|
|
3400
|
+
Name=Name,
|
|
3401
|
+
SubName=SubName,
|
|
3402
|
+
RegexName=RegexName,
|
|
3403
|
+
ClassName=ClassName,
|
|
3404
|
+
AutomationId=AutomationId,
|
|
3405
|
+
Depth=Depth,
|
|
3406
|
+
Compare=Compare,
|
|
3407
|
+
**searchProperties)
|
|
3408
|
+
|
|
3409
|
+
def GetRangeValuePattern(self) -> RangeValuePattern:
|
|
3410
|
+
"""
|
|
3411
|
+
Return `RangeValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3412
|
+
"""
|
|
3413
|
+
return self.GetPattern(PatternId.RangeValuePattern)
|
|
3414
|
+
|
|
3415
|
+
def GetValuePattern(self) -> ValuePattern:
|
|
3416
|
+
"""
|
|
3417
|
+
Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3418
|
+
"""
|
|
3419
|
+
return self.GetPattern(PatternId.ValuePattern)
|
|
3420
|
+
|
|
3421
|
+
|
|
3422
|
+
class RadioButtonControl(Control):
|
|
3423
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3424
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3425
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3426
|
+
foundIndex: int = 1,
|
|
3427
|
+
element=None,
|
|
3428
|
+
Name: Optional[str] = None,
|
|
3429
|
+
SubName: Optional[str] = None,
|
|
3430
|
+
RegexName: Optional[str] = None,
|
|
3431
|
+
ClassName: Optional[str] = None,
|
|
3432
|
+
AutomationId: Optional[str] = None,
|
|
3433
|
+
Depth: Optional[int] = None,
|
|
3434
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3435
|
+
**searchProperties):
|
|
3436
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3437
|
+
ControlType=ControlType.RadioButtonControl,
|
|
3438
|
+
Name=Name,
|
|
3439
|
+
SubName=SubName,
|
|
3440
|
+
RegexName=RegexName,
|
|
3441
|
+
ClassName=ClassName,
|
|
3442
|
+
AutomationId=AutomationId,
|
|
3443
|
+
Depth=Depth,
|
|
3444
|
+
Compare=Compare,
|
|
3445
|
+
**searchProperties)
|
|
3446
|
+
|
|
3447
|
+
def GetSelectionItemPattern(self) -> SelectionItemPattern:
|
|
3448
|
+
"""
|
|
3449
|
+
Return `SelectionItemPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3450
|
+
"""
|
|
3451
|
+
return self.GetPattern(PatternId.SelectionItemPattern)
|
|
3452
|
+
|
|
3453
|
+
|
|
3454
|
+
class ScrollBarControl(Control):
|
|
3455
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3456
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3457
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3458
|
+
foundIndex: int = 1,
|
|
3459
|
+
element=None,
|
|
3460
|
+
Name: Optional[str] = None,
|
|
3461
|
+
SubName: Optional[str] = None,
|
|
3462
|
+
RegexName: Optional[str] = None,
|
|
3463
|
+
ClassName: Optional[str] = None,
|
|
3464
|
+
AutomationId: Optional[str] = None,
|
|
3465
|
+
Depth: Optional[int] = None,
|
|
3466
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3467
|
+
**searchProperties):
|
|
3468
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3469
|
+
ControlType=ControlType.ScrollBarControl,
|
|
3470
|
+
Name=Name,
|
|
3471
|
+
SubName=SubName,
|
|
3472
|
+
RegexName=RegexName,
|
|
3473
|
+
ClassName=ClassName,
|
|
3474
|
+
AutomationId=AutomationId,
|
|
3475
|
+
Depth=Depth,
|
|
3476
|
+
Compare=Compare,
|
|
3477
|
+
**searchProperties)
|
|
3478
|
+
|
|
3479
|
+
def GetRangeValuePattern(self) -> RangeValuePattern:
|
|
3480
|
+
"""
|
|
3481
|
+
Return `RangeValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3482
|
+
"""
|
|
3483
|
+
return self.GetPattern(PatternId.RangeValuePattern)
|
|
3484
|
+
|
|
3485
|
+
|
|
3486
|
+
class SemanticZoomControl(Control):
|
|
3487
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3488
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3489
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3490
|
+
foundIndex: int = 1,
|
|
3491
|
+
element=None,
|
|
3492
|
+
Name: Optional[str] = None,
|
|
3493
|
+
SubName: Optional[str] = None,
|
|
3494
|
+
RegexName: Optional[str] = None,
|
|
3495
|
+
ClassName: Optional[str] = None,
|
|
3496
|
+
AutomationId: Optional[str] = None,
|
|
3497
|
+
Depth: Optional[int] = None,
|
|
3498
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3499
|
+
**searchProperties):
|
|
3500
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3501
|
+
ControlType=ControlType.SemanticZoomControl,
|
|
3502
|
+
Name=Name,
|
|
3503
|
+
SubName=SubName,
|
|
3504
|
+
RegexName=RegexName,
|
|
3505
|
+
ClassName=ClassName,
|
|
3506
|
+
AutomationId=AutomationId,
|
|
3507
|
+
Depth=Depth,
|
|
3508
|
+
Compare=Compare,
|
|
3509
|
+
**searchProperties)
|
|
3510
|
+
|
|
3511
|
+
|
|
3512
|
+
class SeparatorControl(Control):
|
|
3513
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3514
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3515
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3516
|
+
foundIndex: int = 1,
|
|
3517
|
+
element=None,
|
|
3518
|
+
Name: Optional[str] = None,
|
|
3519
|
+
SubName: Optional[str] = None,
|
|
3520
|
+
RegexName: Optional[str] = None,
|
|
3521
|
+
ClassName: Optional[str] = None,
|
|
3522
|
+
AutomationId: Optional[str] = None,
|
|
3523
|
+
Depth: Optional[int] = None,
|
|
3524
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3525
|
+
**searchProperties):
|
|
3526
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3527
|
+
ControlType=ControlType.SeparatorControl,
|
|
3528
|
+
Name=Name,
|
|
3529
|
+
SubName=SubName,
|
|
3530
|
+
RegexName=RegexName,
|
|
3531
|
+
ClassName=ClassName,
|
|
3532
|
+
AutomationId=AutomationId,
|
|
3533
|
+
Depth=Depth,
|
|
3534
|
+
Compare=Compare,
|
|
3535
|
+
**searchProperties)
|
|
3536
|
+
|
|
3537
|
+
|
|
3538
|
+
class SliderControl(Control):
|
|
3539
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3540
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3541
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3542
|
+
foundIndex: int = 1,
|
|
3543
|
+
element=None,
|
|
3544
|
+
Name: Optional[str] = None,
|
|
3545
|
+
SubName: Optional[str] = None,
|
|
3546
|
+
RegexName: Optional[str] = None,
|
|
3547
|
+
ClassName: Optional[str] = None,
|
|
3548
|
+
AutomationId: Optional[str] = None,
|
|
3549
|
+
Depth: Optional[int] = None,
|
|
3550
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3551
|
+
**searchProperties):
|
|
3552
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3553
|
+
ControlType=ControlType.SliderControl,
|
|
3554
|
+
Name=Name,
|
|
3555
|
+
SubName=SubName,
|
|
3556
|
+
RegexName=RegexName,
|
|
3557
|
+
ClassName=ClassName,
|
|
3558
|
+
AutomationId=AutomationId,
|
|
3559
|
+
Depth=Depth,
|
|
3560
|
+
Compare=Compare,
|
|
3561
|
+
**searchProperties)
|
|
3562
|
+
|
|
3563
|
+
def GetRangeValuePattern(self) -> RangeValuePattern:
|
|
3564
|
+
"""
|
|
3565
|
+
Return `RangeValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3566
|
+
"""
|
|
3567
|
+
return self.GetPattern(PatternId.RangeValuePattern)
|
|
3568
|
+
|
|
3569
|
+
def GetSelectionPattern(self) -> SelectionPattern:
|
|
3570
|
+
"""
|
|
3571
|
+
Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3572
|
+
"""
|
|
3573
|
+
return self.GetPattern(PatternId.SelectionPattern)
|
|
3574
|
+
|
|
3575
|
+
def GetValuePattern(self) -> ValuePattern:
|
|
3576
|
+
"""
|
|
3577
|
+
Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3578
|
+
"""
|
|
3579
|
+
return self.GetPattern(PatternId.ValuePattern)
|
|
3580
|
+
|
|
3581
|
+
|
|
3582
|
+
class SpinnerControl(Control):
|
|
3583
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3584
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3585
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3586
|
+
foundIndex: int = 1,
|
|
3587
|
+
element=None,
|
|
3588
|
+
Name: Optional[str] = None,
|
|
3589
|
+
SubName: Optional[str] = None,
|
|
3590
|
+
RegexName: Optional[str] = None,
|
|
3591
|
+
ClassName: Optional[str] = None,
|
|
3592
|
+
AutomationId: Optional[str] = None,
|
|
3593
|
+
Depth: Optional[int] = None,
|
|
3594
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3595
|
+
**searchProperties):
|
|
3596
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3597
|
+
ControlType=ControlType.SpinnerControl,
|
|
3598
|
+
Name=Name,
|
|
3599
|
+
SubName=SubName,
|
|
3600
|
+
RegexName=RegexName,
|
|
3601
|
+
ClassName=ClassName,
|
|
3602
|
+
AutomationId=AutomationId,
|
|
3603
|
+
Depth=Depth,
|
|
3604
|
+
Compare=Compare,
|
|
3605
|
+
**searchProperties)
|
|
3606
|
+
|
|
3607
|
+
def GetRangeValuePattern(self) -> RangeValuePattern:
|
|
3608
|
+
"""
|
|
3609
|
+
Return `RangeValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3610
|
+
"""
|
|
3611
|
+
return self.GetPattern(PatternId.RangeValuePattern)
|
|
3612
|
+
|
|
3613
|
+
def GetSelectionPattern(self) -> SelectionPattern:
|
|
3614
|
+
"""
|
|
3615
|
+
Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3616
|
+
"""
|
|
3617
|
+
return self.GetPattern(PatternId.SelectionPattern)
|
|
3618
|
+
|
|
3619
|
+
def GetValuePattern(self) -> ValuePattern:
|
|
3620
|
+
"""
|
|
3621
|
+
Return `ValuePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3622
|
+
"""
|
|
3623
|
+
return self.GetPattern(PatternId.ValuePattern)
|
|
3624
|
+
|
|
3625
|
+
|
|
3626
|
+
class SplitButtonControl(Control):
|
|
3627
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3628
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3629
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3630
|
+
foundIndex: int = 1,
|
|
3631
|
+
element=None,
|
|
3632
|
+
Name: Optional[str] = None,
|
|
3633
|
+
SubName: Optional[str] = None,
|
|
3634
|
+
RegexName: Optional[str] = None,
|
|
3635
|
+
ClassName: Optional[str] = None,
|
|
3636
|
+
AutomationId: Optional[str] = None,
|
|
3637
|
+
Depth: Optional[int] = None,
|
|
3638
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3639
|
+
**searchProperties):
|
|
3640
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3641
|
+
ControlType=ControlType.SplitButtonControl,
|
|
3642
|
+
Name=Name,
|
|
3643
|
+
SubName=SubName,
|
|
3644
|
+
RegexName=RegexName,
|
|
3645
|
+
ClassName=ClassName,
|
|
3646
|
+
AutomationId=AutomationId,
|
|
3647
|
+
Depth=Depth,
|
|
3648
|
+
Compare=Compare,
|
|
3649
|
+
**searchProperties)
|
|
3650
|
+
|
|
3651
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
3652
|
+
"""
|
|
3653
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3654
|
+
"""
|
|
3655
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
3656
|
+
|
|
3657
|
+
def GetInvokePattern(self) -> InvokePattern:
|
|
3658
|
+
"""
|
|
3659
|
+
Return `InvokePattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3660
|
+
"""
|
|
3661
|
+
return self.GetPattern(PatternId.InvokePattern)
|
|
3662
|
+
|
|
3663
|
+
|
|
3664
|
+
class StatusBarControl(Control):
|
|
3665
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3666
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3667
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3668
|
+
foundIndex: int = 1,
|
|
3669
|
+
element=None,
|
|
3670
|
+
Name: Optional[str] = None,
|
|
3671
|
+
SubName: Optional[str] = None,
|
|
3672
|
+
RegexName: Optional[str] = None,
|
|
3673
|
+
ClassName: Optional[str] = None,
|
|
3674
|
+
AutomationId: Optional[str] = None,
|
|
3675
|
+
Depth: Optional[int] = None,
|
|
3676
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3677
|
+
**searchProperties):
|
|
3678
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3679
|
+
ControlType=ControlType.StatusBarControl,
|
|
3680
|
+
Name=Name,
|
|
3681
|
+
SubName=SubName,
|
|
3682
|
+
RegexName=RegexName,
|
|
3683
|
+
ClassName=ClassName,
|
|
3684
|
+
AutomationId=AutomationId,
|
|
3685
|
+
Depth=Depth,
|
|
3686
|
+
Compare=Compare,
|
|
3687
|
+
**searchProperties)
|
|
3688
|
+
|
|
3689
|
+
def GetGridPattern(self) -> GridPattern:
|
|
3690
|
+
"""
|
|
3691
|
+
Return `GridPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3692
|
+
"""
|
|
3693
|
+
return self.GetPattern(PatternId.GridPattern)
|
|
3694
|
+
|
|
3695
|
+
|
|
3696
|
+
class TabControl(Control):
|
|
3697
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3698
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3699
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3700
|
+
foundIndex: int = 1,
|
|
3701
|
+
element=None,
|
|
3702
|
+
Name: Optional[str] = None,
|
|
3703
|
+
SubName: Optional[str] = None,
|
|
3704
|
+
RegexName: Optional[str] = None,
|
|
3705
|
+
ClassName: Optional[str] = None,
|
|
3706
|
+
AutomationId: Optional[str] = None,
|
|
3707
|
+
Depth: Optional[int] = None,
|
|
3708
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3709
|
+
**searchProperties):
|
|
3710
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3711
|
+
ControlType=ControlType.TabControl,
|
|
3712
|
+
Name=Name,
|
|
3713
|
+
SubName=SubName,
|
|
3714
|
+
RegexName=RegexName,
|
|
3715
|
+
ClassName=ClassName,
|
|
3716
|
+
AutomationId=AutomationId,
|
|
3717
|
+
Depth=Depth,
|
|
3718
|
+
Compare=Compare,
|
|
3719
|
+
**searchProperties)
|
|
3720
|
+
|
|
3721
|
+
def GetSelectionPattern(self) -> SelectionPattern:
|
|
3722
|
+
"""
|
|
3723
|
+
Return `SelectionPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3724
|
+
"""
|
|
3725
|
+
return self.GetPattern(PatternId.SelectionPattern)
|
|
3726
|
+
|
|
3727
|
+
def GetScrollPattern(self) -> ScrollPattern:
|
|
3728
|
+
"""
|
|
3729
|
+
Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3730
|
+
"""
|
|
3731
|
+
return self.GetPattern(PatternId.ScrollPattern)
|
|
3732
|
+
|
|
3733
|
+
|
|
3734
|
+
class TabItemControl(Control):
|
|
3735
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3736
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3737
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3738
|
+
foundIndex: int = 1,
|
|
3739
|
+
element=None,
|
|
3740
|
+
Name: Optional[str] = None,
|
|
3741
|
+
SubName: Optional[str] = None,
|
|
3742
|
+
RegexName: Optional[str] = None,
|
|
3743
|
+
ClassName: Optional[str] = None,
|
|
3744
|
+
AutomationId: Optional[str] = None,
|
|
3745
|
+
Depth: Optional[int] = None,
|
|
3746
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3747
|
+
**searchProperties):
|
|
3748
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3749
|
+
ControlType=ControlType.TabItemControl,
|
|
3750
|
+
Name=Name,
|
|
3751
|
+
SubName=SubName,
|
|
3752
|
+
RegexName=RegexName,
|
|
3753
|
+
ClassName=ClassName,
|
|
3754
|
+
AutomationId=AutomationId,
|
|
3755
|
+
Depth=Depth,
|
|
3756
|
+
Compare=Compare,
|
|
3757
|
+
**searchProperties)
|
|
3758
|
+
|
|
3759
|
+
def GetSelectionItemPattern(self) -> SelectionItemPattern:
|
|
3760
|
+
"""
|
|
3761
|
+
Return `SelectionItemPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3762
|
+
"""
|
|
3763
|
+
return self.GetPattern(PatternId.SelectionItemPattern)
|
|
3764
|
+
|
|
3765
|
+
|
|
3766
|
+
class TableControl(Control):
|
|
3767
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3768
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3769
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3770
|
+
foundIndex: int = 1,
|
|
3771
|
+
element=None,
|
|
3772
|
+
Name: Optional[str] = None,
|
|
3773
|
+
SubName: Optional[str] = None,
|
|
3774
|
+
RegexName: Optional[str] = None,
|
|
3775
|
+
ClassName: Optional[str] = None,
|
|
3776
|
+
AutomationId: Optional[str] = None,
|
|
3777
|
+
Depth: Optional[int] = None,
|
|
3778
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3779
|
+
**searchProperties):
|
|
3780
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3781
|
+
ControlType=ControlType.TableControl,
|
|
3782
|
+
Name=Name,
|
|
3783
|
+
SubName=SubName,
|
|
3784
|
+
RegexName=RegexName,
|
|
3785
|
+
ClassName=ClassName,
|
|
3786
|
+
AutomationId=AutomationId,
|
|
3787
|
+
Depth=Depth,
|
|
3788
|
+
Compare=Compare,
|
|
3789
|
+
**searchProperties)
|
|
3790
|
+
|
|
3791
|
+
def GetGridPattern(self) -> GridPattern:
|
|
3792
|
+
"""
|
|
3793
|
+
Return `GridPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3794
|
+
"""
|
|
3795
|
+
return self.GetPattern(PatternId.GridPattern)
|
|
3796
|
+
|
|
3797
|
+
def GetGridItemPattern(self) -> GridItemPattern:
|
|
3798
|
+
"""
|
|
3799
|
+
Return `GridItemPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3800
|
+
"""
|
|
3801
|
+
return self.GetPattern(PatternId.GridItemPattern)
|
|
3802
|
+
|
|
3803
|
+
def GetTablePattern(self) -> TablePattern:
|
|
3804
|
+
"""
|
|
3805
|
+
Return `TablePattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3806
|
+
"""
|
|
3807
|
+
return self.GetPattern(PatternId.TablePattern)
|
|
3808
|
+
|
|
3809
|
+
def GetTableItemPattern(self) -> TableItemPattern:
|
|
3810
|
+
"""
|
|
3811
|
+
Return `TableItemPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3812
|
+
"""
|
|
3813
|
+
return self.GetPattern(PatternId.TableItemPattern)
|
|
3814
|
+
|
|
3815
|
+
def GetTableItemsValue(self, row: int = -1, column: int = -1):
|
|
3816
|
+
"""
|
|
3817
|
+
Get the value of a table
|
|
3818
|
+
row: int. Position of the row in the table
|
|
3819
|
+
column: int. Position of the column in the table
|
|
3820
|
+
Return a list with values in the table.
|
|
3821
|
+
If a row and column is specified, return a cell value.
|
|
3822
|
+
If only a row is specified, return a list with row values
|
|
3823
|
+
"""
|
|
3824
|
+
table = []
|
|
3825
|
+
for item in self.GetChildren():
|
|
3826
|
+
table.append([cell.GetLegacyIAccessiblePattern().Value for cell in item.GetChildren()])
|
|
3827
|
+
if row > 0 and column > 0:
|
|
3828
|
+
return table[row][column]
|
|
3829
|
+
if row > 0:
|
|
3830
|
+
return table[row]
|
|
3831
|
+
return table
|
|
3832
|
+
|
|
3833
|
+
|
|
3834
|
+
class TextControl(Control):
|
|
3835
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3836
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3837
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3838
|
+
foundIndex: int = 1,
|
|
3839
|
+
element=None,
|
|
3840
|
+
Name: Optional[str] = None,
|
|
3841
|
+
SubName: Optional[str] = None,
|
|
3842
|
+
RegexName: Optional[str] = None,
|
|
3843
|
+
ClassName: Optional[str] = None,
|
|
3844
|
+
AutomationId: Optional[str] = None,
|
|
3845
|
+
Depth: Optional[int] = None,
|
|
3846
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3847
|
+
**searchProperties):
|
|
3848
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3849
|
+
ControlType=ControlType.TextControl,
|
|
3850
|
+
Name=Name,
|
|
3851
|
+
SubName=SubName,
|
|
3852
|
+
RegexName=RegexName,
|
|
3853
|
+
ClassName=ClassName,
|
|
3854
|
+
AutomationId=AutomationId,
|
|
3855
|
+
Depth=Depth,
|
|
3856
|
+
Compare=Compare,
|
|
3857
|
+
**searchProperties)
|
|
3858
|
+
|
|
3859
|
+
def GetGridItemPattern(self) -> GridItemPattern:
|
|
3860
|
+
"""
|
|
3861
|
+
Return `GridItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3862
|
+
"""
|
|
3863
|
+
return self.GetPattern(PatternId.GridItemPattern)
|
|
3864
|
+
|
|
3865
|
+
def GetTableItemPattern(self) -> TableItemPattern:
|
|
3866
|
+
"""
|
|
3867
|
+
Return `TableItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3868
|
+
"""
|
|
3869
|
+
return self.GetPattern(PatternId.TableItemPattern)
|
|
3870
|
+
|
|
3871
|
+
def GetTextPattern(self) -> TextPattern:
|
|
3872
|
+
"""
|
|
3873
|
+
Return `TextPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3874
|
+
"""
|
|
3875
|
+
return self.GetPattern(PatternId.TextPattern)
|
|
3876
|
+
|
|
3877
|
+
|
|
3878
|
+
class ThumbControl(Control):
|
|
3879
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3880
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3881
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3882
|
+
foundIndex: int = 1,
|
|
3883
|
+
element=None,
|
|
3884
|
+
Name: Optional[str] = None,
|
|
3885
|
+
SubName: Optional[str] = None,
|
|
3886
|
+
RegexName: Optional[str] = None,
|
|
3887
|
+
ClassName: Optional[str] = None,
|
|
3888
|
+
AutomationId: Optional[str] = None,
|
|
3889
|
+
Depth: Optional[int] = None,
|
|
3890
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3891
|
+
**searchProperties):
|
|
3892
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3893
|
+
ControlType=ControlType.ThumbControl,
|
|
3894
|
+
Name=Name,
|
|
3895
|
+
SubName=SubName,
|
|
3896
|
+
RegexName=RegexName,
|
|
3897
|
+
ClassName=ClassName,
|
|
3898
|
+
AutomationId=AutomationId,
|
|
3899
|
+
Depth=Depth,
|
|
3900
|
+
Compare=Compare,
|
|
3901
|
+
**searchProperties)
|
|
3902
|
+
|
|
3903
|
+
def GetTransformPattern(self) -> TransformPattern:
|
|
3904
|
+
"""
|
|
3905
|
+
Return `TransformPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
3906
|
+
"""
|
|
3907
|
+
return self.GetPattern(PatternId.TransformPattern)
|
|
3908
|
+
|
|
3909
|
+
|
|
3910
|
+
class TitleBarControl(Control):
|
|
3911
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3912
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3913
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3914
|
+
foundIndex: int = 1,
|
|
3915
|
+
element=None,
|
|
3916
|
+
Name: Optional[str] = None,
|
|
3917
|
+
SubName: Optional[str] = None,
|
|
3918
|
+
RegexName: Optional[str] = None,
|
|
3919
|
+
ClassName: Optional[str] = None,
|
|
3920
|
+
AutomationId: Optional[str] = None,
|
|
3921
|
+
Depth: Optional[int] = None,
|
|
3922
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3923
|
+
**searchProperties):
|
|
3924
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3925
|
+
ControlType=ControlType.TitleBarControl,
|
|
3926
|
+
Name=Name,
|
|
3927
|
+
SubName=SubName,
|
|
3928
|
+
RegexName=RegexName,
|
|
3929
|
+
ClassName=ClassName,
|
|
3930
|
+
AutomationId=AutomationId,
|
|
3931
|
+
Depth=Depth,
|
|
3932
|
+
Compare=Compare,
|
|
3933
|
+
**searchProperties)
|
|
3934
|
+
|
|
3935
|
+
|
|
3936
|
+
class ToolBarControl(Control):
|
|
3937
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3938
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3939
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3940
|
+
foundIndex: int = 1,
|
|
3941
|
+
element=None,
|
|
3942
|
+
Name: Optional[str] = None,
|
|
3943
|
+
SubName: Optional[str] = None,
|
|
3944
|
+
RegexName: Optional[str] = None,
|
|
3945
|
+
ClassName: Optional[str] = None,
|
|
3946
|
+
AutomationId: Optional[str] = None,
|
|
3947
|
+
Depth: Optional[int] = None,
|
|
3948
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3949
|
+
**searchProperties):
|
|
3950
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3951
|
+
ControlType=ControlType.ToolBarControl,
|
|
3952
|
+
Name=Name,
|
|
3953
|
+
SubName=SubName,
|
|
3954
|
+
RegexName=RegexName,
|
|
3955
|
+
ClassName=ClassName,
|
|
3956
|
+
AutomationId=AutomationId,
|
|
3957
|
+
Depth=Depth,
|
|
3958
|
+
Compare=Compare,
|
|
3959
|
+
**searchProperties)
|
|
3960
|
+
|
|
3961
|
+
def GetDockPattern(self) -> DockPattern:
|
|
3962
|
+
"""
|
|
3963
|
+
Return `DockPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3964
|
+
"""
|
|
3965
|
+
return self.GetPattern(PatternId.DockPattern)
|
|
3966
|
+
|
|
3967
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
3968
|
+
"""
|
|
3969
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3970
|
+
"""
|
|
3971
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
3972
|
+
|
|
3973
|
+
def GetTransformPattern(self) -> TransformPattern:
|
|
3974
|
+
"""
|
|
3975
|
+
Return `TransformPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
3976
|
+
"""
|
|
3977
|
+
return self.GetPattern(PatternId.TransformPattern)
|
|
3978
|
+
|
|
3979
|
+
|
|
3980
|
+
class ToolTipControl(Control):
|
|
3981
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
3982
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
3983
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
3984
|
+
foundIndex: int = 1,
|
|
3985
|
+
element=None,
|
|
3986
|
+
Name: Optional[str] = None,
|
|
3987
|
+
SubName: Optional[str] = None,
|
|
3988
|
+
RegexName: Optional[str] = None,
|
|
3989
|
+
ClassName: Optional[str] = None,
|
|
3990
|
+
AutomationId: Optional[str] = None,
|
|
3991
|
+
Depth: Optional[int] = None,
|
|
3992
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
3993
|
+
**searchProperties):
|
|
3994
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
3995
|
+
ControlType=ControlType.ToolTipControl,
|
|
3996
|
+
Name=Name,
|
|
3997
|
+
SubName=SubName,
|
|
3998
|
+
RegexName=RegexName,
|
|
3999
|
+
ClassName=ClassName,
|
|
4000
|
+
AutomationId=AutomationId,
|
|
4001
|
+
Depth=Depth,
|
|
4002
|
+
Compare=Compare,
|
|
4003
|
+
**searchProperties)
|
|
4004
|
+
|
|
4005
|
+
def GetTextPattern(self) -> TextPattern:
|
|
4006
|
+
"""
|
|
4007
|
+
Return `TextPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
4008
|
+
"""
|
|
4009
|
+
return self.GetPattern(PatternId.TextPattern)
|
|
4010
|
+
|
|
4011
|
+
def GetWindowPattern(self) -> WindowPattern:
|
|
4012
|
+
"""
|
|
4013
|
+
Return `WindowPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
4014
|
+
"""
|
|
4015
|
+
return self.GetPattern(PatternId.WindowPattern)
|
|
4016
|
+
|
|
4017
|
+
|
|
4018
|
+
class TreeControl(Control):
|
|
4019
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
4020
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
4021
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
4022
|
+
foundIndex: int = 1,
|
|
4023
|
+
element=None,
|
|
4024
|
+
Name: Optional[str] = None,
|
|
4025
|
+
SubName: Optional[str] = None,
|
|
4026
|
+
RegexName: Optional[str] = None,
|
|
4027
|
+
ClassName: Optional[str] = None,
|
|
4028
|
+
AutomationId: Optional[str] = None,
|
|
4029
|
+
Depth: Optional[int] = None,
|
|
4030
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
4031
|
+
**searchProperties):
|
|
4032
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
4033
|
+
ControlType=ControlType.TreeControl,
|
|
4034
|
+
Name=Name,
|
|
4035
|
+
SubName=SubName,
|
|
4036
|
+
RegexName=RegexName,
|
|
4037
|
+
ClassName=ClassName,
|
|
4038
|
+
AutomationId=AutomationId,
|
|
4039
|
+
Depth=Depth,
|
|
4040
|
+
Compare=Compare,
|
|
4041
|
+
**searchProperties)
|
|
4042
|
+
|
|
4043
|
+
def GetScrollPattern(self) -> ScrollPattern:
|
|
4044
|
+
"""
|
|
4045
|
+
Return `ScrollPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
4046
|
+
"""
|
|
4047
|
+
return self.GetPattern(PatternId.ScrollPattern)
|
|
4048
|
+
|
|
4049
|
+
def GetSelectionPattern(self) -> SelectionPattern:
|
|
4050
|
+
"""
|
|
4051
|
+
Return `SelectionPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
4052
|
+
"""
|
|
4053
|
+
return self.GetPattern(PatternId.SelectionPattern)
|
|
4054
|
+
|
|
4055
|
+
|
|
4056
|
+
class TreeItemControl(Control):
|
|
4057
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
4058
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
4059
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
4060
|
+
foundIndex: int = 1,
|
|
4061
|
+
element=None,
|
|
4062
|
+
Name: Optional[str] = None,
|
|
4063
|
+
SubName: Optional[str] = None,
|
|
4064
|
+
RegexName: Optional[str] = None,
|
|
4065
|
+
ClassName: Optional[str] = None,
|
|
4066
|
+
AutomationId: Optional[str] = None,
|
|
4067
|
+
Depth: Optional[int] = None,
|
|
4068
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
4069
|
+
**searchProperties):
|
|
4070
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
4071
|
+
ControlType=ControlType.TreeItemControl,
|
|
4072
|
+
Name=Name,
|
|
4073
|
+
SubName=SubName,
|
|
4074
|
+
RegexName=RegexName,
|
|
4075
|
+
ClassName=ClassName,
|
|
4076
|
+
AutomationId=AutomationId,
|
|
4077
|
+
Depth=Depth,
|
|
4078
|
+
Compare=Compare,
|
|
4079
|
+
**searchProperties)
|
|
4080
|
+
|
|
4081
|
+
def GetExpandCollapsePattern(self) -> ExpandCollapsePattern:
|
|
4082
|
+
"""
|
|
4083
|
+
Return `ExpandCollapsePattern` if it supports the pattern else None(Must support according to MSDN).
|
|
4084
|
+
"""
|
|
4085
|
+
return self.GetPattern(PatternId.ExpandCollapsePattern)
|
|
4086
|
+
|
|
4087
|
+
def GetInvokePattern(self) -> InvokePattern:
|
|
4088
|
+
"""
|
|
4089
|
+
Return `InvokePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
4090
|
+
"""
|
|
4091
|
+
return self.GetPattern(PatternId.InvokePattern)
|
|
4092
|
+
|
|
4093
|
+
def GetScrollItemPattern(self) -> ScrollItemPattern:
|
|
4094
|
+
"""
|
|
4095
|
+
Return `ScrollItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
4096
|
+
"""
|
|
4097
|
+
return self.GetPattern(PatternId.ScrollItemPattern)
|
|
4098
|
+
|
|
4099
|
+
def GetSelectionItemPattern(self) -> SelectionItemPattern:
|
|
4100
|
+
"""
|
|
4101
|
+
Return `SelectionItemPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
4102
|
+
"""
|
|
4103
|
+
return self.GetPattern(PatternId.SelectionItemPattern)
|
|
4104
|
+
|
|
4105
|
+
def GetTogglePattern(self) -> TogglePattern:
|
|
4106
|
+
"""
|
|
4107
|
+
Return `TogglePattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
4108
|
+
"""
|
|
4109
|
+
return self.GetPattern(PatternId.TogglePattern)
|
|
4110
|
+
|
|
4111
|
+
|
|
4112
|
+
class WindowControl(Control, TopLevel):
|
|
4113
|
+
def __init__(self, searchFromControl: Optional[Control] = None,
|
|
4114
|
+
searchDepth: int = 0xFFFFFFFF,
|
|
4115
|
+
searchInterval: float = SEARCH_INTERVAL,
|
|
4116
|
+
foundIndex: int = 1,
|
|
4117
|
+
element=None,
|
|
4118
|
+
Name: Optional[str] = None,
|
|
4119
|
+
SubName: Optional[str] = None,
|
|
4120
|
+
RegexName: Optional[str] = None,
|
|
4121
|
+
ClassName: Optional[str] = None,
|
|
4122
|
+
AutomationId: Optional[str] = None,
|
|
4123
|
+
Depth: Optional[int] = None,
|
|
4124
|
+
Compare: Optional[Callable[[TreeNode], bool]] = None,
|
|
4125
|
+
**searchProperties):
|
|
4126
|
+
Control.__init__(self, searchFromControl, searchDepth, searchInterval, foundIndex, element,
|
|
4127
|
+
ControlType=ControlType.WindowControl,
|
|
4128
|
+
Name=Name,
|
|
4129
|
+
SubName=SubName,
|
|
4130
|
+
RegexName=RegexName,
|
|
4131
|
+
ClassName=ClassName,
|
|
4132
|
+
AutomationId=AutomationId,
|
|
4133
|
+
Depth=Depth,
|
|
4134
|
+
Compare=Compare,
|
|
4135
|
+
**searchProperties)
|
|
4136
|
+
self._DockPattern = None
|
|
4137
|
+
self._TransformPattern = None
|
|
4138
|
+
|
|
4139
|
+
def GetTransformPattern(self) -> TransformPattern:
|
|
4140
|
+
"""
|
|
4141
|
+
Return `TransformPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
4142
|
+
"""
|
|
4143
|
+
return self.GetPattern(PatternId.TransformPattern)
|
|
4144
|
+
|
|
4145
|
+
def GetWindowPattern(self) -> WindowPattern:
|
|
4146
|
+
"""
|
|
4147
|
+
Return `WindowPattern` if it supports the pattern else None(Must support according to MSDN).
|
|
4148
|
+
"""
|
|
4149
|
+
return self.GetPattern(PatternId.WindowPattern)
|
|
4150
|
+
|
|
4151
|
+
def GetDockPattern(self) -> DockPattern:
|
|
4152
|
+
"""
|
|
4153
|
+
Return `DockPattern` if it supports the pattern else None(Conditional support according to MSDN).
|
|
4154
|
+
"""
|
|
4155
|
+
return self.GetPattern(PatternId.DockPattern)
|
|
4156
|
+
|
|
4157
|
+
def MetroClose(self, waitTime: float = OPERATION_WAIT_TIME) -> None:
|
|
4158
|
+
"""
|
|
4159
|
+
Only work on Windows 8/8.1, if current window is Metro UI.
|
|
4160
|
+
waitTime: float.
|
|
4161
|
+
"""
|
|
4162
|
+
if self.ClassName == METRO_WINDOW_CLASS_NAME:
|
|
4163
|
+
screenWidth, screenHeight = GetScreenSize()
|
|
4164
|
+
MoveTo(screenWidth // 2, 0, waitTime=0)
|
|
4165
|
+
DragDrop(screenWidth // 2, 0, screenWidth // 2, screenHeight, waitTime=waitTime)
|
|
4166
|
+
else:
|
|
4167
|
+
Logger.WriteLine('Window is not Metro!', ConsoleColor.Yellow)
|
|
4168
|
+
|
|
4169
|
+
|
|
4170
|
+
ControlConstructors = {
|
|
4171
|
+
ControlType.AppBarControl: AppBarControl,
|
|
4172
|
+
ControlType.ButtonControl: ButtonControl,
|
|
4173
|
+
ControlType.CalendarControl: CalendarControl,
|
|
4174
|
+
ControlType.CheckBoxControl: CheckBoxControl,
|
|
4175
|
+
ControlType.ComboBoxControl: ComboBoxControl,
|
|
4176
|
+
ControlType.CustomControl: CustomControl,
|
|
4177
|
+
ControlType.DataGridControl: DataGridControl,
|
|
4178
|
+
ControlType.DataItemControl: DataItemControl,
|
|
4179
|
+
ControlType.DocumentControl: DocumentControl,
|
|
4180
|
+
ControlType.EditControl: EditControl,
|
|
4181
|
+
ControlType.GroupControl: GroupControl,
|
|
4182
|
+
ControlType.HeaderControl: HeaderControl,
|
|
4183
|
+
ControlType.HeaderItemControl: HeaderItemControl,
|
|
4184
|
+
ControlType.HyperlinkControl: HyperlinkControl,
|
|
4185
|
+
ControlType.ImageControl: ImageControl,
|
|
4186
|
+
ControlType.ListControl: ListControl,
|
|
4187
|
+
ControlType.ListItemControl: ListItemControl,
|
|
4188
|
+
ControlType.MenuBarControl: MenuBarControl,
|
|
4189
|
+
ControlType.MenuControl: MenuControl,
|
|
4190
|
+
ControlType.MenuItemControl: MenuItemControl,
|
|
4191
|
+
ControlType.PaneControl: PaneControl,
|
|
4192
|
+
ControlType.ProgressBarControl: ProgressBarControl,
|
|
4193
|
+
ControlType.RadioButtonControl: RadioButtonControl,
|
|
4194
|
+
ControlType.ScrollBarControl: ScrollBarControl,
|
|
4195
|
+
ControlType.SemanticZoomControl: SemanticZoomControl,
|
|
4196
|
+
ControlType.SeparatorControl: SeparatorControl,
|
|
4197
|
+
ControlType.SliderControl: SliderControl,
|
|
4198
|
+
ControlType.SpinnerControl: SpinnerControl,
|
|
4199
|
+
ControlType.SplitButtonControl: SplitButtonControl,
|
|
4200
|
+
ControlType.StatusBarControl: StatusBarControl,
|
|
4201
|
+
ControlType.TabControl: TabControl,
|
|
4202
|
+
ControlType.TabItemControl: TabItemControl,
|
|
4203
|
+
ControlType.TableControl: TableControl,
|
|
4204
|
+
ControlType.TextControl: TextControl,
|
|
4205
|
+
ControlType.ThumbControl: ThumbControl,
|
|
4206
|
+
ControlType.TitleBarControl: TitleBarControl,
|
|
4207
|
+
ControlType.ToolBarControl: ToolBarControl,
|
|
4208
|
+
ControlType.ToolTipControl: ToolTipControl,
|
|
4209
|
+
ControlType.TreeControl: TreeControl,
|
|
4210
|
+
ControlType.TreeItemControl: TreeItemControl,
|
|
4211
|
+
ControlType.WindowControl: WindowControl,
|
|
4212
|
+
}
|
|
4213
|
+
|
|
4214
|
+
|
|
4215
|
+
class UIAutomationInitializerInThread:
|
|
4216
|
+
def __init__(self, debug: bool = False):
|
|
4217
|
+
self.debug = debug
|
|
4218
|
+
InitializeUIAutomationInCurrentThread()
|
|
4219
|
+
self.inited = True
|
|
4220
|
+
if self.debug:
|
|
4221
|
+
th = threading.currentThread()
|
|
4222
|
+
print('\ncall InitializeUIAutomationInCurrentThread in {}, inited {}'.format(th, self.inited))
|
|
4223
|
+
|
|
4224
|
+
def __del__(self):
|
|
4225
|
+
self.Uninitialize()
|
|
4226
|
+
|
|
4227
|
+
def __enter__(self):
|
|
4228
|
+
return self
|
|
4229
|
+
|
|
4230
|
+
def __exit__(self, exceptionType, exceptionValue, exceptionTraceback):
|
|
4231
|
+
self.Uninitialize()
|
|
4232
|
+
|
|
4233
|
+
def Uninitialize(self):
|
|
4234
|
+
if self.inited:
|
|
4235
|
+
UninitializeUIAutomationInCurrentThread()
|
|
4236
|
+
self.inited = False
|
|
4237
|
+
if self.debug:
|
|
4238
|
+
th = threading.currentThread()
|
|
4239
|
+
print('\ncall UninitializeUIAutomationInCurrentThread in {}'.format(th))
|
|
4240
|
+
|
|
4241
|
+
|
|
4242
|
+
def InitializeUIAutomationInCurrentThread() -> None:
|
|
4243
|
+
"""
|
|
4244
|
+
Initialize UIAutomation in a new thread.
|
|
4245
|
+
If you want to use functionalities related to Controls and Patterns in a new thread.
|
|
4246
|
+
You must call this function first in the new thread.
|
|
4247
|
+
But you can't use use a Control or a Pattern created in a different thread.
|
|
4248
|
+
So you can't create a Control or a Pattern in main thread and then pass it to a new thread and use it.
|
|
4249
|
+
"""
|
|
4250
|
+
comtypes.CoInitializeEx()
|
|
4251
|
+
|
|
4252
|
+
|
|
4253
|
+
def UninitializeUIAutomationInCurrentThread() -> None:
|
|
4254
|
+
"""
|
|
4255
|
+
Uninitialize UIAutomation in a new thread after calling InitializeUIAutomationInCurrentThread.
|
|
4256
|
+
You must call this function when the new thread exits if you have called InitializeUIAutomationInCurrentThread in the same thread.
|
|
4257
|
+
"""
|
|
4258
|
+
comtypes.CoUninitialize()
|
|
4259
|
+
|
|
4260
|
+
|
|
4261
|
+
def SetGlobalSearchTimeout(seconds: float) -> None:
|
|
4262
|
+
"""
|
|
4263
|
+
seconds: float.
|
|
4264
|
+
To make this available, you need explicitly import uiautomation:
|
|
4265
|
+
from uiautomation import uiautomation as auto
|
|
4266
|
+
auto.SetGlobalSearchTimeout(10)
|
|
4267
|
+
"""
|
|
4268
|
+
global TIME_OUT_SECOND
|
|
4269
|
+
TIME_OUT_SECOND = seconds
|
|
4270
|
+
|
|
4271
|
+
|
|
4272
|
+
def WaitForExist(control: Control, timeout: float) -> bool:
|
|
4273
|
+
"""
|
|
4274
|
+
Check if control exists in timeout seconds.
|
|
4275
|
+
control: `Control` or its subclass.
|
|
4276
|
+
timeout: float.
|
|
4277
|
+
Return bool.
|
|
4278
|
+
"""
|
|
4279
|
+
return control.Exists(timeout, 1)
|
|
4280
|
+
|
|
4281
|
+
|
|
4282
|
+
def WaitForDisappear(control: Control, timeout: float) -> bool:
|
|
4283
|
+
"""
|
|
4284
|
+
Check if control disappears in timeout seconds.
|
|
4285
|
+
control: `Control` or its subclass.
|
|
4286
|
+
timeout: float.
|
|
4287
|
+
Return bool.
|
|
4288
|
+
"""
|
|
4289
|
+
return control.Disappears(timeout, 1)
|
|
4290
|
+
|
|
4291
|
+
|
|
4292
|
+
def WalkTree(top, getChildren: Optional[Callable[[TreeNode], List[TreeNode]]] = None,
|
|
4293
|
+
getFirstChild: Optional[Callable[[TreeNode], TreeNode]] = None, getNextSibling: Optional[Callable[[TreeNode], TreeNode]] = None,
|
|
4294
|
+
yieldCondition: Optional[Callable[[TreeNode, int], bool]] = None, includeTop: bool = False, maxDepth: int = 0xFFFFFFFF):
|
|
4295
|
+
"""
|
|
4296
|
+
Walk a tree not using recursive algorithm.
|
|
4297
|
+
top: a tree node.
|
|
4298
|
+
getChildren: Callable[[TreeNode], List[TreeNode]], function(treeNode: TreeNode) -> List[TreeNode].
|
|
4299
|
+
getNextSibling: Callable[[TreeNode], TreeNode], function(treeNode: TreeNode) -> TreeNode.
|
|
4300
|
+
getNextSibling: Callable[[TreeNode], TreeNode], function(treeNode: TreeNode) -> TreeNode.
|
|
4301
|
+
yieldCondition: Callable[[TreeNode, int], bool], function(treeNode: TreeNode, depth: int) -> bool.
|
|
4302
|
+
includeTop: bool, if True yield top first.
|
|
4303
|
+
maxDepth: int, enum depth.
|
|
4304
|
+
|
|
4305
|
+
If getChildren is valid, ignore getFirstChild and getNextSibling,
|
|
4306
|
+
yield 3 items tuple: (treeNode, depth, remain children count in current depth).
|
|
4307
|
+
If getChildren is not valid, using getFirstChild and getNextSibling,
|
|
4308
|
+
yield 2 items tuple: (treeNode, depth).
|
|
4309
|
+
If yieldCondition is not None, only yield tree nodes that yieldCondition(treeNode: TreeNode, depth: int)->bool returns True.
|
|
4310
|
+
|
|
4311
|
+
For example:
|
|
4312
|
+
def GetDirChildren(dir_):
|
|
4313
|
+
if os.path.isdir(dir_):
|
|
4314
|
+
return [os.path.join(dir_, it) for it in os.listdir(dir_)]
|
|
4315
|
+
for it, depth, leftCount in WalkTree('D:\\', getChildren= GetDirChildren):
|
|
4316
|
+
print(it, depth, leftCount)
|
|
4317
|
+
"""
|
|
4318
|
+
if maxDepth <= 0:
|
|
4319
|
+
return
|
|
4320
|
+
depth = 0
|
|
4321
|
+
if getChildren:
|
|
4322
|
+
if includeTop:
|
|
4323
|
+
if not yieldCondition or yieldCondition(top, 0):
|
|
4324
|
+
yield top, 0, 0
|
|
4325
|
+
children = getChildren(top)
|
|
4326
|
+
childList = [children]
|
|
4327
|
+
while depth >= 0: # or while childList:
|
|
4328
|
+
lastItems = childList[-1]
|
|
4329
|
+
if lastItems:
|
|
4330
|
+
if not yieldCondition or yieldCondition(lastItems[0], depth + 1):
|
|
4331
|
+
yield lastItems[0], depth + 1, len(lastItems) - 1
|
|
4332
|
+
if depth + 1 < maxDepth:
|
|
4333
|
+
children = getChildren(lastItems[0])
|
|
4334
|
+
if children:
|
|
4335
|
+
depth += 1
|
|
4336
|
+
childList.append(children)
|
|
4337
|
+
del lastItems[0]
|
|
4338
|
+
else:
|
|
4339
|
+
del childList[depth]
|
|
4340
|
+
depth -= 1
|
|
4341
|
+
elif getFirstChild and getNextSibling:
|
|
4342
|
+
if includeTop:
|
|
4343
|
+
if not yieldCondition or yieldCondition(top, 0):
|
|
4344
|
+
yield top, 0
|
|
4345
|
+
child = getFirstChild(top)
|
|
4346
|
+
childList = [child]
|
|
4347
|
+
while depth >= 0: # or while childList:
|
|
4348
|
+
lastItem = childList[-1]
|
|
4349
|
+
if lastItem:
|
|
4350
|
+
if not yieldCondition or yieldCondition(lastItem, depth + 1):
|
|
4351
|
+
yield lastItem, depth + 1
|
|
4352
|
+
child = getNextSibling(lastItem)
|
|
4353
|
+
childList[depth] = child
|
|
4354
|
+
if depth + 1 < maxDepth:
|
|
4355
|
+
child = getFirstChild(lastItem)
|
|
4356
|
+
if child:
|
|
4357
|
+
depth += 1
|
|
4358
|
+
childList.append(child)
|
|
4359
|
+
else:
|
|
4360
|
+
del childList[depth]
|
|
4361
|
+
depth -= 1
|
|
4362
|
+
|
|
4363
|
+
|
|
4364
|
+
def GetRootControl() -> PaneControl:
|
|
4365
|
+
"""
|
|
4366
|
+
Get root control, the Desktop window.
|
|
4367
|
+
Return `PaneControl`.
|
|
4368
|
+
"""
|
|
4369
|
+
control = Control.CreateControlFromElement(_AutomationClient.instance().IUIAutomation.GetRootElement())
|
|
4370
|
+
if isinstance(control, PaneControl):
|
|
4371
|
+
return control
|
|
4372
|
+
|
|
4373
|
+
if control is None:
|
|
4374
|
+
raise AssertionError('Expected valid root element')
|
|
4375
|
+
raise AssertionError('Expected root element to be a PaneControl. Found: %s (%s)' % (type(control), control))
|
|
4376
|
+
|
|
4377
|
+
|
|
4378
|
+
def GetFocusedControl() -> Optional[Control]:
|
|
4379
|
+
"""Return `Control` subclass."""
|
|
4380
|
+
return Control.CreateControlFromElement(_AutomationClient.instance().IUIAutomation.GetFocusedElement())
|
|
4381
|
+
|
|
4382
|
+
|
|
4383
|
+
def GetForegroundControl() -> Control:
|
|
4384
|
+
"""Return `Control` subclass."""
|
|
4385
|
+
return ControlFromHandle(GetForegroundWindow())
|
|
4386
|
+
# another implement
|
|
4387
|
+
#focusedControl = GetFocusedControl()
|
|
4388
|
+
#parentControl = focusedControl
|
|
4389
|
+
#controlList = []
|
|
4390
|
+
# while parentControl:
|
|
4391
|
+
#controlList.insert(0, parentControl)
|
|
4392
|
+
#parentControl = parentControl.GetParentControl()
|
|
4393
|
+
# if len(controlList) == 1:
|
|
4394
|
+
#parentControl = controlList[0]
|
|
4395
|
+
# else:
|
|
4396
|
+
#parentControl = controlList[1]
|
|
4397
|
+
# return parentControl
|
|
4398
|
+
|
|
4399
|
+
|
|
4400
|
+
def GetConsoleWindow() -> Optional[WindowControl]:
|
|
4401
|
+
"""Return `WindowControl` or None, a console window that runs python."""
|
|
4402
|
+
consoleWindow = ControlFromHandle(ctypes.windll.kernel32.GetConsoleWindow())
|
|
4403
|
+
if consoleWindow and consoleWindow.ClassName == 'PseudoConsoleWindow':
|
|
4404
|
+
# Windows Terminal
|
|
4405
|
+
consoleWindow = consoleWindow.GetParentControl()
|
|
4406
|
+
return consoleWindow
|
|
4407
|
+
|
|
4408
|
+
|
|
4409
|
+
def ControlFromPoint(x: int, y: int) -> Optional[Control]:
|
|
4410
|
+
"""
|
|
4411
|
+
Call IUIAutomation ElementFromPoint x,y. May return None if mouse is over cmd's title bar icon.
|
|
4412
|
+
Return `Control` subclass or None.
|
|
4413
|
+
"""
|
|
4414
|
+
element = _AutomationClient.instance().IUIAutomation.ElementFromPoint(ctypes.wintypes.POINT(x, y))
|
|
4415
|
+
return Control.CreateControlFromElement(element)
|
|
4416
|
+
|
|
4417
|
+
|
|
4418
|
+
def ControlFromPoint2(x: int, y: int) -> Optional[Control]:
|
|
4419
|
+
"""
|
|
4420
|
+
Get a native handle from point x,y and call IUIAutomation.ElementFromHandle.
|
|
4421
|
+
Return `Control` subclass.
|
|
4422
|
+
"""
|
|
4423
|
+
return Control.CreateControlFromElement(_AutomationClient.instance().IUIAutomation.ElementFromHandle(WindowFromPoint(x, y)))
|
|
4424
|
+
|
|
4425
|
+
|
|
4426
|
+
def ControlFromCursor() -> Optional[Control]:
|
|
4427
|
+
"""
|
|
4428
|
+
Call ControlFromPoint with current cursor point.
|
|
4429
|
+
Return `Control` subclass.
|
|
4430
|
+
"""
|
|
4431
|
+
x, y = GetCursorPos()
|
|
4432
|
+
return ControlFromPoint(x, y)
|
|
4433
|
+
|
|
4434
|
+
|
|
4435
|
+
def ControlFromCursor2() -> Optional[Control]:
|
|
4436
|
+
"""
|
|
4437
|
+
Call ControlFromPoint2 with current cursor point.
|
|
4438
|
+
Return `Control` subclass.
|
|
4439
|
+
"""
|
|
4440
|
+
x, y = GetCursorPos()
|
|
4441
|
+
return ControlFromPoint2(x, y)
|
|
4442
|
+
|
|
4443
|
+
|
|
4444
|
+
def ControlFromHandle(handle: int) -> Optional[Control]:
|
|
4445
|
+
"""
|
|
4446
|
+
Call IUIAutomation.ElementFromHandle with a native handle.
|
|
4447
|
+
handle: int, a native window handle.
|
|
4448
|
+
Return `Control` subclass or None.
|
|
4449
|
+
"""
|
|
4450
|
+
if handle:
|
|
4451
|
+
return Control.CreateControlFromElement(_AutomationClient.instance().IUIAutomation.ElementFromHandle(handle))
|
|
4452
|
+
return None
|
|
4453
|
+
|
|
4454
|
+
|
|
4455
|
+
def ControlsAreSame(control1: Control, control2: Control) -> bool:
|
|
4456
|
+
"""
|
|
4457
|
+
control1: `Control` or its subclass.
|
|
4458
|
+
control2: `Control` or its subclass.
|
|
4459
|
+
Return bool, True if control1 and control2 represent the same control otherwise False.
|
|
4460
|
+
"""
|
|
4461
|
+
return bool(_AutomationClient.instance().IUIAutomation.CompareElements(control1.Element, control2.Element))
|
|
4462
|
+
|
|
4463
|
+
|
|
4464
|
+
def WalkControl(control: Control, includeTop: bool = False, maxDepth: int = 0xFFFFFFFF) -> Generator[Tuple[Control, int], None, None]:
|
|
4465
|
+
"""
|
|
4466
|
+
control: `Control` or its subclass.
|
|
4467
|
+
includeTop: bool, if True, yield (control, 0) first.
|
|
4468
|
+
maxDepth: int, enum depth.
|
|
4469
|
+
Yield 2 items tuple (control: Control, depth: int).
|
|
4470
|
+
"""
|
|
4471
|
+
if includeTop:
|
|
4472
|
+
yield control, 0
|
|
4473
|
+
if maxDepth <= 0:
|
|
4474
|
+
return
|
|
4475
|
+
depth = 0
|
|
4476
|
+
child = control.GetFirstChildControl()
|
|
4477
|
+
controlList = [child]
|
|
4478
|
+
while depth >= 0:
|
|
4479
|
+
lastControl = controlList[-1]
|
|
4480
|
+
if lastControl:
|
|
4481
|
+
yield lastControl, depth + 1
|
|
4482
|
+
child = lastControl.GetNextSiblingControl()
|
|
4483
|
+
controlList[depth] = child
|
|
4484
|
+
if depth + 1 < maxDepth:
|
|
4485
|
+
child = lastControl.GetFirstChildControl()
|
|
4486
|
+
if child:
|
|
4487
|
+
depth += 1
|
|
4488
|
+
controlList.append(child)
|
|
4489
|
+
else:
|
|
4490
|
+
del controlList[depth]
|
|
4491
|
+
depth -= 1
|
|
4492
|
+
|
|
4493
|
+
|
|
4494
|
+
def LogControl(control: Control, depth: int = 0, showAllName: bool = True, showPid: bool = False) -> None:
|
|
4495
|
+
"""
|
|
4496
|
+
Print and log control's properties.
|
|
4497
|
+
control: `Control` or its subclass.
|
|
4498
|
+
depth: int, current depth.
|
|
4499
|
+
showAllName: bool, if False, print the first 30 characters of control.Name.
|
|
4500
|
+
"""
|
|
4501
|
+
indent = ' ' * depth * 4
|
|
4502
|
+
Logger.Write('{0}ControlType: '.format(indent))
|
|
4503
|
+
Logger.Write(control.ControlTypeName, ConsoleColor.DarkGreen)
|
|
4504
|
+
Logger.Write(' ClassName: ')
|
|
4505
|
+
Logger.Write(control.ClassName, ConsoleColor.DarkGreen)
|
|
4506
|
+
Logger.Write(' AutomationId: ')
|
|
4507
|
+
Logger.Write(control.AutomationId, ConsoleColor.DarkGreen)
|
|
4508
|
+
Logger.Write(' Rect: ')
|
|
4509
|
+
Logger.Write(control.BoundingRectangle, ConsoleColor.DarkGreen)
|
|
4510
|
+
Logger.Write(' Name: ')
|
|
4511
|
+
Logger.Write(control.Name, ConsoleColor.DarkGreen, printTruncateLen=0 if showAllName else 30)
|
|
4512
|
+
Logger.Write(' Handle: ')
|
|
4513
|
+
Logger.Write('0x{0:X}({0})'.format(control.NativeWindowHandle), ConsoleColor.DarkGreen)
|
|
4514
|
+
Logger.Write(' Depth: ')
|
|
4515
|
+
Logger.Write(depth, ConsoleColor.DarkGreen)
|
|
4516
|
+
if showPid:
|
|
4517
|
+
Logger.Write(' ProcessId: ')
|
|
4518
|
+
Logger.Write(control.ProcessId, ConsoleColor.DarkGreen)
|
|
4519
|
+
supportedPatterns = list(filter(lambda t: t[0], ((control.GetPattern(id_), name) for id_, name in PatternIdNames.items())))
|
|
4520
|
+
for pt, name in supportedPatterns:
|
|
4521
|
+
if isinstance(pt, ValuePattern):
|
|
4522
|
+
Logger.Write(' ValuePattern.Value: ')
|
|
4523
|
+
Logger.Write(repr(pt.Value), ConsoleColor.DarkGreen, printTruncateLen=0 if showAllName else 30)
|
|
4524
|
+
elif isinstance(pt, RangeValuePattern):
|
|
4525
|
+
Logger.Write(' RangeValuePattern.Value: ')
|
|
4526
|
+
Logger.Write(pt.Value, ConsoleColor.DarkGreen)
|
|
4527
|
+
elif isinstance(pt, TogglePattern):
|
|
4528
|
+
Logger.Write(' TogglePattern.ToggleState: ')
|
|
4529
|
+
Logger.Write('ToggleState.' + _GetDictKeyName(ToggleState.__dict__, pt.ToggleState), ConsoleColor.DarkGreen)
|
|
4530
|
+
elif isinstance(pt, SelectionItemPattern):
|
|
4531
|
+
Logger.Write(' SelectionItemPattern.IsSelected: ')
|
|
4532
|
+
Logger.Write(pt.IsSelected, ConsoleColor.DarkGreen)
|
|
4533
|
+
elif isinstance(pt, ExpandCollapsePattern):
|
|
4534
|
+
Logger.Write(' ExpandCollapsePattern.ExpandCollapseState: ')
|
|
4535
|
+
Logger.Write('ExpandCollapseState.' + _GetDictKeyName(ExpandCollapseState.__dict__, pt.ExpandCollapseState), ConsoleColor.DarkGreen)
|
|
4536
|
+
elif isinstance(pt, ScrollPattern):
|
|
4537
|
+
Logger.Write(' ScrollPattern.HorizontalScrollPercent: ')
|
|
4538
|
+
Logger.Write(pt.HorizontalScrollPercent, ConsoleColor.DarkGreen)
|
|
4539
|
+
Logger.Write(' ScrollPattern.VerticalScrollPercent: ')
|
|
4540
|
+
Logger.Write(pt.VerticalScrollPercent, ConsoleColor.DarkGreen)
|
|
4541
|
+
elif isinstance(pt, GridPattern):
|
|
4542
|
+
Logger.Write(' GridPattern.RowCount: ')
|
|
4543
|
+
Logger.Write(pt.RowCount, ConsoleColor.DarkGreen)
|
|
4544
|
+
Logger.Write(' GridPattern.ColumnCount: ')
|
|
4545
|
+
Logger.Write(pt.ColumnCount, ConsoleColor.DarkGreen)
|
|
4546
|
+
elif isinstance(pt, GridItemPattern):
|
|
4547
|
+
Logger.Write(' GridItemPattern.Row: ')
|
|
4548
|
+
Logger.Write(pt.Row, ConsoleColor.DarkGreen)
|
|
4549
|
+
Logger.Write(' GridItemPattern.Column: ')
|
|
4550
|
+
Logger.Write(pt.Column, ConsoleColor.DarkGreen)
|
|
4551
|
+
elif isinstance(pt, TextPattern):
|
|
4552
|
+
# issue 49: CEF Control as DocumentControl have no "TextPattern.Text" property, skip log this part.
|
|
4553
|
+
# https://docs.microsoft.com/en-us/windows/win32/api/uiautomationclient/nf-uiautomationclient-iuiautomationtextpattern-get_documentrange
|
|
4554
|
+
try:
|
|
4555
|
+
Logger.Write(' TextPattern.Text: ')
|
|
4556
|
+
Logger.Write(repr(pt.DocumentRange.GetText(30)), ConsoleColor.DarkGreen)
|
|
4557
|
+
except comtypes.COMError as ex:
|
|
4558
|
+
pass
|
|
4559
|
+
Logger.Write(' SupportedPattern:')
|
|
4560
|
+
for pt, name in supportedPatterns:
|
|
4561
|
+
Logger.Write(' ' + name, ConsoleColor.DarkGreen)
|
|
4562
|
+
Logger.Write('\n')
|
|
4563
|
+
|
|
4564
|
+
|
|
4565
|
+
def EnumAndLogControl(control: Control, maxDepth: int = 0xFFFFFFFF, showAllName: bool = True, showPid: bool = False, startDepth: int = 0) -> None:
|
|
4566
|
+
"""
|
|
4567
|
+
Print and log control and its descendants' propertyies.
|
|
4568
|
+
control: `Control` or its subclass.
|
|
4569
|
+
maxDepth: int, enum depth.
|
|
4570
|
+
showAllName: bool, if False, print the first 30 characters of control.Name.
|
|
4571
|
+
startDepth: int, control's current depth.
|
|
4572
|
+
"""
|
|
4573
|
+
for c, d in WalkControl(control, True, maxDepth):
|
|
4574
|
+
LogControl(c, d + startDepth, showAllName, showPid)
|
|
4575
|
+
|
|
4576
|
+
|
|
4577
|
+
def EnumAndLogControlAncestors(control: Control, showAllName: bool = True, showPid: bool = False) -> None:
|
|
4578
|
+
"""
|
|
4579
|
+
Print and log control and its ancestors' propertyies.
|
|
4580
|
+
control: `Control` or its subclass.
|
|
4581
|
+
showAllName: bool, if False, print the first 30 characters of control.Name.
|
|
4582
|
+
"""
|
|
4583
|
+
curr = control
|
|
4584
|
+
lists = []
|
|
4585
|
+
while curr:
|
|
4586
|
+
lists.insert(0, curr)
|
|
4587
|
+
curr = curr.GetParentControl()
|
|
4588
|
+
for i, curr in enumerate(lists):
|
|
4589
|
+
LogControl(curr, i, showAllName, showPid)
|
|
4590
|
+
|
|
4591
|
+
|
|
4592
|
+
def FindControl(control: Optional[Control], compare: Callable[[Control, int], bool], maxDepth: int = 0xFFFFFFFF, findFromSelf: bool = False, foundIndex: int = 1) -> Optional[Control]:
|
|
4593
|
+
"""
|
|
4594
|
+
control: `Control` or its subclass.
|
|
4595
|
+
compare: Callable[[Control, int], bool], function(control: Control, depth: int) -> bool.
|
|
4596
|
+
maxDepth: int, enum depth.
|
|
4597
|
+
findFromSelf: bool, if False, do not compare self.
|
|
4598
|
+
foundIndex: int, starts with 1, >= 1.
|
|
4599
|
+
Return `Control` subclass or None if not find.
|
|
4600
|
+
"""
|
|
4601
|
+
foundCount = 0
|
|
4602
|
+
if not control:
|
|
4603
|
+
control = GetRootControl()
|
|
4604
|
+
traverseCount = 0
|
|
4605
|
+
for child, depth in WalkControl(control, findFromSelf, maxDepth):
|
|
4606
|
+
traverseCount += 1
|
|
4607
|
+
if compare(child, depth):
|
|
4608
|
+
foundCount += 1
|
|
4609
|
+
if foundCount == foundIndex:
|
|
4610
|
+
child.traverseCount = traverseCount
|
|
4611
|
+
return child
|
|
4612
|
+
return None
|
|
4613
|
+
|
|
4614
|
+
|
|
4615
|
+
def ShowDesktop(waitTime: float = 1) -> None:
|
|
4616
|
+
"""Show Desktop by pressing win + d"""
|
|
4617
|
+
SendKeys('{Win}d', waitTime=waitTime)
|
|
4618
|
+
# another implement
|
|
4619
|
+
#paneTray = PaneControl(searchDepth = 1, ClassName = 'Shell_TrayWnd')
|
|
4620
|
+
# if paneTray.Exists():
|
|
4621
|
+
#WM_COMMAND = 0x111
|
|
4622
|
+
#MIN_ALL = 419
|
|
4623
|
+
#MIN_ALL_UNDO = 416
|
|
4624
|
+
#PostMessage(paneTray.NativeWindowHandle, WM_COMMAND, MIN_ALL, 0)
|
|
4625
|
+
# time.sleep(1)
|
|
4626
|
+
|
|
4627
|
+
|
|
4628
|
+
def WaitHotKeyReleased(hotkey: Tuple[int, int]) -> None:
|
|
4629
|
+
"""hotkey: Tuple[int, int], two ints tuple (modifierKey, key)"""
|
|
4630
|
+
mod = {ModifierKey.Alt: Keys.VK_MENU,
|
|
4631
|
+
ModifierKey.Control: Keys.VK_CONTROL,
|
|
4632
|
+
ModifierKey.Shift: Keys.VK_SHIFT,
|
|
4633
|
+
ModifierKey.Win: Keys.VK_LWIN
|
|
4634
|
+
}
|
|
4635
|
+
while True:
|
|
4636
|
+
time.sleep(0.05)
|
|
4637
|
+
if IsKeyPressed(hotkey[1]):
|
|
4638
|
+
continue
|
|
4639
|
+
for k, v in mod.items():
|
|
4640
|
+
if k & hotkey[0]:
|
|
4641
|
+
if IsKeyPressed(v):
|
|
4642
|
+
break
|
|
4643
|
+
else:
|
|
4644
|
+
break
|
|
4645
|
+
|
|
4646
|
+
|
|
4647
|
+
def RunByHotKey(keyFunctions: Dict[Tuple[int, int], Callable], stopHotKey: Optional[Tuple[int, int]] = None, exitHotKey: Tuple[int, int] = (ModifierKey.Control, Keys.VK_D), waitHotKeyReleased: bool = True) -> None:
|
|
4648
|
+
"""
|
|
4649
|
+
Bind functions with hotkeys, the function will be run or stopped in another thread when the hotkey is pressed.
|
|
4650
|
+
keyFunctions: Dict[Tuple[int, int], Callable], such as {(uiautomation.ModifierKey.Control, uiautomation.Keys.VK_1) : function}
|
|
4651
|
+
stopHotKey: hotkey tuple
|
|
4652
|
+
exitHotKey: hotkey tuple
|
|
4653
|
+
waitHotKeyReleased: bool, if True, hotkey function will be triggered after the hotkey is released
|
|
4654
|
+
|
|
4655
|
+
def main(stopEvent):
|
|
4656
|
+
while True:
|
|
4657
|
+
if stopEvent.is_set(): # must check stopEvent.is_set() if you want to stop when stop hotkey is pressed
|
|
4658
|
+
break
|
|
4659
|
+
print(n)
|
|
4660
|
+
n += 1
|
|
4661
|
+
stopEvent.wait(1)
|
|
4662
|
+
print('main exit')
|
|
4663
|
+
|
|
4664
|
+
uiautomation.RunByHotKey({(uiautomation.ModifierKey.Control, uiautomation.Keys.VK_1) : main}
|
|
4665
|
+
, (uiautomation.ModifierKey.Control | uiautomation.ModifierKey.Shift, uiautomation.Keys.VK_2))
|
|
4666
|
+
"""
|
|
4667
|
+
import traceback
|
|
4668
|
+
|
|
4669
|
+
def getModName(theDict, theValue):
|
|
4670
|
+
name = ''
|
|
4671
|
+
for key in theDict:
|
|
4672
|
+
if isinstance(theDict[key], int) and theValue & theDict[key]:
|
|
4673
|
+
if name:
|
|
4674
|
+
name += '|'
|
|
4675
|
+
name += key
|
|
4676
|
+
return name
|
|
4677
|
+
|
|
4678
|
+
def releaseAllKeys():
|
|
4679
|
+
for key, value in Keys.__dict__.items():
|
|
4680
|
+
if isinstance(value, int) and key.startswith('VK'):
|
|
4681
|
+
if IsKeyPressed(value):
|
|
4682
|
+
ReleaseKey(value)
|
|
4683
|
+
|
|
4684
|
+
def threadFunc(function, stopEvent, hotkey, hotkeyName):
|
|
4685
|
+
if waitHotKeyReleased:
|
|
4686
|
+
WaitHotKeyReleased(hotkey)
|
|
4687
|
+
try:
|
|
4688
|
+
function(stopEvent)
|
|
4689
|
+
except Exception as ex:
|
|
4690
|
+
Logger.ColorfullyWrite('Catch an exception <Color=Red>{}</Color> in thread for hotkey <Color=DarkCyan>{}</Color>\n'.format(
|
|
4691
|
+
ex.__class__.__name__, hotkeyName), writeToFile=False)
|
|
4692
|
+
print(traceback.format_exc())
|
|
4693
|
+
finally:
|
|
4694
|
+
releaseAllKeys() # need to release keys if some keys were pressed
|
|
4695
|
+
Logger.ColorfullyWrite('{} for function <Color=DarkCyan>{}</Color> exits, hotkey <Color=DarkCyan>{}</Color>\n'.format(
|
|
4696
|
+
threading.currentThread(), function.__name__, hotkeyName), ConsoleColor.DarkYellow, writeToFile=False)
|
|
4697
|
+
|
|
4698
|
+
stopHotKeyId = 1
|
|
4699
|
+
exitHotKeyId = 2
|
|
4700
|
+
hotKeyId = 3
|
|
4701
|
+
registed = True
|
|
4702
|
+
id2HotKey = {}
|
|
4703
|
+
id2Function = {}
|
|
4704
|
+
id2Thread = {}
|
|
4705
|
+
id2Name = {}
|
|
4706
|
+
for hotkey in keyFunctions:
|
|
4707
|
+
id2HotKey[hotKeyId] = hotkey
|
|
4708
|
+
id2Function[hotKeyId] = keyFunctions[hotkey]
|
|
4709
|
+
id2Thread[hotKeyId] = None
|
|
4710
|
+
modName = getModName(ModifierKey.__dict__, hotkey[0])
|
|
4711
|
+
keyName = _GetDictKeyName(Keys.__dict__, hotkey[1])
|
|
4712
|
+
id2Name[hotKeyId] = str((modName, keyName))
|
|
4713
|
+
if ctypes.windll.user32.RegisterHotKey(0, hotKeyId, hotkey[0], hotkey[1]):
|
|
4714
|
+
Logger.ColorfullyWrite('Register hotkey <Color=Cyan>{}</Color> successfully\n'.format((modName, keyName)), writeToFile=False)
|
|
4715
|
+
else:
|
|
4716
|
+
registed = False
|
|
4717
|
+
Logger.ColorfullyWrite('Register hotkey <Color=Cyan>{}</Color> unsuccessfully, maybe it was allready registered by another program\n'.format((modName, keyName)), writeToFile=False)
|
|
4718
|
+
hotKeyId += 1
|
|
4719
|
+
if stopHotKey and len(stopHotKey) == 2:
|
|
4720
|
+
modName = getModName(ModifierKey.__dict__, stopHotKey[0])
|
|
4721
|
+
keyName = _GetDictKeyName(Keys.__dict__, stopHotKey[1])
|
|
4722
|
+
if ctypes.windll.user32.RegisterHotKey(0, stopHotKeyId, stopHotKey[0], stopHotKey[1]):
|
|
4723
|
+
Logger.ColorfullyWrite('Register stop hotkey <Color=DarkYellow>{}</Color> successfully\n'.format((modName, keyName)), writeToFile=False)
|
|
4724
|
+
else:
|
|
4725
|
+
registed = False
|
|
4726
|
+
Logger.ColorfullyWrite('Register stop hotkey <Color=DarkYellow>{}</Color> unsuccessfully, maybe it was allready registered by another program\n'.format((modName, keyName)), writeToFile=False)
|
|
4727
|
+
if not registed:
|
|
4728
|
+
return
|
|
4729
|
+
if exitHotKey and len(exitHotKey) == 2:
|
|
4730
|
+
modName = getModName(ModifierKey.__dict__, exitHotKey[0])
|
|
4731
|
+
keyName = _GetDictKeyName(Keys.__dict__, exitHotKey[1])
|
|
4732
|
+
if ctypes.windll.user32.RegisterHotKey(0, exitHotKeyId, exitHotKey[0], exitHotKey[1]):
|
|
4733
|
+
Logger.ColorfullyWrite('Register exit hotkey <Color=DarkYellow>{}</Color> successfully\n'.format((modName, keyName)), writeToFile=False)
|
|
4734
|
+
else:
|
|
4735
|
+
Logger.ColorfullyWrite('Register exit hotkey <Color=DarkYellow>{}</Color> unsuccessfully\n'.format((modName, keyName)), writeToFile=False)
|
|
4736
|
+
funcThread = None
|
|
4737
|
+
livingThreads = []
|
|
4738
|
+
stopEvent = threading.Event()
|
|
4739
|
+
msg = ctypes.wintypes.MSG()
|
|
4740
|
+
while ctypes.windll.user32.GetMessageW(ctypes.byref(msg), ctypes.c_void_p(0), ctypes.c_uint(0), ctypes.c_uint(0)) != 0:
|
|
4741
|
+
if msg.message == 0x0312: # WM_HOTKEY=0x0312
|
|
4742
|
+
if msg.wParam in id2HotKey:
|
|
4743
|
+
if msg.lParam & 0x0000FFFF == id2HotKey[msg.wParam][0] and msg.lParam >> 16 & 0x0000FFFF == id2HotKey[msg.wParam][1]:
|
|
4744
|
+
Logger.ColorfullyWrite('----------hotkey <Color=Cyan>{}</Color> pressed----------\n'.format(id2Name[msg.wParam]), writeToFile=False)
|
|
4745
|
+
if not id2Thread[msg.wParam]:
|
|
4746
|
+
stopEvent.clear()
|
|
4747
|
+
funcThread = threading.Thread(None, threadFunc, args=(id2Function[msg.wParam], stopEvent, id2HotKey[msg.wParam], id2Name[msg.wParam]))
|
|
4748
|
+
funcThread.start()
|
|
4749
|
+
id2Thread[msg.wParam] = funcThread
|
|
4750
|
+
else:
|
|
4751
|
+
if id2Thread[msg.wParam].is_alive():
|
|
4752
|
+
Logger.WriteLine('There is a {} that is already running for hotkey {}'.format(id2Thread[msg.wParam], id2Name[msg.wParam]), ConsoleColor.Yellow, writeToFile=False)
|
|
4753
|
+
else:
|
|
4754
|
+
stopEvent.clear()
|
|
4755
|
+
funcThread = threading.Thread(None, threadFunc, args=(id2Function[msg.wParam], stopEvent, id2HotKey[msg.wParam], id2Name[msg.wParam]))
|
|
4756
|
+
funcThread.start()
|
|
4757
|
+
id2Thread[msg.wParam] = funcThread
|
|
4758
|
+
elif stopHotKeyId == msg.wParam:
|
|
4759
|
+
if msg.lParam & 0x0000FFFF == stopHotKey[0] and msg.lParam >> 16 & 0x0000FFFF == stopHotKey[1]:
|
|
4760
|
+
Logger.Write('----------stop hotkey pressed----------\n', ConsoleColor.DarkYellow, writeToFile=False)
|
|
4761
|
+
stopEvent.set()
|
|
4762
|
+
for id_ in id2Thread:
|
|
4763
|
+
if id2Thread[id_]:
|
|
4764
|
+
if id2Thread[id_].is_alive():
|
|
4765
|
+
livingThreads.append((id2Thread[id_], id2Name[id_]))
|
|
4766
|
+
id2Thread[id_] = None
|
|
4767
|
+
elif exitHotKeyId == msg.wParam:
|
|
4768
|
+
if msg.lParam & 0x0000FFFF == exitHotKey[0] and msg.lParam >> 16 & 0x0000FFFF == exitHotKey[1]:
|
|
4769
|
+
Logger.Write('Exit hotkey pressed. Exit\n', ConsoleColor.DarkYellow, writeToFile=False)
|
|
4770
|
+
stopEvent.set()
|
|
4771
|
+
for id_ in id2Thread:
|
|
4772
|
+
if id2Thread[id_]:
|
|
4773
|
+
if id2Thread[id_].is_alive():
|
|
4774
|
+
livingThreads.append((id2Thread[id_], id2Name[id_]))
|
|
4775
|
+
id2Thread[id_] = None
|
|
4776
|
+
break
|
|
4777
|
+
for thread, hotkeyName in livingThreads:
|
|
4778
|
+
if thread.is_alive():
|
|
4779
|
+
Logger.Write('join {} triggered by hotkey {}\n'.format(thread, hotkeyName), ConsoleColor.DarkYellow, writeToFile=False)
|
|
4780
|
+
thread.join(2)
|
|
4781
|
+
exit()
|