| name | windows-ui-automation |
| description | Automate Windows GUI interactions using Python (pyautogui) + AI vision for applications with custom-drawn UI (like DaVinci Resolve). Use when asked to control a Windows application UI, automate mouse/keyboard actions, or find UI element coordinates. |
| author | sunchenzheng |
| version | 1.1 |
| tags | ["windows","automation","pyautogui","ui-automation","mouse","keyboard"] |
Windows UI Automation Skill
Automate Windows GUI interactions when standard Windows UI Automation (pywinauto) fails on custom-drawn applications.
When to Use
- User asks to control a Windows application UI programmatically
- Application has a custom-drawn UI (no standard Windows controls — pywinauto's
child_window() won't find elements)
- Need to find UI element coordinates to click/type
- Example tasks: automate DaVinci Resolve, Adobe Premiere, or any non-standard Windows app
Core Method: pyautogui + AI Vision
Step 1: Screenshot
import pyautogui
pyautogui.screenshot("screen.png")
pyautogui.screenshot(region=(x, y, width, height))
Step 2: AI Vision → Find Coordinates
image(
prompt="Find the exact pixel position of the 'Saturation' slider. Give coordinates relative to full screen (WxH).",
image="screen.png"
)
Step 3: Operate
pyautogui.click(x, y)
pyautogui.drag(dx, dy, duration=0.5)
pyautogui.type_keys("60")
pyautogui.moveTo(x, y, duration=0.3)
Architecture Decision Tree
Is the app standard Windows UI (buttons, menus)?
├── YES → Use pywinauto child_window() — reliable
└── NO → Use pyautogui + AI vision
├── Can you see the element on screen? → AI vision coordinates
├── No standard controls → pyautogui pixel scan
└── Fixed-position UI → Hardcode coordinates after first discovery
pyautogui Quick Reference
import pyautogui
pyautogui.FAILSAFE = False
pyautogui.PAUSE = 0.1
pyautogui.click(x, y, clicks=2, interval=0.2)
pyautogui.rightClick(x, y)
pyautogui.drag(startX, startY, offsetX, offsetY, duration=0.5)
pyautogui.moveTo(x, y, duration=0.3)
pyautogui.type_keys("{UP}")
pyautogui.type_keys("^a")
pyautogui.type_keys("%{F4}")
location = pyautogui.locateOnScreen("button.png", confidence=0.8)
if location:
center = pyautogui.center(location)
pyautogui.click(center)
Keyboard Modifiers (pywinauto notation)
| Key | pywinauto | pyautogui |
|---|
| Ctrl | ^ | ^ |
| Alt | % | % |
| Shift | + | + |
| Escape | {ESC} | {ESC} |
| Tab | {TAB} | {TAB} |
| Enter | {ENTER} | {ENTER} |
| Delete | {DELETE} | {DELETE} |
| Home | {HOME} | {HOME} |
| End | {END} | {END} |
| Up/Down arrows | {UP} / {DOWN} | {UP} / {DOWN} |
Finding Windows Handle (HWND)
import ctypes
user32 = ctypes.windll.user32
windows = []
def enum_callback(hwnd, lParam):
length = user32.GetWindowTextLengthW(hwnd)
if length > 0:
buff = ctypes.create_unicode_buffer(length + 1)
user32.GetWindowTextW(hwnd, buff, length + 1)
title = buff.value
if "TargetApp" in title:
windows.append((hwnd, title))
return True
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.c_void_p, ctypes.c_void_p)
user32.EnumWindows(EnumWindowsProc(enum_callback), 0)
if windows:
hwnd, title = windows[0]
user32.SetForegroundWindow(hwnd)
Focus and Stability
from pywinauto import Application
app = Application(backend='uia')
app.connect(handle=hwnd)
dlg = app.window(handle=hwnd)
dlg.set_focus()
time.sleep(0.3)
Emergency Stop Protocol
CRITICAL: When user says "停" (stop):
taskkill /F /IM python.exe
taskkill /F /IM node.exe
Do NOT finish the current loop. Stop immediately.
Known Limitations
- DR20 Fusion API: PowerWindow creation is blocked — must use UI automation instead
- Saturation sliders: Direct value input (Ctrl+A → type → Enter) is more reliable than drag
- Coordinate drift: When a window moves, all hardcoded coordinates become invalid
- Multi-monitor: Coordinates are absolute across all monitors
Scripts
| Script | Purpose |
|---|
mouse_control.ps1 | Native PowerShell mouse control (fallback) |
keyboard_control.ps1 | Native PowerShell keyboard control |
explore_ui.py | Scan screen for UI elements using pixel analysis |
Example: DaVinci Resolve 20 Workflow
hwnd = 1905922
user32.SetForegroundWindow(hwnd)
time.sleep(0.5)
app = Application(backend='uia').connect(handle=hwnd)
app.window(handle=hwnd).set_focus()
app.window(handle=hwnd).type_keys('%c')
time.sleep(0.5)
img = pyautogui.screenshot()
pyautogui.click(240, 874)
time.sleep(0.8)
curve_pts = []
for y in range(900, 1400, 5):
for x in range(1000, 2600, 3):
pixel = img.getpixel((x, y))
if pixel[0] > 200 and pixel[1] > 200 and pixel[2] > 200:
if max(pixel) - min(pixel) < 40:
curve_pts.append((x, y))
break
Installation
pip install pyautogui pywin32
No additional drivers required — uses Windows native user32.dll.