0
# Automation Patterns
1
2
Implementation of Windows UI Automation patterns for specialized control operations. Patterns provide standardized interfaces for common control behaviors like invoking buttons, setting values, handling selections, and managing scrollable content.
3
4
## Capabilities
5
6
### Invoke Pattern
7
8
The Invoke pattern enables triggering of controls that perform a single action when activated.
9
10
```python { .api }
11
class InvokePattern:
12
"""Pattern for controls that can be invoked (clicked/activated)."""
13
14
def Invoke(self) -> None:
15
"""
16
Invoke the control (equivalent to clicking).
17
Typically used for buttons, menu items, and hyperlinks.
18
"""
19
```
20
21
### Value Pattern
22
23
The Value pattern provides access to controls that have a string value that can be read or set.
24
25
```python { .api }
26
class ValuePattern:
27
"""Pattern for controls with settable string values."""
28
29
def SetValue(self, value: str) -> None:
30
"""
31
Set the value of the control.
32
33
Args:
34
value: String value to set
35
"""
36
37
def GetValue(self) -> str:
38
"""
39
Get the current value of the control.
40
41
Returns:
42
str: Current string value of the control
43
"""
44
45
@property
46
def IsReadOnly(self) -> bool:
47
"""Whether the control's value is read-only."""
48
```
49
50
### Toggle Pattern
51
52
The Toggle pattern supports controls that can cycle through a set of states.
53
54
```python { .api }
55
class TogglePattern:
56
"""Pattern for controls with toggle states (checkboxes, toggle buttons)."""
57
58
def Toggle(self) -> None:
59
"""Toggle the control to its next state."""
60
61
@property
62
def ToggleState(self) -> int:
63
"""
64
Current toggle state.
65
66
Returns:
67
int: ToggleState constant (Off=0, On=1, Indeterminate=2)
68
"""
69
70
class ToggleState:
71
"""Constants for toggle states."""
72
Off: int = 0
73
On: int = 1
74
Indeterminate: int = 2
75
```
76
77
### Range Value Pattern
78
79
The Range Value pattern provides access to controls that represent a value within a range.
80
81
```python { .api }
82
class RangeValuePattern:
83
"""Pattern for controls with numeric ranges (sliders, progress bars)."""
84
85
def SetValue(self, value: float) -> None:
86
"""
87
Set the numeric value.
88
89
Args:
90
value: Numeric value within the valid range
91
"""
92
93
@property
94
def Value(self) -> float:
95
"""Current numeric value."""
96
97
@property
98
def Minimum(self) -> float:
99
"""Minimum allowed value."""
100
101
@property
102
def Maximum(self) -> float:
103
"""Maximum allowed value."""
104
105
@property
106
def SmallChange(self) -> float:
107
"""Small increment/decrement amount."""
108
109
@property
110
def LargeChange(self) -> float:
111
"""Large increment/decrement amount."""
112
113
@property
114
def IsReadOnly(self) -> bool:
115
"""Whether the value is read-only."""
116
```
117
118
### Selection Pattern
119
120
The Selection pattern supports controls that act as containers for selectable child items.
121
122
```python { .api }
123
class SelectionPattern:
124
"""Pattern for selection containers (lists, combo boxes)."""
125
126
def GetSelection(self) -> list:
127
"""
128
Get currently selected items.
129
130
Returns:
131
list: List of selected control elements
132
"""
133
134
@property
135
def CanSelectMultiple(self) -> bool:
136
"""Whether multiple items can be selected."""
137
138
@property
139
def IsSelectionRequired(self) -> bool:
140
"""Whether at least one item must be selected."""
141
```
142
143
### Selection Item Pattern
144
145
The Selection Item pattern supports individual items that can be selected within a selection container.
146
147
```python { .api }
148
class SelectionItemPattern:
149
"""Pattern for selectable items within selection containers."""
150
151
def Select(self) -> None:
152
"""Select this item (deselecting others if single-select)."""
153
154
def AddToSelection(self) -> None:
155
"""Add this item to the selection (multi-select containers)."""
156
157
def RemoveFromSelection(self) -> None:
158
"""Remove this item from the selection."""
159
160
@property
161
def IsSelected(self) -> bool:
162
"""Whether this item is currently selected."""
163
164
@property
165
def SelectionContainer(self):
166
"""The container control that manages selection."""
167
```
168
169
### Scroll Pattern
170
171
The Scroll pattern provides scrolling functionality for controls with scrollable content.
172
173
```python { .api }
174
class ScrollPattern:
175
"""Pattern for scrollable controls."""
176
177
def Scroll(self, horizontalAmount: int, verticalAmount: int) -> None:
178
"""
179
Scroll by specified amounts.
180
181
Args:
182
horizontalAmount: Horizontal scroll amount
183
verticalAmount: Vertical scroll amount
184
"""
185
186
def SetScrollPercent(self, horizontalPercent: float, verticalPercent: float) -> None:
187
"""
188
Set scroll position by percentage.
189
190
Args:
191
horizontalPercent: Horizontal position (0-100)
192
verticalPercent: Vertical position (0-100)
193
"""
194
195
@property
196
def HorizontalScrollPercent(self) -> float:
197
"""Current horizontal scroll percentage."""
198
199
@property
200
def VerticalScrollPercent(self) -> float:
201
"""Current vertical scroll percentage."""
202
203
@property
204
def HorizontalViewSize(self) -> float:
205
"""Horizontal view size as percentage of total."""
206
207
@property
208
def VerticalViewSize(self) -> float:
209
"""Vertical view size as percentage of total."""
210
211
@property
212
def HorizontallyScrollable(self) -> bool:
213
"""Whether horizontal scrolling is available."""
214
215
@property
216
def VerticallyScrollable(self) -> bool:
217
"""Whether vertical scrolling is available."""
218
```
219
220
### Scroll Item Pattern
221
222
The Scroll Item pattern enables individual items to scroll themselves into view.
223
224
```python { .api }
225
class ScrollItemPattern:
226
"""Pattern for items that can scroll themselves into view."""
227
228
def ScrollIntoView(self) -> None:
229
"""Scroll this item into the visible area of its container."""
230
```
231
232
### Expand Collapse Pattern
233
234
The Expand Collapse pattern supports controls that can expand to show more content or collapse to hide content.
235
236
```python { .api }
237
class ExpandCollapsePattern:
238
"""Pattern for expandable/collapsible controls (tree nodes, menus)."""
239
240
def Expand(self) -> None:
241
"""Expand the control to show child items."""
242
243
def Collapse(self) -> None:
244
"""Collapse the control to hide child items."""
245
246
@property
247
def ExpandCollapseState(self) -> int:
248
"""
249
Current expand/collapse state.
250
251
Returns:
252
int: ExpandCollapseState constant
253
"""
254
255
class ExpandCollapseState:
256
"""Constants for expand/collapse states."""
257
Collapsed: int = 0
258
Expanded: int = 1
259
PartiallyExpanded: int = 2
260
LeafNode: int = 3
261
```
262
263
### Grid Pattern
264
265
The Grid pattern provides access to controls that act as containers for a collection of child elements organized in a grid.
266
267
```python { .api }
268
class GridPattern:
269
"""Pattern for grid controls (data grids, tables)."""
270
271
def GetItem(self, row: int, column: int):
272
"""
273
Get the control at the specified grid coordinates.
274
275
Args:
276
row: Zero-based row index
277
column: Zero-based column index
278
279
Returns:
280
Control: The control at the specified position
281
"""
282
283
@property
284
def RowCount(self) -> int:
285
"""Number of rows in the grid."""
286
287
@property
288
def ColumnCount(self) -> int:
289
"""Number of columns in the grid."""
290
```
291
292
### Grid Item Pattern
293
294
The Grid Item pattern provides information about individual items within a grid.
295
296
```python { .api }
297
class GridItemPattern:
298
"""Pattern for individual items within grid controls."""
299
300
@property
301
def Row(self) -> int:
302
"""Zero-based row index of this item."""
303
304
@property
305
def Column(self) -> int:
306
"""Zero-based column index of this item."""
307
308
@property
309
def RowSpan(self) -> int:
310
"""Number of rows spanned by this item."""
311
312
@property
313
def ColumnSpan(self) -> int:
314
"""Number of columns spanned by this item."""
315
316
@property
317
def ContainingGrid(self):
318
"""The grid control containing this item."""
319
```
320
321
### Window Pattern
322
323
The Window pattern provides access to window-specific functionality.
324
325
```python { .api }
326
class WindowPattern:
327
"""Pattern for window controls."""
328
329
def Close(self) -> None:
330
"""Close the window."""
331
332
def SetWindowVisualState(self, state: int) -> None:
333
"""
334
Set the window's visual state.
335
336
Args:
337
state: WindowVisualState constant
338
"""
339
340
def WaitForInputIdle(self, timeout: int) -> bool:
341
"""
342
Wait for the window to be ready for user input.
343
344
Args:
345
timeout: Timeout in milliseconds
346
347
Returns:
348
bool: True if window became ready, False if timeout
349
"""
350
351
@property
352
def WindowVisualState(self) -> int:
353
"""Current window visual state."""
354
355
@property
356
def WindowInteractionState(self) -> int:
357
"""Current window interaction state."""
358
359
@property
360
def IsModal(self) -> bool:
361
"""Whether the window is modal."""
362
363
@property
364
def IsTopmost(self) -> bool:
365
"""Whether the window is topmost."""
366
367
@property
368
def Maximizable(self) -> bool:
369
"""Whether the window can be maximized."""
370
371
@property
372
def Minimizable(self) -> bool:
373
"""Whether the window can be minimized."""
374
375
class WindowVisualState:
376
"""Constants for window visual states."""
377
Normal: int = 0
378
Maximized: int = 1
379
Minimized: int = 2
380
```
381
382
### Text Pattern
383
384
The Text pattern provides access to text content and formatting information.
385
386
```python { .api }
387
class TextPattern:
388
"""Pattern for controls containing text content."""
389
390
def GetText(self, maxLength: int = -1) -> str:
391
"""
392
Get text content.
393
394
Args:
395
maxLength: Maximum length to retrieve (-1 for all)
396
397
Returns:
398
str: Text content
399
"""
400
401
def GetSelection(self) -> list:
402
"""
403
Get selected text ranges.
404
405
Returns:
406
list: List of selected text range objects
407
"""
408
409
def GetVisibleRanges(self) -> list:
410
"""
411
Get visible text ranges.
412
413
Returns:
414
list: List of visible text range objects
415
"""
416
```
417
418
## Usage Examples
419
420
### Using Invoke Pattern
421
422
```python
423
import uiautomation
424
425
# Get button and invoke it using pattern
426
button = uiautomation.ButtonControl(Name='Submit')
427
invoke_pattern = button.GetInvokePattern()
428
if invoke_pattern:
429
invoke_pattern.Invoke()
430
```
431
432
### Using Value Pattern
433
434
```python
435
# Set value in a text box
436
text_box = uiautomation.EditControl(Name='Username')
437
value_pattern = text_box.GetValuePattern()
438
if value_pattern and not value_pattern.IsReadOnly:
439
value_pattern.SetValue('myusername')
440
441
# Get current value
442
current_value = value_pattern.GetValue()
443
print(f"Current value: {current_value}")
444
```
445
446
### Using Selection Patterns
447
448
```python
449
# Work with a list box
450
list_box = uiautomation.ListControl(Name='Items')
451
selection_pattern = list_box.GetSelectionPattern()
452
453
# Get current selection
454
selected_items = selection_pattern.GetSelection()
455
for item in selected_items:
456
print(f"Selected: {item.Name}")
457
458
# Select an item
459
list_item = list_box.ListItemControl(Name='Item 3')
460
selection_item_pattern = list_item.GetSelectionItemPattern()
461
if selection_item_pattern:
462
selection_item_pattern.Select()
463
```
464
465
### Using Toggle Pattern
466
467
```python
468
# Toggle a checkbox
469
checkbox = uiautomation.CheckBoxControl(Name='Enable notifications')
470
toggle_pattern = checkbox.GetTogglePattern()
471
if toggle_pattern:
472
current_state = toggle_pattern.ToggleState
473
if current_state == uiautomation.ToggleState.Off:
474
toggle_pattern.Toggle() # Turn on
475
```
476
477
### Using Range Value Pattern
478
479
```python
480
# Set slider value
481
slider = uiautomation.SliderControl(Name='Volume')
482
range_pattern = slider.GetRangeValuePattern()
483
if range_pattern and not range_pattern.IsReadOnly:
484
# Set to 75% of the range
485
range_size = range_pattern.Maximum - range_pattern.Minimum
486
target_value = range_pattern.Minimum + (range_size * 0.75)
487
range_pattern.SetValue(target_value)
488
```
489
490
### Using Scroll Pattern
491
492
```python
493
# Scroll in a scrollable area
494
text_area = uiautomation.EditControl(Name='Content')
495
scroll_pattern = text_area.GetScrollPattern()
496
if scroll_pattern and scroll_pattern.VerticallyScrollable:
497
# Scroll to bottom
498
scroll_pattern.SetScrollPercent(-1, 100) # -1 means no change for horizontal
499
```
500
501
### Using Expand Collapse Pattern
502
503
```python
504
# Expand a tree node
505
tree = uiautomation.TreeControl(Name='Directory')
506
folder_node = tree.TreeItemControl(Name='Documents')
507
expand_pattern = folder_node.GetExpandCollapsePattern()
508
if expand_pattern:
509
if expand_pattern.ExpandCollapseState == uiautomation.ExpandCollapseState.Collapsed:
510
expand_pattern.Expand()
511
```
512
513
### Using Grid Pattern
514
515
```python
516
# Access grid data
517
data_grid = uiautomation.DataGridControl(Name='Results')
518
grid_pattern = data_grid.GetGridPattern()
519
if grid_pattern:
520
# Get cell at row 2, column 1
521
cell = grid_pattern.GetItem(2, 1)
522
if cell:
523
print(f"Cell value: {cell.Name}")
524
525
print(f"Grid size: {grid_pattern.RowCount} x {grid_pattern.ColumnCount}")
526
```
527
528
### Using Window Pattern
529
530
```python
531
# Manage window state
532
window = uiautomation.WindowControl(Name='My Application')
533
window_pattern = window.GetWindowPattern()
534
if window_pattern:
535
# Maximize the window
536
window_pattern.SetWindowVisualState(uiautomation.WindowVisualState.Maximized)
537
538
# Wait for window to be ready
539
ready = window_pattern.WaitForInputIdle(5000) # 5 second timeout
540
if ready:
541
print("Window is ready for input")
542
```
543
544
### Pattern Availability Checking
545
546
```python
547
def safe_invoke_button(button_name):
548
"""Safely invoke a button using pattern if available."""
549
button = uiautomation.ButtonControl(Name=button_name)
550
if not button.Exists():
551
print(f"Button '{button_name}' not found")
552
return False
553
554
# Try using invoke pattern first
555
invoke_pattern = button.GetInvokePattern()
556
if invoke_pattern:
557
invoke_pattern.Invoke()
558
return True
559
560
# Fall back to regular click
561
button.Click()
562
return True
563
```