<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1632085368384154" crossorigin="anonymous"></script><script src="https://autohotkey.top/gtag.js"></script></head> <body> <h1>Send / SendText / SendInput / SendPlay / SendEvent</h1> <p>发送模拟键击和鼠标点击到<a href="WinActivate.htm">活动</a>窗口.</p> <pre class="Syntax"><span class="func">Send</span> Keys <span class="func">SendText</span> Keys <span class="func">SendInput</span> Keys <span class="func">SendPlay</span> Keys <span class="func">SendEvent</span> Keys</pre> <h2 id="Parameters">参数</h2> <dl> <dt>Keys</dt> <dd> <p>类型: <a href="../Concepts.htm#strings">字符串</a></p> <p>要发送的按键序列.</p> <p>默认情况下(也就是说, 如果既不使用 SendText, 也不使用<a href="#Raw">原始模式</a>或<a href="#Text">文本模式</a>), 字符 <code>^+!#{}</code> 具有特殊含义. 字符 <code>^+!#</code> 分别代表修饰符键 <kbd>Ctrl</kbd>, <kbd>Shift</kbd>, <kbd>Alt</kbd> 和 <kbd>Win</kbd>. 他们仅影响紧跟着的下一个键. 若要发送修饰符本身对应的键, 将按键名称括在大括号中. 若要按下(按住) 或松开按键, 下面所示的单词 "down" 或 "up" 跟在按键名称的后面.</p> <style> #modifierkeys td:not(:last-child) { white-space: nowrap; text-align: center } </style> <table id="modifierkeys" class="info"> <tr> <th>符号</th> <th>按键</th> <th>按下</th> <th>松开</th> <th>示例</th> </tr> <tr> <td>^</td> <td>{Ctrl}</td> <td>{Ctrl down}</td> <td>{Ctrl up}</td> <td><code>Send "^{Home}"</code> 按下 <kbd>Ctrl</kbd>+<kbd>Home</kbd></td> </tr> <tr> <td>+</td> <td>{Shift}</td> <td>{Shift down}</td> <td>{Shift up}</td> <td><code>Send "+abC"</code> 发送文本 "AbC"<br> <code>Send "!+a"</code> 按下 <kbd>Alt</kbd>+<kbd>Shift</kbd>+<kbd>A</kbd></td> </tr> <tr> <td>!</td> <td>{Alt}</td> <td>{Alt down}</td> <td>{Alt up}</td> <td><code>Send "!a"</code> 按下 <kbd>Alt</kbd>+<kbd>A</kbd></td> </tr> <tr> <td>#</td> <td>{LWin}<br>{RWin}</td> <td>{LWin down}<br>{RWin down}</td> <td>{LWin up}<br>{RWin up}</td> <td><code>Send "#e"</code> 按住 <kbd>Win</kbd> 键时, 按下字母 <kbd>E</kbd></td> </tr> </table> <p class="note"><strong>注意:</strong> 由于大写字母是通过发送 <kbd>Shift</kbd> 产生的, 因此在某些程序中 <code>A</code> 和 <code>a</code> 会产生不同的效果. 例如, <code>!A</code> 按下 <kbd>Alt</kbd>+<kbd>Shift</kbd>+<kbd>A</kbd>, 而 <code>!a</code> 按下 <kbd>Alt</kbd>+<kbd>A</kbd>. 如果不确定, 请使用小写字母.</p> <p>字符 <code>{}</code> 用于括起<a href="#keynames">键名和其他选项</a>, 并发送特殊的原义字符. 例如, <code>{Tab}</code> 是 <kbd>Tab</kbd>, 而 <code>{!}</code> 是原义的感叹号.</p> <p>将一个纯 ASCII 字母(a-z 或 A-Z) 括在大括号中强制它作为相应的虚拟键码发送, 即使该字符在当前键盘布局上不存在. 换句话说, <code>Send a</code> 产生字母 "a", 而 <code>Send {a}</code> 根据键盘布局, 可能产生也可能不产生 "a". 有关详情, 请参阅<a href="#AZ">下面的注释</a>.</p> </dd> </dl> <h2 id="Send_variants">Send 的变体</h2> <p><strong>Send:</strong> 默认情况下, Send 等同于 SendInput; 但是可以通过 <a href="SendMode.htm">SendMode</a> 使其等同于 SendEvent 或 SendPlay.</p> <p><strong>SendText:</strong> 类似于 Send, 除了 <em>Keys</em> 中的所有字符都按原义解释. 有关详情, 请参阅<a href="#Text">文本模式</a>.</p> <p><strong id="SendInput">SendInput</strong> 和 <strong id="SendPlay">SendPlay:</strong> SendInput 和 SendPlay 使用与 SendEvent 相同的语法, 但通常更快更可靠. 此外, 它们在发送过程中缓冲任何物理键盘或鼠标活动, 这可以防止用户的击键与发送的击键穿插在一起. 通过 <a href="SendMode.htm">SendMode</a> 可以使 Send 等同于 SendInput 或 SendPlay. 有关每种模式的更多信息, 请参阅下面的 <a href="#SendInputDetail">SendInput</a> 和 <a href="#SendPlayDetail">SendPlay</a>.</p> <p id="SendEvent"><strong>SendEvent:</strong> SendEvent 使用 Windows keybd_event 函数发送键击(有关详情, 请在 Microsoft Docs 搜索). 发送击键的速率由 <a href="SetKeyDelay.htm">SetKeyDelay</a> 决定. 通过 <a href="SendMode.htm">SendMode</a> 可以使 Send 等同于 SendEvent 或 SendPlay.</p> <h2 id="Special_modes">特殊模式</h2> <p>以下模式影响 <em>Keys</em> 中字符的解释, 或键发送函数(例如 Send, SendInput, SendPlay, SendEvent 和 <a href="ControlSend.htm">ControlSend</a>) 的行为. 这些模式必须在 <em>Keys</em> 中指定 <code>{x}</code>, 其中 x 可以是 Raw, Text 或 Blind. 例如, <code>{Raw}</code>.</p> <h3 id="Raw">原始模式</h3> <p id="SendRaw">可以使用 <code>{Raw}</code> 启用原始模式, 这会导致所有后续字符, 包括特殊字符 <code>^+!#{}</code>, 都按原义进行解释, 如 <code>{Enter}</code> 不会转换为 <kbd>Enter</kbd>, <code>^c</code> 不会转换为 <kbd>Ctrl</kbd>+<kbd>C</kbd>, 等等. 例如, <code>Send "{Raw}{Tab}"</code> 发送 <code>{Tab}</code>, 而不是 <kbd>Tab</kbd>.</p> <p>原始模式不影响<a href="../misc/EscapeChar.htm">转义序列</a>和<a href="../Variables.htm#Expressions">表达式</a>的解释. 例如, <code>Send "{Raw}``100`%"</code> 发送字符 <code class="no-highlight">`100%</code>.</p> <h3 id="Text">文本模式</h3> <p id="SendText">可以使用 <code>{Text}</code>, SendText 或 <a href="ControlSend.htm">ControlSendText</a> 来启用文本模式, 与原始模式类似, 不同之处在于不会尝试将字符(<code>`r</code>, <code>`n</code>, <code>`t</code> 和 <code>`b</code> 除外) 转换为键码; 作为代替, <a href="#fallback">后备方法</a>适用于所有剩余的字符. 对于 SendEvent, SendInput 和 <a href="ControlSend.htm">ControlSend</a>, 这提高了可靠性, 因为字符对正确的修饰符状态的依赖性要小得多. 文本模式可以与盲从模式结合使用, 以避免释放任何修饰键: <code>Send "{Blind}{Text}your text"</code>. 但是, 一些应用程序会要求修饰键被释放.</p> <p><code>`n</code>, <code>`r</code> 和 <code>`r`n</code> 都被转换为一次单独的 <kbd>Enter</kbd>, 不像普通模式和原始模式, 转换 <code>`r`n</code> 为两次 <kbd>Enter</kbd>. <code>`t</code> 转换为 <kbd>Tab</kbd>, 而 <code>`b</code> 转换为 <kbd>Backspace</kbd>, 但所有其他字符都是不经转换直接发送的.</p> <p>与盲从模式类似, 文本模式忽略 <a href="SetStoreCapsLockMode.htm">SetStoreCapsLockMode</a>(也就是说, 不会改变 <kbd>CapsLock</kbd> 的状态), 并且不<a href="../Hotkeys.htm#win-l">等待 <kbd>Win</kbd> 被释放</a>. 这是因为文本模式通常不依赖于 <kbd>CapsLock</kbd> 的状态, 并且不能触发系统 <kbd>Win</kbd>+<kbd>L</kbd> 热键. 但是, 这仅适用于当 <em>Keys</em> 以 <code>{Text}</code> 或 <code>{Blind}{Text}</code> 开头时.</p> <h3 id="Blind">盲从模式</h3> <p id="blind">可以使用 <code>{Blind}</code> 启用盲从模式, 该模式通过禁用通常自动执行的许多操作来使脚本按预期运行, 从而赋予脚本更多控制权. 要启用盲从模式, <code>{Blind}</code> 必须是字符串中的第一个项目. 它具有以下效果:</p> <ul> <li>如果在发送开始时为按下的状态, 则盲从模式避免释放这些修饰符键(Alt, Ctrl, Shift 和 Win), 除非该修饰键被<a href="#blind-exclude">排除</a>了. 例如, 热键 <code>+s::Send "{Blind}abc"</code> 将发送 ABC 而不是 abc, 因为用户按住了 <kbd>Shift</kbd>.</li> <li>修饰键有不同的恢复方式, 以允许 Send 能关闭热键的修饰键, 即使用户在物理上仍然是按下的. 例如, 如果用户仍然物理按住 <kbd>Ctrl</kbd>, 则 <code>^space::Send "{Ctrl up}"</code> 自动推送 <kbd>Ctrl</kbd> 按下, 而 <code>^space::Send "{Blind}{Ctrl up}"</code> 允许 <kbd>Ctrl</kbd> 逻辑松开, 即使它物理上是按下的.</li> <li><a href="SetStoreCapsLockMode.htm">SetStoreCapsLockMode</a> 会被忽略; 也就是说, 不会改变 <kbd>CapsLock</kbd> 的状态.</li> <li><a href="lib/A_MenuMaskKey.htm">菜单掩饰</a>是禁用的. 也就是说, Send 忽略额外的击键, 这些键原本会被发送, 以防止: 1) 在按下 Win(LWin/RWin) 键时, 出现开始菜单; 2) 在按下 Alt 键时, 菜单栏的激活. 然而, 盲从模式不会阻止在钩子热键激活后由键盘钩子进行的掩饰.</li> <li>即使文本包含一个 <kbd>L</kbd>, Send 也不会等待 <kbd>Win</kbd> 被释放. 一般情况下会等待, 以防止 Send 触发系统 "锁定工作站" 的热键(<kbd>Win</kbd>+<kbd>L</kbd>). 有关详情, 请参阅<a href="../Hotkeys.htm#win-l">热键</a>.</li> </ul> <p id="blind-exclude">单词 "Blind" 后面可以用一个或多个修饰符号(<code>!#^+</code>) 以便在需要时自动释放这些修饰符. 例如, <code>*^a::Send "{Blind^}b"</code> 在按下 <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>A</kbd> 时, 将发送 <kbd>Shift</kbd>+<kbd>B</kbd> 而不是 <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>B</kbd>. <code>{Blind!#^+}</code> 可以在需要的时候释放所有的修饰符, 但是会启用盲从模式的其他效果.</p> <p>在<a href="../misc/Remap.htm">重映射按键</a>时, 盲从模式可以在其内部使用. 例如, 重映射 <code>a::b</code> 会发生这样的情况: 1) 输入 "a" 时会映射为 "b"; 2) 输入大写字母 "A" 时映射为大写字母 "B"; 并且 3) 按下 <kbd>Ctrl</kbd>+<kbd>A</kbd> 时映射为按下 <kbd>Ctrl</kbd>+<kbd>B</kbd>. 如果任何修饰符指定为源按键(包括 <kbd>Shift</kbd> 如果源按键是大写字母), 则如上所述, 这些修饰符被排除在外. 例如 <code>^a::b</code> 产生的是正常的 <kbd>B</kbd>, 而不是 <kbd>Ctrl</kbd>+<kbd>B</kbd>.</p> <p>SendText 或 <a href="ControlSend.htm">ControlSendText</a> 不支持 <code>{Blind}</code>; 请使用 <code>{Blind}{Text}</code> 代替.</p> <p><a href="#SendPlayDetail">SendPlay</a> 不完全支持盲从模式, 尤其是在处理修饰键时(Ctrl, Alt, Shift 和 Win).</p> <h2 id="keynames">Key 名称</h2> <p>下表中列出了可以发送的特殊按键(每个按键名称必须用大括号括起来):</p> <table class="info"> <tr> <th abbr="Key">按键名称</th> <th abbr="Descr">描述</th> </tr> <tr> <td>{F1} - {F24}</td> <td>功能键. 例如: {F12} 表示 <kbd>F12</kbd>.</td> </tr> <tr> <td>{!}</td> <td>!</td> </tr> <tr> <td>{#}</td> <td>#</td> </tr> <tr> <td>{+}</td> <td>+</td> </tr> <tr> <td>{^}</td> <td>^</td> </tr> <tr> <td>{{}</td> <td>{</td> </tr> <tr> <td>{}}</td> <td>}</td> </tr> <tr> <td>{Enter}</td> <td>主键盘上的 <kbd>Enter</kbd></td> </tr> <tr> <td>{Escape} 或 {Esc}</td> <td><kbd>Esc</kbd></td> </tr> <tr> <td>{Space}</td> <td><kbd>Space</kbd>(这只适用于出现在要发送的字符串的开头或结尾的空格 -- 而在中间的空格是原义的)</td> </tr> <tr> <td>{Tab}</td> <td><kbd>Tab</kbd></td> </tr> <tr> <td>{Backspace} 或 {BS}</td> <td><kbd>Backspace</kbd></td> </tr> <tr> <td>{Delete} 或 {Del}</td> <td><kbd>Del</kbd></td> </tr> <tr> <td>{Insert} 或 {Ins}</td> <td><kbd>Ins</kbd></td> </tr> <tr> <td>{Up}</td> <td><kbd>&uarr;</kbd>(主键盘上的向上键)</td> </tr> <tr> <td>{Down}</td> <td><kbd>&darr;</kbd>(主键盘上的向下键)</td> </tr> <tr> <td>{Left}</td> <td><kbd>&larr;</kbd>(主键盘上的向左键)</td> </tr> <tr> <td>{Right}</td> <td><kbd>&rarr;</kbd>(主键盘上的向右键)</td> </tr> <tr> <td>{Home}</td> <td><kbd>Home</kbd>(主键盘)</td> </tr> <tr> <td>{End}</td> <td><kbd>End</kbd>(主键盘)</td> </tr> <tr> <td>{PgUp}</td> <td><kbd>PgUp</kbd>(主键盘)</td> </tr> <tr class="sep_below"> <td>{PgDn}</td> <td><kbd>PgDn</kbd>(主键盘)</td> </tr> <tr> <td>{CapsLock}</td> <td><kbd>CapsLock</kbd>(使用 <a href="SetNumScrollCapsLockState.htm">SetCapsLockState</a> 更可靠). 发送 {CapsLock} 之前可能要求 <code><a href="SetStoreCapsLockMode.htm">SetStoreCapsLockMode</a> False</code>.</td> </tr> <tr> <td>{ScrollLock}</td> <td><kbd>ScrollLock</kbd>(另请参阅: <a href="SetNumScrollCapsLockState.htm">SetScrollLockState</a>)</td> </tr> <tr class="sep_below"> <td>{NumLock}</td> <td><kbd>NumLock</kbd>(另请参阅: <a href="SetNumScrollCapsLockState.htm">SetNumLockState</a>)</td> </tr> <tr> <td>{Control} 或 {Ctrl}</td> <td><kbd>Ctrl</kbd>(技术信息: 发送中性键的虚拟键码而不是左边键的扫描码)</td> </tr> <tr> <td>{LControl} 或 {LCtrl}</td> <td>左 <kbd>Ctrl</kbd>(技术信息: 发送左边键的虚拟键码而不是中性键)</td> </tr> <tr> <td>{RControl} 或 {RCtrl}</td> <td>右 <kbd>Ctrl</kbd></td> </tr> <tr class="sep_below"> <td>{Control down} 或 {Ctrl down}</td> <td>按住 <kbd>Ctrl</kbd> 键直到发送 {Ctrl up}. 要按住左边或右边的键, 请使用 LCtrl 或 RCtrl 替换 Ctrl.</td> </tr> <tr> <td>{Alt}</td> <td><kbd>Alt</kbd>(技术信息: 发送中性键的虚拟键码而不是左边键的扫描码)</td> </tr> <tr> <td>{LAlt}</td> <td>左 <kbd>Alt</kbd>(技术信息: 发送左边键的虚拟键码而不是中性键)</td> </tr> <tr> <td>{RAlt}</td> <td>右 <kbd>Alt</kbd>(或 <kbd>AltGr</kbd>, 取决于键盘布局)</td> </tr> <tr class="sep_below"> <td>{Alt down}</td> <td>按住 <kbd>Alt</kbd> 直到发送 {Alt up}. 要按住左边或右边的键, 请使用 LAlt 或 RAlt 替换 Alt.</td> </tr> <tr> <td>{Shift}</td> <td><kbd>Shift</kbd>(技术信息: 发送中性键的虚拟键码而不是左边键的扫描码)</td> </tr> <tr> <td>{LShift}</td> <td>左 <kbd>Shift</kbd>(技术信息: 发送左边键的虚拟键码而不是中性键)</td> </tr> <tr> <td>{RShift}</td> <td>右 <kbd>Shift</kbd></td> </tr> <tr class="sep_below"> <td>{Shift down}</td> <td>按住 <kbd>Shift</kbd> 直到发送 {Shift up}. 要按住左边或右边的键, 请使用 LShift 或 RShift 替换 Shift.</td> </tr> <tr> <td>{LWin}</td> <td>左 <kbd>Win</kbd></td> </tr> <tr> <td>{RWin}</td> <td>右 <kbd>Win</kbd></td> </tr> <tr> <td>{LWin down}</td> <td>按住左 <kbd>Win</kbd> 直到发送 {LWin up}</td> </tr> <tr class="sep_below"> <td>{RWin down}</td> <td>按住右 <kbd>Win</kbd> 直到发送 {RWin up}</td> </tr> <tr> <td>{AppsKey}</td> <td><kbd>Menu</kbd> (调用右键点击或上下文菜单)</td> </tr> <tr> <td>{Sleep}</td> <td><kbd>Sleep</kbd></td> </tr> <tr id="asc"> <td>{ASC nnnnn}</td> <td><p>发送 <kbd>Alt</kbd>+nnnnn 小键盘上的按键组合, 可以用来生成键盘上不存在的特殊字符. 要生成 ASCII 字符, 请指定一个介于 1 和 255 之间的数字. 要生成 ANSI 字符(在大多数语言中的标准), 请指定一个介于 128 和 255 之间的数字, 但需要在数字前加上一个前导零, 例如 {Asc 0133}..</p> <p>要生成 Unicode 字符, 请指定一个介于 256 和 65535 之间的数字(不带前导零). 但是, 有些应用程序不支持这种方法. 对于替代方法, 请参阅下面的部分.</p></td> </tr> <tr id="Unicode"> <td>{U+nnnn}</td> <td><p id="sendu">发送 Unicode 字符, 其中 <em>nnnn</em> 为字符的不包括 0x 前缀的十六进制值. 通常不需要这么做, 因为 Send 和 ControlSend 自动支持 Unicode 文本.</p> <p>会使用 <a href="https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-sendinput">SendInput()</a> 或 <a href="https://learn.microsoft.com/windows/win32/inputdev/wm-char">WM_CHAR</a> 来发送字符, 并且当前的发送模式没有效果. 以这种方式发送的字符通常不会触发快捷键或热键.</p></td> </tr> <tr id="vk" class="sep_below"> <td><p>{vkXX}<br> {scYYY}<br> {vkXXscYYY}</p></td> <td><p>发送虚拟键为 XX 和扫描码为 YYY 的按键. 例如: <code>Send "{vkFFsc159}"</code>. 如果省略 sc 或 vk 部分, 则发送最合适的值.</p> <p>XX 和 YYY 的值是十六进制的, 通常可以从<a href="../Program.htm#main-window">主窗口</a>的 View-&gt;<a href="KeyHistory.htm">Key history</a> 菜单项中确定. 另请参阅: <a href="../KeyList.htm#SpecialKeys">特殊按键</a></p> <p class="warning"><strong>警告:</strong> 以这种方式组合 vk 和 sc 仅在 Send 有效.</p></td> </tr> <tr> <td>{Numpad0} - {Numpad9}</td> <td>小键盘上的数字键(与 <kbd>NumLock</kbd> 打开时输入的一样). 例如: {Numpad5} 为数字 <kbd>5</kbd>.</td> </tr> <tr> <td>{NumpadDot}</td> <td><kbd>.</kbd>(小键盘上的点)(与 <kbd>NumLock</kbd> 打开时输入的一样).</td> </tr> <tr> <td>{NumpadEnter}</td> <td>小键盘上的 <kbd>Enter</kbd></td> </tr> <tr> <td>{NumpadMult}</td> <td><kbd>*</kbd>(小键盘上的乘号)</td> </tr> <tr> <td>{NumpadDiv}</td> <td><kbd>/</kbd>(小键盘上的除号)</td> </tr> <tr> <td>{NumpadAdd}</td> <td><kbd>+</kbd>(小键盘上的加号)</td> </tr> <tr class="sep_below"> <td>{NumpadSub}</td> <td><kbd>-</kbd>(小键盘上的减号)</td> </tr> <tr> <td>{NumpadDel}</td> <td>小键盘上的 <kbd>Del</kbd>(当 <kbd>NumLock</kbd> 为 OFF 时, 此键和以下的小键盘按键将被使用)</td> </tr> <tr> <td>{NumpadIns}</td> <td>小键盘上的 <kbd>Ins</kbd></td> </tr> <tr> <td>{NumpadClear}</td> <td>小键盘上的 Clear 键(在 <kbd>NumLock</kbd> 关闭时, 通常为 <kbd>5</kbd>).</td> </tr> <tr> <td>{NumpadUp}</td> <td>小键盘上的 <kbd>&uarr;</kbd>(向上)</td> </tr> <tr> <td>{NumpadDown}</td> <td>小键盘上的 <kbd>&darr;</kbd>(向下)</td> </tr> <tr> <td>{NumpadLeft}</td> <td>小键盘上的 <kbd>&larr;</kbd>(向左)</td> </tr> <tr> <td>{NumpadRight}</td> <td>小键盘上的 <kbd>&rarr;</kbd>(向右)</td> </tr> <tr> <td>{NumpadHome}</td> <td>小键盘上的 <kbd>Home</kbd></td> </tr> <tr> <td>{NumpadEnd}</td> <td>小键盘上的 <kbd>End</kbd></td> </tr> <tr> <td>{NumpadPgUp}</td> <td>小键盘上的 <kbd>PgUp</kbd></td> </tr> <tr class="sep_below"> <td>{NumpadPgDn}</td> <td>小键盘上的 <kbd>PgDn</kbd></td> </tr> <tr> <td>{Browser_Back}</td> <td>浏览器 "后退" 按钮</td> </tr> <tr> <td>{Browser_Forward}</td> <td>浏览器 "前进" 按钮</td> </tr> <tr> <td>{Browser_Refresh}</td> <td>浏览器 "刷新" 按钮</td> </tr> <tr> <td>{Browser_Stop}</td> <td>浏览器 "停止" 按钮</td> </tr> <tr> <td>{Browser_Search}</td> <td>浏览器 "搜索" 按钮</td> </tr> <tr> <td>{Browser_Favorites}</td> <td>浏览器 "收藏" 按钮</td> </tr> <tr> <td>{Browser_Home}</td> <td>启动浏览器并打开主页</td> </tr> <tr> <td>{Volume_Mute}</td> <td>主音量静音/取消静音. 通常相当于 <code><a href="SoundSetMute.htm">SoundSetMute</a> -1</code>.</td> </tr> <tr> <td>{Volume_Down}</td> <td>减小主音量. 通常相当于 <code><a href="SoundSetVolume.htm">SoundSetVolume</a> -5</code>.</td> </tr> <tr> <td>{Volume_Up}</td> <td>增加主音量. 通常相当于 <code><a href="SoundSetVolume.htm">SoundSetVolume</a> "+5"</code>.</td> </tr> <tr> <td>{Media_Next}</td> <td>在媒体播放器中播放下一曲目</td> </tr> <tr> <td>{Media_Prev}</td> <td>在媒体播放器中播放前一曲目</td> </tr> <tr> <td>{Media_Stop}</td> <td>停止媒体播放器</td> </tr> <tr> <td>{Media_Play_Pause}</td> <td>播放/暂停媒体播放器</td> </tr> <tr> <td>{Launch_Mail}</td> <td>启动电子邮件程序</td> </tr> <tr> <td>{Launch_Media}</td> <td>启动媒体播放器</td> </tr> <tr> <td>{Launch_App1}</td> <td>启动用户程序 1</td> </tr> <tr class="sep_below"> <td>{Launch_App2}</td> <td>启动用户程序 2</td> </tr> <tr> <td>{PrintScreen}</td> <td><kbd>PrtScr</kbd></td> </tr> <tr> <td>{CtrlBreak}</td> <td><kbd>Ctrl</kbd>+<kbd>Pause</kbd></td> </tr> <tr class="sep_below"> <td>{Pause}</td> <td><kbd>Pause</kbd></td> </tr> <tr id="Click"> <td>{Click [Options]}</td> <td>Send 鼠标点击使用的选项与 <a href="Click.htm">Click 函数</a>中的一样. 例如, <code>Send "{Click}"</code> 会在鼠标光标当前位置点击一次鼠标左键, 而 <code>Send "{Click 100 200}"</code> 则在坐标 100, 200 处点击(这里的坐标模式取决于 <a href="CoordMode.htm">CoordMode</a>). 要移动鼠标而不点击, 请在坐标后指定 0; 例如: <code>Send "{Click 100 200 0}"</code>. 鼠标点击之间的延迟由 <a href="SetMouseDelay.htm">SetMouseDelay</a> 决定(而不是 <a href="SetKeyDelay.htm">SetKeyDelay</a>).</td> </tr> <tr id="mouse-buttons"> <td>{WheelDown}, {WheelUp}, {WheelLeft}, {WheelRight}, {LButton}, {RButton}, {MButton}, {XButton1}, {XButton2}</td> <td> </p>在光标的当前位置发送一个鼠标按钮事件(要控制位置和其他选项, 请使用上面的 <a href="Click.htm">{Click}</a>). 鼠标点击之间的延迟由 <a href="SetMouseDelay.htm">SetMouseDelay</a> 决定.</p> <p>LButton 和 RButton 分别对应鼠标的主按钮和次按钮. 通常鼠标的主按钮(LButton) 在左边, 但是用户可以通过系统设置来交换按钮.</p> </td> </tr> <tr> <td>{Blind}</td> <td>启用<a href="#blind">盲从模式</a>, 通过禁用一些通常会自动完成的事情, 让脚本有了更多的控制权, 从而使事情一般都能正常工作. <code>{Blind}</code> 必须出现在字符串的开头.</td> </tr> <tr> <td>{Raw}</td> <td>启用<a href="#SendRaw">原始模式</a>, 这将导致以下字符按原义解释: <code>^+!#{}</code>. 虽然 <code>{Raw}</code> 不需要出现在字符串的开头, 但一旦指定, 它将在字符串的其余部分保持有效.</td> </tr> <tr> <td>{Text}</td> <td>启用<a href="#SendText">文本模式</a>, 它发送的是字符流而不是按键. 与原始模式一样, 文本模式会使以下字符按原义解释: <code>^+!#{}</code>. 虽然 <code>{Text}</code> 不需要出现在字符串的开头, 但一旦指定, 它将在字符串的其余部分保持有效.</td> </tr> </table> <h2 id="Repeating_or_Holding_Down_a_Key">重复或按住按键</h2> <p id="repeat"><strong>重复键击:</strong> 用大括号括起按键名称和重复次数. 例如:</p> <pre>Send "{DEL 4}" <em>; 按 4 次 Delete 键.</em> Send "{S 30}" <em>; 发送 30 次大写字母 S.</em> Send "+{TAB 4}" <em>; 按 4 次 Shift-Tab.</em></pre> <p id="Down"><strong>按住或释放按键:</strong> 用大括号括起按键名称和单词 <strong>Down</strong> 或 <strong>Up</strong>. 例如:</p> <pre>Send "{b down}{b up}" Send "{TAB down}{TAB up}" Send "{Up down}" <em>; 按下向上键.</em> Sleep 1000 <em>; 按住 1 秒.</em> Send "{Up up}" <em>; 释放向上键.</em></pre> <p>使用上面的方法按住一个按键后, 这个期间它不会像您实际按住这个按键一样自动重复(这是由于自动重复是一个驱动/硬件的特性). 不过, 可以使用 <a href="Loop.htm">Loop</a> 来模拟自动重复. 下面的例子中发送 20 次 tab 键击:</p> <pre>Loop 20 { Send "{Tab down}" <em>; 自动重复由连续的按下事件组成(没有弹起事件).</em> Sleep 30 <em>; 在两次键击之间的毫秒数(或使用 <a href="SetKeyDelay.htm">SetKeyDelay</a> 设置).</em> } Send "{Tab up}" <em>; 松开按键.</em></pre> <p>默认情况下, 如果一个修饰键在发送时被 "按下", 则 Send 不会自动释放该修饰键(Control, Shift, Alt 和 Win) . 例如, 如果用户物理按下 <kbd>Ctrl</kbd> 时, <code>Send "a"</code> 的行为类似于 <code>Send "<a href="#blind">{Blind}</a>{Ctrl up}a{Ctrl down}"</code>, 但 <code>Send "{Ctrl Down}"</code> 后面接着 <code>Send "a"</code> 将产生 <kbd>Ctrl</kbd>+<kbd>A</kbd>. <em>DownTemp</em> 和 <em>DownR</em> 可以用来覆盖这种行为. <em>DownTemp</em> 和 <em>DownR</em> 与 <em>Down</em> 具有同样的效果, 除了修饰键(Control, Shift, Alt 和 Win).</p> <p id="DownTemp"><strong>DownTemp</strong> 告诉后续的发送, 该键不是永久按下的, 只要有按键需要就可以释放. 例如, 在发送 <code>Send "{Control DownTemp}"</code> 之后, 再 <code>Send "a"</code> 将产生一个正常的 <kbd>A</kbd>, 而不是 <kbd>Ctrl</kbd>+<kbd>A</kbd>. 任何使用 Send 的方法都有可能永久地释放修饰键, 所以 <em>DownTemp</em> 并不是<a href="../misc/Remap.htm">重映射</a>修饰键的理想选择.</p> <p id="DownR"><strong>DownR</strong>(其中 "R" 表示<a href="../misc/Remap.htm">重映射</a>, 这是它的主要用途) 告诉后续的发送, 如果该键被自动释放, 则应在发送结束后再次按下. 例如, <code>Send "{Control DownR}"</code> 后面跟着 <code>Send "a"</code> 会产生一个正常的 <kbd>A</kbd>, 而不是 <kbd>Ctrl</kbd>+<kbd>A</kbd>, 但会让 <kbd>Ctrl</kbd> 处于被按下的状态, 以便用于键盘快捷键. 换句话说, <em>DownR</em> 有类似于物理按下按键的效果.</p> <p>如果某个字符与当前键盘布局上的虚拟键不一致, 则不能 "按下" 或 "释放". 例如, <code>Send "{μ up}"</code> 对大多数键盘布局没有效果, 而 <code>Send "{μ down}"</code> 等同于 <code>Send "μ"</code>.</p> <h2 id="Remarks">备注</h2> <p id="characters"><strong>字符 vs. 按键:</strong> 默认情况下, 先将字符转换为按键来发送字符. 如果这种转换是不可能的(即, 如果当前的键盘布局不包含产生该字符的键或键组合), 则通过以下回退方法之一来发送字符:</p> <ul id="fallback"> <li>SendEvent 和 SendInput 使用带有 a href="https://learn.microsoft.com/windows/win32/api/winuser/ns-winuser-keybdinput#keyeventf_unicode">KEYEVENTF_UNICODE 标志</a>的 <a href="https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-sendinput">SendInput()</a>.</li> <li>SendPlay 使用 <a href="#asc">Alt+nnnnn</a> 方法, 只有在目标应用程序支持的情况下才会产生 Unicode 字符.</li> <li>ControlSend 发布 <a href="https://learn.microsoft.com/windows/win32/inputdev/wm-char">WM_CHAR</a> 消息.</li> </ul> <p class="warning"><strong>注意:</strong> 使用上述方法发送字符通常不会触发键盘快捷键或热键.</p> <p id="AZ">对于 a-z 或 A-Z(纯 ASCII 字母) 范围内的字符, 每个当前键盘布局中不存在的字符可以作为字符或相应的虚拟键码(vk41-vk5A) 发送:</p> <ul> <li>如果只是发送字母(即没有修饰符或大括号), 或<a href="#Raw">原始</a>模式正生效, 则将其作为字符发送. 例如, <code>Send "{Raw}Regards"</code> 发送预期的文本, 即使按住 <kbd>R</kbd>(vk52) 产生其他一些字符(如 <kbd>к</kbd> 在俄语键盘). 在这种情况下, <code>{Raw}</code> 可以省略, 除非一个修饰键被前一个 Send 所实现.</li> <li>如果一个或多个修饰键已经通过 Send 函数生效, 或者如果该字母包裹在大括号中, 它将作为键码发送(如果是大写字母, 则用 <kbd>Shift</kbd> 修饰). 这使脚本可以更容易地激活标准键盘快捷键. 例如, <code>^c</code> 和 <code>{Ctrl down}c{Ctrl up}</code> 激活标准的 <kbd>Ctrl</kbd>+<kbd>C</kbd> 快捷键, 而 <code>{c}</code> 等同于 <code>{vk43}</code>.</li> </ul> <p>如果字母存在于当前的键盘布局中, 那么它总是以布局与该字母相关联的键码发送(除非使用了<a href="#SendText">文本模式</a>, 在这种情况下, 该字符将通过其他方式发送). 换句话说, 上面的部分只适用于非拉丁语系的布局, 如俄语.</p> <p id="mask"><strong>修饰键状态:</strong> 当 Send 需要改变 <kbd>Win</kbd> 或 <kbd>Alt</kbd> 修饰键的状态时(比如用户按住其中一个键), 它可能会注入额外的按键(默认为 <kbd>Ctrl</kbd>) 来阻止开始菜单或窗口菜单的出现. 有关详情, 请参阅 <a href="lib/A_MenuMaskKey.htm">A_MenuMaskKey</a>.</p> <p><strong>BlockInput 对比 SendInput/SendPlay:</strong> 尽管 <a href="BlockInput.htm">BlockInput</a> 函数可以用来防止用户物理输入的任何按键破坏模拟按键的流, 但通常最好使用 <a href="#SendInputDetail">SendInput</a> 或 <a href="#SendPlayDetail">SendPlay</a> 这样按键和鼠标点击就不会中断. 这是因为与 BlockInput 不同的是, SendInput/Play 不会在发送过程中丢弃用户输入的内容; 相反, 这样的按键会被缓冲并在之后发送.</p> <p>当发送大量的按键时, 可以使用<a href="../Scripts.htm#continuation">延续片段</a>来提高可读性和可维护性.</p> <p>由于操作系统不允许模拟 <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> 组合, 所以类似 <code>Send "^!{Delete}"</code> 这样的操作是没有效果的.</p> <p>当活动窗口以管理身份运行而当前脚本不是时, <b>Send 可能没有效果</b>. 这是由于一种叫做用户界面特权隔离的安全机制造成的.</p> <h2 id="SendInputDetail">SendInput</h2> <p>一般情况下, SendInput 是发送按键和鼠标点击的首选方法, 因为它的速度和可靠性都很高. 在大多数情况下, SendInput 几乎是瞬间完成的, 即使是发送长字符串时也是如此. 由于 SendInput 的速度如此之快, 它的可靠性也更高, 因为这样其他一些窗口更没有机会出乎意料地弹出并打断按键. 用户在 SendInput 过程中输入的任何东西都会被推迟到之后再进行, 从而进一步提高了可靠性.</p> <p>与其他发送模式不同, 操作系统限制 SendInput 每次只能发送大约 5000 个字符(此限制可能因操作系统版本和性能设置而有所不同). 超过此限制的字符和事件不会被发送.</p> <p class="note"><strong>注意:</strong> SendInput 会忽略 SetKeyDelay, 因为在这种发送模式中操作系统不支持延迟. 但是, 在后面描述的情况中, 当 SendInput 恢复到 <a href="#SendEvent">SendEvent</a> 时, 它会使用 <code><a href="SetKeyDelay.htm">SetKeyDelay</a> -1, 0</code>(但如果 SendEvent 的按键延迟为 <code>-1,-1</code> 时, 则使用 <code>-1,-1</code>). 当 SendInput 恢复为 <a href="#SendPlayDetail">SendPlay</a> 时, 它使用 SendPlay 的按键延迟.</p> <p id="SendInputUnavail">如果执行 SendInput 的脚本 <em>以外的</em> 脚本安装了<a href="InstallKeybdHook.htm">低级键盘钩子</a>, 则 SendInput 会自动恢复为 <a href="#SendEvent">SendEvent</a>(或当 <code><a href="SendMode.htm">SendMode</a> "InputThenPlay"</code> 生效时为 <a href="#SendPlayDetail">SendPlay</a>). 这是由于外部钩子的存在让 SendInput 失去了所有的优势, 使它不如 SendPlay 和 SendEvent 两者. 然而, 由于 SendInput 无法检测到除 AutoHotkey v1.0.43+ 以外的程序中的低级钩子, 所以在这些情况下它不会还原, 使得它的可靠性不如 SendPlay/Event.</p> <p>当 SendInput 使用像 <a href="#Click">{Click}</a> 这样的方法发送鼠标点击, 并且 <code><a href="CoordMode.htm">CoordMode</a> "Mouse", "Window"</code> 或 <code>CoordMode "Mouse", "Client"</code> 有效时(默认的), 则每次点击都会相对于发送开始时的那个活动窗口. 因此, 如果 SendInput 有意地激活另一个窗口(通过类似 alt-tab 的方法), 那么这个命令中后续点击的坐标将变成错误的, 因为它们仍然相对于原来的活动窗口而不是新的.</p> <h2 id="SendPlayDetail">SendPlay</h2> <p class="warning"><strong>警告:</strong> 如果启用了 UAC, 即使脚本以管理员身份运行, SendPlay 也可能没有效果. 有关详情, 请参阅 <a href="../FAQ.htm#uac">FAQ</a>.</p> <p>SendPlay 最大的优势在于它能在更多的游戏中 "回放" 按键和鼠标点击. 例如, 某款游戏只有在有 <a href="../Hotstrings.htm#SendMode">SendPlay 选项</a>的情况下才能接受<a href="../Hotstrings.htm#SendMode">热字串</a>.</p> <p>在这三种发送模式中, SendPlay 是最特别的, 因为它本身并不模拟按键和鼠标点击. 相反, 它创建了一系列的事件(消息), 直接流向活动窗口(类似于 <a href="ControlSend.htm">ControlSend</a>, 但级别较低). 因此, 不会触发热键或热字串.</p> <p>和 <a href="#SendInputDetail">SendInput</a> 一样, SendPlay 的按键与用户键入的按键互不干扰. 因此, 如果用户在 SendPlay 期间碰巧输入了一些东西, 这些键程会被推迟到之后.</p> <p>虽然 SendPlay 比 SendInput 要慢很多, 但它通常比传统的 <a href="#SendEvent">SendEvent</a> 模式要快(即使 <a href="SetKeyDelay.htm">KeyDelay</a> 为 -1 时, 也是如此).</p> <p>如果安装了<a href="InstallKeybdHook.htm">键盘钩子</a>, 则在 SendPlay 发送期间会自动屏蔽 <kbd>Win</kbd>(LWin 和 RWin). 这样避免了在发送期间当用户无意按了 <kbd>Win</kbd> 键时显示开始菜单. 与之相比, LWin 和 RWin 之外的其他按键不需要屏蔽, 因为操作系统会自动把它们延迟到 SendPlay 执行完后(通过缓冲).</p> <p>SendPlay 不使用 <a href="SetKeyDelay.htm">SetKeyDelay</a> 和 <a href="SetMouseDelay.htm">SetMouseDelay</a> 的标准设置. 相反, 它默认为无延迟, 可以按照下面的例子来改变:</p> <pre><a href="SetKeyDelay.htm">SetKeyDelay</a> 0, 10, <strong>"Play"</strong> <em>; 注意 0 和 -1 在 SendPlay 模式中是一样的.</em> <a href="SetMouseDelay.htm">SetMouseDelay</a> 10, <strong>"Play"</strong></pre> <p>SendPlay 无法打开或关闭 <kbd>CapsLock</kbd>, <kbd>NumLock</kbd> 或 <kbd>ScrollLock</kbd>. 同样, 它也无法改变 <a href="GetKeyState.htm">GetKeyState</a> 所看到的键的状态, 除非按键被发送到脚本自己的一个窗口. 即使如此, 任何对左/右修饰键(例如 RControl) 的改变也只能通过它们的中性对应键(例如 Control) 来检测. 此外, SendPlay 还有其他限制, 在 <a href="SendMode.htm#Play">SendMode 页面</a>上有描述.</p> <p>与 <a href="#SendInputDetail">SendInput</a> 和 <a href="#SendEvent">SendEvent</a> 不同, 用户可以通过按下 <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> 或 <kbd>Ctrl</kbd>+<kbd>Esc</kbd> 来中断 SendPlay. 当这种情况发生时, 剩余的按键不会被发送, 但是脚本会继续执行, 就像 SendPlay 已经正常完成一样.</p> <p>虽然 SendPlay 可以发送 LWin 和 RWin 事件, 但是它们会直接发送到活动窗口, 而不是执行它们的在操作系统中的原生功能. 要解决这个问题, 请使用 <a href="#SendEvent">SendEvent</a>. 例如, <code>SendEvent "#r"</code> 将显示开始菜单的运行对话框.</p> <h2 id="Related">相关</h2> <p><a href="SendMode.htm">SendMode</a>, <a href="SetKeyDelay.htm">SetKeyDelay</a>, <a href="SetStoreCapsLockMode.htm">SetStoreCapsLockMode</a>, <a href="../misc/EscapeChar.htm">转义序列(例 `n)</a>, <a href="ControlSend.htm">ControlSend</a>, <a href="BlockInput.htm">BlockInput</a>, <a href="../Hotstrings.htm">热字串</a>, <a href="WinActivate.htm">WinActivate</a></p> <h2 id="Examples">示例</h2> <div class="ex" id="ExBasic"> <p><a class="ex_number" href="#ExBasic"></a> 输入两行签名.</p> <pre>Send "Sincerely,{enter}John Smith"</pre> </div> <div class="ex" id="ExModifier"> <p><a class="ex_number" href="#ExModifier"></a> 选择 File-&gt;Save 菜单(Alt+F 后面跟着 S).</p> <pre>Send "!fs"</pre> </div> <div class="ex" id="ExBrace"> <p><a class="ex_number" href="#ExBrace"></a> 到文本的末尾然后发送四次 shift 和左方向键组合的键击.</p> <pre>Send "{End}+{Left 4}"</pre> </div> <div class="ex" id="ExSendInputRaw"> <p><a class="ex_number" href="#ExSendInputRaw"></a> 通过最快的方法发送一长串<a href="#Raw">原始字符</a>.</p> <pre><a href="#SendInputDetail">SendInput</a> "{Raw}A long series of raw characters sent via the fastest method."</pre> </div> <a href="https://dftg.net">dftg</a><!-- Cloudflare Pages Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "d5a9c4fcb9b6482fa53ce820d892f969"}'></script><!-- Cloudflare Pages Analytics --><script defer src="https://static.cloudflareinsights.com/beacon.min.js/vcd15cbe7772f49c399c6a5babf22c1241717689176015" integrity="sha512-ZpsOmlRQV6y907TI0dKBHq9Md29nnaEIPlkf84rnaERnq6zvWvPUqr2ft8M1aS28oN72PdrCzSjY4U6VaAw1EQ==" data-cf-beacon='{"rayId":"93a28daf2ad8ab95","version":"2025.4.0-1-g37f21b1","r":1,"serverTiming":{"name":{"cfExtPri":true,"cfL4":true,"cfSpeedBrain":true,"cfCacheStatus":true}},"token":"51750bb5dc4f40cc91a5ec55c63bbc01","b":1}' crossorigin="anonymous"></script> </body> </html>