ControlSend / ControlSendText

发送模拟键盘输入或文本到窗口或控件.

ControlSend Keys , ControlID, WinTitle, WinText, ExcludeTitle, ExcludeText
ControlSendText Keys , ControlID, WinTitle, WinText, ExcludeTitle, ExcludeText

参数

Keys

类型: 字符串

要发送的按键的序列(有关详情, 请参阅 Send 函数). 发送字符的速率由 SetKeyDelay 决定.

Send 函数不同, ControlSend 不能发送鼠标点击. 请使用 ControlClick 来发送.

ControlID

类型: 字符串, 整数对象

如果省略此参数, 击键将直接发送到目标窗口, 而不是它的一个控件. 否则, 请指定控件的 ClassNN, 文本或 HWND, 或具有 Hwnd 属性的对象. 有关详情, 请参阅控件标识符.

WinTitle, WinText, ExcludeTitle, ExcludeText

类型: 字符串, 整数对象

如果这些都是空白或省略, 将使用上次找到的窗口. 否则, 为 WinTitle 指定窗口标题或其他条件, 来标识目标窗口, 和/或为 WinText 指定目标窗口的单个文本元素的子字符串(由包含的 Window Spy 实用程序显示).

ExcludeTitleExcludeText 可用于根据标题或文本排除一个或多个窗口. 它们的规范类似于 WinTitleWinText, 除了 ExcludeTitle 不识别除窗口标题之外的任何条件.

窗口标题和文本是区分大小写的. 默认情况下, 不检测隐藏窗口, 而检测隐藏文本元素, 除非使用 DetectHiddenWindowsDetectHiddenText 进行更改; 当使用纯 HWND 时, 都会检测隐藏窗口. 默认情况下, 窗口标题的任意位置包含 WinTitleExcludeTitle 就能形成匹配, 除非使用 SetTitleMatchMode 进行了更改.

错误处理

如果找不到窗口或控件, 则抛出 TargetError.

备注

此函数适用于非图形用户界面窗口中的控件, 即那些并非通过 Gui 函数创建的窗口. 这个函数最适用于常见的或预定义的 Microsoft 控件; 而某些应用程序则使用自定义或修改后的控件, 在这种情况下, 函数可能无法按预期工作. 对于 GUI 控件, 如果存在相应的对应项, 通常通过其 GuiControl 对象来操作它们会更加方便.

不像 Send, ControlSend 忽略 SendMode. 它使用操作系统的 PostMessage 函数来发布键盘消息.

ControlSendText 类似于 ControlSend, 除了它发送 Keys 参数中的单个字符, 而不把 {Enter} 转换成 Enter, 把 ^c 转换成 Ctrl+C, 等等. 有关详情, 请参阅文本模式. 在 ControlSend 中, 使用 {Raw}{Text} 也是有效的.

如果省略 ControlID 参数, 该函数将尝试直接发送至目标窗口的最上面的控件(通常是正确的控件), 如果没有控件, 则发送至窗口本身. 如果一个窗口看起来根本没有任何控件, 或者只是为了方便且不必担心发送到哪个控件, 那么这个函数就很有用.

默认情况下, 修饰键(Ctrl, Alt, Shift 和 Win) 会像正常情况下一样由 SendEvent 函数发送. 这使得命令提示符和其他控制台窗口能够正确检测大写字母, 控制字符等. 它还可以在其他方面提高可靠性.

然而, 在某些情况下, 这些修饰符事件可能会干扰活动窗口, 特别是当用户在 ControlSend 期间正在进行输入, 或者正在发送 Alt 键时(因为 Alt 会激活活动窗口的菜单栏). 可以通过显式发送修饰符按下和弹起事件来避免这种情况, 如本例所示:

ControlSend "{Alt down}f{Alt up}", "Edit1", "Untitled - Notepad"

上面的方法也允许在工作站被锁定(由登录提示保护) 时发送修饰键(Ctrl, Alt, Shift 和 Win).

当在命令提示符等控制台窗口中使用 ControlSend 时, 应避免使用 BlockInput. 这是因为它可能会阻止大写和修饰键(如 Ctrl) 的正常工作.

SetKeyDelay 的值决定了按键的发送速度. 如果目标窗口无法可靠地接收按键, 请尝试通过 SetKeyDelay 的第二个参数来增加按下的持续时间, 如下面的例子所示:

SetKeyDelay 10, 10
SetKeyDelay 0, 10
SetKeyDelay -1, 0

如果目标控件是一个编辑控件(或类似的控件), 下面的方法通常比 ControlSend 更可靠和更快:

ControlSend 通常不能操纵窗口的菜单栏. 要解决这个问题, 可以使用 MenuSelect. 如果由于菜单栏的性质而无法做到这一点, 你可以尝试按照 SendMessage 教程来发现对应于所需菜单项的消息.

SetKeyDelay, 转义序列(例如 `n) , 控件函数, Send, 自动化 Winamp

示例

打开记事本(最小化的) 并发送一些文本. 这个例子在 Windows 11 或更高版本系统可能会失败, 因为它需要经典版本的记事本.

Run "Notepad",, "Min", &PID  ; 最小化运行记事本.
WinWait "ahk_pid " PID  ; 等待记事本进程的出现.
; 将文本发送到不活动的记事本编辑控件.
; 省略了第三个参数, 因此使用最后一个找到的窗口.
ControlSend "This is a line of text in the notepad window.{Enter}", "Edit1"
ControlSendText "Notice that {Enter} is not sent as an Enter keystroke with ControlSendText.", "Edit1"

Msgbox "Press OK to activate the window to see the result."
WinActivate "ahk_pid " PID  ; 显示结果.

打开命令提示符并向它发送一些文本. 这个例子在 Windows 11 或更高版本系统可能会失败, 因为它需要经典版本的命令提示符.

SetTitleMatchMode 2
Run A_ComSpec,,, &PID  ; 打开命令提示符.
WinWait "ahk_pid " PID  ; 等待它的出现.
ControlSend "ipconfig{Enter}",, "cmd.exe"  ; 直接发送到命令提示符窗口.

创建一个带有编辑控件的 GUI, 并向它发送一些文本.

MyGui := Gui()
MyGui.Add("Edit", "r10 w500")
MyGui.Show()
ControlSend "This is a line of text in the edit control.{Enter}", "Edit1", MyGui
ControlSendText "Notice that {Enter} is not sent as an Enter keystroke with ControlSendText.", "Edit1", MyGui