# 查找与点击

> 完整的控件获取流程（导出控件树、批量查找、列表项、control\_browser）见 [控件获取](/doc-site/dev/winauto/controls.md)。

## 查找控件

> 完整的控件获取流程（导出控件树、批量查找、列表项、control\_browser）见 [控件获取](/doc-site/dev/winauto/controls.md)。

在目标窗口的 UIA 控件树中定位元素：

```python
ctrl = auto.find(
    ctrl_type='ButtonControl',   # UIA 控件类型，如 EditControl / ListControl
    name='发送',                  # Name 属性（精确匹配）
    aid='chat_input',            # AutomationId
    cls='ChatInputBox',          # ClassName
    depth=10,                    # 搜索深度
)
```

常用 `ctrl_type`：`Control`、`ButtonControl`、`EditControl`、`ListControl`、`TextControl`、`MenuItemControl` 等（与 UIA 类型名一致）。

## 点击

```python
# 按属性查找并点击
auto.click(name='确定')
auto.click(ctrl_type='ButtonControl', aid='btn_ok')

# 传入已找到的控件
auto.click(ctrl)

# 坐标点击（屏幕坐标）
auto.click_xy(100, 200)
auto.click(x=100, y=200)

# 消息/卡片气泡常用落点（左缘 +100px，纵向居中）
# ctrl 必须来自 Message 对象（GetAllMessage / GetNextNewMessage），勿在窗口全局 find
auto.click_bubble(msg.control)

# 右键 / 双击（ctrl 来自 find 固定 UI，或 msg.control）
auto.right_click(ctrl)
auto.right_click_xy(500, 300, mode='mouse')
auto.right_click_message(msg, mode='uia')

# 点击位置偏移（控件内）
auto.click(name='发送', position='center')   # center / top / bottom / left / right
auto.click(name='发送', margin_left=5, margin_top=3)

# 单次覆盖模式（示例默认 UIA）
auto.click(name='确定', mode='uia')    # UIA Invoke（通用）
auto.click(name='确定', mode='mouse')  # 物理点击（通用）
auto.click(name='确定', mode='post')   # 后台 Post（仅部分原生控件）
auto.right_click(name='复制', mode='uia')
```

### Studio「点击操作」

操作面板 **功能 → 点击操作**：

1. 选 **点击模式**（UIA / 物理 / Post 等）
2. **选项**里选 **○ 左键单击** 或 **○ 右键单击**（可另勾「双击」，仅左键生效）
3. 设落点位置与边距 L/T/R/B
4. **▶ 执行点击** / **写入编辑框**（控件）；或 **▶ 坐标点击** / **写入 · 坐标**

等价生成代码示例：

```python
# 左键
auto.click(ctrl=target, mode='mouse', position='center')
# 右键
auto.right_click(ctrl=target, mode='mouse', position='center')
# 坐标右键
auto.right_click_xy(click_x, click_y, mode='mouse')
```

***

## API 参考

### 控件查找

### ✨find

在 `self.hwnd` 子树中按 UIA 属性查找**第一个**匹配控件。

```
editor = auto.find(ctrl_type='EditControl', aid='chat_input_field', depth=15)
note_body = auto.find(ctrl_type='DocumentControl', aid='RootWebArea', depth=9)
```

**参数**：

| 参数名        | 类型  | 默认值 | 描述                                                         |
| ---------- | --- | --- | ---------------------------------------------------------- |
| ctrl\_type | str | ''  | UIA 类型名，如 `'EditControl'`、`'DocumentControl'`；空则 `Control` |
| name       | str | ''  | `Name` 属性（精确匹配）                                            |
| aid        | str | ''  | `AutomationId`                                             |
| cls        | str | ''  | `ClassName`                                                |
| depth      | int | 10  | 最大搜索深度                                                     |

**返回值**：

- 类型：`Control | None`
- 描述：UIA 控件对象，未找到为 `None`

### ✨wait\_ctrl

参数同 `find`，轮询直到控件出现或超时。

```
ctrl = auto.wait_ctrl(ctrl_type='EditControl', aid='chat_input', timeout=5.0)
```

**参数**：

| 参数名        | 类型    | 默认值 | 描述       |
| ---------- | ----- | --- | -------- |
| ctrl\_type | str   | ''  | 同 `find` |
| name       | str   | ''  | 同 `find` |
| aid        | str   | ''  | 同 `find` |
| cls        | str   | ''  | 同 `find` |
| depth      | int   | 10  | 同 `find` |
| timeout    | float | 5.0 | 轮询超时（秒）  |
| interval   | float | 0.2 | 轮询间隔（秒）  |

**返回值**：

- 类型：`Control | None`

***

### 点击

### ✨click

按属性查找控件或传入已找到的控件后点击。

```
auto.click(ctrl=editor, mode='uia')
auto.click(name='发送', mode='uia', position='center', margin_left=5)
```

**参数**：

| 参数名            | 类型      | 默认值      | 描述                                                   |
| -------------- | ------- | -------- | ---------------------------------------------------- |
| ctrl           | Control | None     | 已找到的 UIA 控件；与属性查找二选一                                 |
| ctrl\_type     | str     | ''       | UIA 类型名                                              |
| name           | str     | ''       | `Name` 属性                                            |
| aid            | str     | ''       | `AutomationId`                                       |
| cls            | str     | ''       | `ClassName`                                          |
| depth          | int     | 10       | 搜索深度                                                 |
| x              | int     | 0        | 屏幕坐标 X；有 `ctrl` 时可忽略                                 |
| y              | int     | 0        | 屏幕坐标 Y                                               |
| mode           | str     | None     | 覆盖实例默认模式                                             |
| position       | str     | 'center' | 控件内落点：`center` / `top` / `bottom` / `left` / `right` |
| margin\_left   | int     | 0        | 相对落点的左偏移（像素）                                         |
| margin\_top    | int     | 0        | 相对落点的上偏移（像素）                                         |
| margin\_right  | int     | 0        | 相对落点的右偏移（像素）                                         |
| margin\_bottom | int     | 0        | 相对落点的下偏移（像素）                                         |

**返回值**：

- 类型：`WinAuto`

**说明**：

- `uia`：必须有 `ctrl`，走 UIA Invoke/Click
- `post`：PostMessage 左键到屏幕坐标
- `mouse`：物理点击

### ✨click\_xy

屏幕坐标左键点击。

```
auto.click_xy(800, 600, mode='mouse')
```

**参数**：

| 参数名  | 类型  | 默认值  | 描述     |
| ---- | --- | ---- | ------ |
| x    | int | 无    | 屏幕坐标 X |
| y    | int | 无    | 屏幕坐标 Y |
| mode | str | None | 操作模式   |

**返回值**：

- 类型：`WinAuto`

### ✨click\_bubble

消息/卡片气泡常用落点（左缘 + 偏移，纵向居中）。**`ctrl` 须为消息列表返回的 `msg.control`**，不要在主窗口 `find(name='[笔记]')`。

```
# msg 来自 im.GetAllMessage() 或 GetNextNewMessage 的 callback
auto.click_bubble(msg.control)
auto.click_bubble(msg.control, left_offset=100)
```

**参数**：

| 参数名          | 类型      | 默认值  | 描述            |
| ------------ | ------- | ---- | ------------- |
| ctrl         | Control | None | 气泡 UIA 控件     |
| left\_offset | int     | 100  | 相对左缘的水平偏移（像素） |
| mode         | str     | None | 操作模式          |

**返回值**：

- 类型：`WinAuto`

### ✨right\_click

右键点击控件（参数与落点规则同 [`click`](#click)）。

```python
# 按属性右键（固定 UI，如菜单项）
auto.right_click(name='另存为', mode='uia')

# 已找到的控件
auto.right_click(ctrl=item, mode='uia', position='center')

# 消息气泡右键：须用 Message API 的 msg.control，不要全局 find 名称
auto.right_click(msg.control, mode='uia')

# 带边距（例如避开左侧头像）
auto.right_click(
    ctrl=msg.control, mode='mouse',
    position='left_top', margin_left=100, margin_top=35,
)
```

**参数**：与 `click` 相同（`ctrl` / `ctrl_type` / `name` / `aid` / `cls` / `depth` / `mode` / `position` / `margin_*`）。\
无纯坐标参数时请用 `right_click_xy`。

**模式说明**：

| mode            | 行为                |
| --------------- | ----------------- |
| `uia`           | 必须有 `ctrl`，UIA 右键 |
| `post` / `send` | 按落点坐标发右键消息        |
| `mouse`         | 物理鼠标右键            |
| `auto`          | 尽量 UIA，失败再降级      |

**返回值**：`WinAuto`

### ✨right\_click\_xy

屏幕坐标右键单击。**不支持** `mode='uia'`（无控件，请用 `right_click(ctrl=...)`）。

```python
auto.right_click_xy(500, 300, mode='mouse')
auto.right_click_xy(cx, cy, mode='post')
```

**参数**：

| 参数名  | 类型  | 默认值  | 描述                                           |
| ---- | --- | ---- | -------------------------------------------- |
| x    | int | 必填   | 屏幕 X                                         |
| y    | int | 必填   | 屏幕 Y                                         |
| mode | str | None | `mouse` / `post` / `send` / `auto`（勿用 `uia`） |

**返回值**：`WinAuto`

### ✨right\_click\_message / right\_click\_msg

对 **消息对象** 右键（内部用 `msg.control` + 落点）。适合聊天列表里弹出「复制 / 转发 / 删除」等菜单。

```python
# 推荐
auto.right_click_message(msg, mode='uia')
auto.right_click_message(
    msg, mode='post',
    position='left_top', margin_left=100, margin_top=35,
)

# 别名
auto.right_click_msg(msg, mode='uia')
```

**参数**：

| 参数名                                 | 类型      | 默认值        | 描述                                       |
| ----------------------------------- | ------- | ---------- | ---------------------------------------- |
| msg                                 | Message | 必填         | `GetAllMessage` / `GetNewMessage` 等返回的消息 |
| mode                                | str     | None       | 同 `right_click`                          |
| position                            | str     | `'center'` | 落点                                       |
| margin\_left / top / right / bottom | int     | 0          | 边距                                       |
| prefer\_native                      | bool    | False      | 是否优先原生路径                                 |
| move                                | bool    | False      | 是否移动鼠标（视实现）                              |

**返回值**：`WinAuto`

> 找图后右键：`WinAuto.click_pic(..., right=True)`，或 `findpic` 后 `auto.right_click_xy(*hit.center, mode='mouse')`。见 [找图找色采样](/doc-site/dev/winauto/vision.md)。

### ✨double\_click / double\_click\_xy

双击。参数同 `click` / `click_xy`。

```python
auto.double_click(aid='item_0', mode='uia')
auto.double_click_xy(500, 300, mode='mouse')
```

**返回值**：

- 类型：`WinAuto`

***

[上一页构造与绑定](/doc-site/dev/winauto/bind.md)[下一页输入与键盘](/doc-site/dev/winauto/input.md)
