WinTitle 参数 & 最近找到的窗口

许多内置函数都有 WinTitle 参数, 用于识别要操作的窗口. 此参数可以是窗口的标题或部分标题, 和/或本页上描述的任何其他条件.

快速参考:
标题匹配行为
整数HWND
对象具有 HWND 的对象
A活动窗口
ahk_class窗口类
ahk_id唯一 ID/HWND
ahk_pid进程 ID
ahk_exe进程名称/路径
ahk_group窗口组
 多重条件
(空)上次找到的窗口

匹配行为

SetTitleMatchMode 控制如何将部分或完整标题与每个窗口的标题进行比较. 根据这个设置, WinTitle 可以是完全匹配的标题, 也可以包含前面部分, 标题中任何位置出现的子字符串或 RegEx 模式. 该设置还控制 ahk_classahk_exe 是否解释为 RegEx 模式.

窗口标题是区分大小写的, 除非在 RegEx 模式中使用 i) 修饰符.

仅当 DetectHiddenWindows 被的打开时, 才会检测隐藏窗口, 但 WinShow 除外, 它总是检测隐藏窗口.

如果多个窗口与 WinTitle 和其他任何条件匹配, 则使用最顶层的匹配窗口. 如果活动窗口匹配条件, 则它通常优先, 因为它一般在其他所有窗口的上面. 然而, 如果某个置顶的窗口也匹配条件(且活动窗口没有置顶), 则使用这个置顶窗口.

A(活动窗口)

使用字母 A 表示 WinTitle, 并省略其他三个窗口参数(WinText, ExcludeTitleExcludeText), 对活动窗口进行操作.

以下示例检索并报告活动窗口的唯一 ID(HWND):

MsgBox WinExist("A")

下面的例子创建了一个热键, 按下它可以使活动窗口最大化:

#Up::WinMaximize "A"  ; Win+Up

ahk_ 条件

指定一个或多个下面的 ahk_ 条件(可选, 除了窗口标题). 一个 ahk_ 条件总是由一个 _ahk 关键字和它的条件值组成, 两者之间用零或多个空格或制表符分隔. 例如, ahk_class Notepad 代表一个记事本窗口.

ahk_ 关键字和它的条件值不需要用空格或制表符来分隔. 这主要是在指定 ahk_ 条件值为表达式并与变量结合时有用. 例如, 可以指定 "ahk_pid" PID 而不是 "ahk_pid " PID. 然而, 在所有其他情况下, 建议使用至少一个空格或制表符作为分隔, 以提高可读性.

ahk_class(窗口类)

WinTitle 中使用 ahk_class ClassName 通过其窗口类来识别窗口.

窗口类是系统用来创建窗口的模板的属性集. 换句话说, 窗口类表示窗口的 类型. 窗口类可以通过 Window Spy 来显示或通过 WinGetClass 获取. 如果 RegEx 标题匹配模式被激活, ClassName 接受正则表达式.

下面的例子激活了一个控制台窗口(例如 cmd.exe):

WinActivate "ahk_class ConsoleWindowClass"

下面的示例与上面的相同, 但使用了正则表达式(注意必须事先打开 RegEx 标题匹配模式才行):

WinActivate "ahk_class i)^ConsoleWindowClass$"

ahk_id(唯一 ID / HWND)

WinTitle 中使用 ahk_id HWND, 通过其唯一的 ID 来识别窗口或控件.

每个窗口或控件都有一个唯一 ID, 也称为 HWND(即窗口句柄的缩写). 即使在窗口或控件的标题改变时也可用这个 ID 来识别它.

DetectHiddenWindows 会影响 ahk_id 条件是否检测隐藏的顶层窗口, 但隐藏的控件总是会被检测到. 如果传递了一个有效的整数对象, 则隐藏的窗口总是能被检测到.

ahk_id 条件也可以和给定窗口必须匹配的其他条件相结合. 例如, WinExist("ahk_id " ahwnd " ahk_class " aclass) 在窗口被 "检测到"(根据 DetectHiddenWindows) 且其窗口类别与 aclass 所包含的字符串相匹配时, 返回 ahwnd.

窗口的 ID 通常通过 WinExistWinGetID 来检索. 控件的 ID 通常通过 ControlGetHwnd, MouseGetPosDllCall 来检索. GuiGuiControl 对象具有 Hwnd 属性, 因此可以直接在 WinTitle 中使用.

下面的示例通过存储在 VarContainingID 中的唯一 ID 对窗口进行操作:

; 传递一个整数.
WinActivate Integer(VarContainingID)
WinShow A_ScriptHwnd
WinWaitNotActive WinExist("A")

; 传递一个具有 HWND 属性的 对象.
WinWaitClose myGuiObject

; 使用 ahk_id 前缀.
WinActivate "ahk_id " VarContainingID	WinActivate "ahk_id " VarContainingID

如果对象没有 HWND 属性或该属性的值不是整数, 则抛出 PropertyErrorTypeError.

ahk_pid(进程 ID)

WinTitle 中使用 ahk_pid PID 来识别属于特定进程的窗口. 进程标识符(PID) 通常由 WinGetPID, RunProcess 函数检索. 窗口的进程 ID 可以通过 Window Spy 来显示.

下面的例子是通过存储在 VarContainingPID 中的进程 ID 来激活一个窗口:

WinActivate "ahk_pid " VarContainingPID

ahk_exe(进程名称/路径)

WinTitle 中使用 ahk_exe ProcessNameOrPath 来识别属于任何具有给定名称或路径的进程的窗口.

ahk_pid 条件仅限于一个特定的进程, 而 ahk_exe 条件则考虑所有名称或完整路径与给定字符串相匹配的进程. 如果 RegEx 标题匹配模式处于活动状态, ProcessNameOrPath 接受正则表达式, 该表达式必须匹配进程的完整路径. 否则, 它接受不区分大小写的名称或完整路径; 例如, ahk_exe notepad.exe 涵盖了 ahk_exe C:\Windows\Notepad.exe, ahk_exe C:\Windows\System32\Notepad.exe 和其他变体. 窗口的进程名称可以通过 Window Spy 显示出来.

下面的例子是通过进程名称来激活一个记事本窗口:

WinActivate "ahk_exe notepad.exe"

下面的示例与上面的相同, 但使用了正则表达式(注意必须事先打开 RegEx 标题匹配模式才行):

WinActivate "ahk_exe i)\\notepad\.exe$"  ; 匹配完整路径的名称部分.

ahk_group(窗口组)

WinTitle 中使用 ahk_group GroupName 来识别与先前定义的窗口组

WinMinimize, WinMaximize, WinRestore, WinHide, WinShow, WinCloseWinKill 将对组中的 所有 窗口进行操作. 相比之下, 其他窗口函数(如 WinActivateWinExist) 仅对组中最顶层的窗口进行操作.

以下示例将激活任何符合窗口组定义标准的任何窗口:

; 定义组: Windows 资源管理器窗口
GroupAdd "Explorer", "ahk_class ExploreWClass" ; 在 Vista 及更高版本中不使用
GroupAdd "Explorer", "ahk_class CabinetWClass"

; 激活匹配上面标准的任意窗口
WinActivate "ahk_group Explorer"

多重条件

ahk_group 条件(它扩大了搜索范围) 相比, 在 WinTitle 参数中指定多个条件可以缩小搜索范围. 在下面的例子中, 脚本等待标题中包含 My File.txt 类名为 Notepad 的窗口出现:

WinWait "My File.txt ahk_class Notepad"
WinActivate  ; 激活它找到的窗口.

使用这种方法时, 应该首先列出标题的文本(如果希望使用), 后面跟着一个或多个附加条件. 超过一个条件时条件之间必须准确地用一个空格或 tab 分隔(其他任何空格或 tab 会被视为前面一个条件的文字部分).

ahk_id 条件 可以和其他条件组合来测试窗口标题, 类名或其他属性:

MouseGetPos ,, &id
if WinExist("ahk_class Notepad ahk_id " id)
    MsgBox "The mouse is over Notepad."

"上次找到的" 窗口

"上次找到的" 窗口是由最近的 WinExist, WinActive, WinWait[Not]ActiveWinWait 发现的窗口. 这样可以让脚本更容易创建和维护, 因为目标窗口的 WinTitleWinText 不需要在每个窗口函数中重复. 此外, 脚本会执行的更好, 因为在首次找到目标窗口后这些函数不需要再次搜索目标窗口.

"上次找到的" 窗口可以用于除 WinWait, WinActivateBottom, GroupAdd, WinGetCountWinGetList 以外的所有窗口函数. 要使用它, 只需简单地省略所有的四个窗口参数(WinTitle, WinText, ExcludeTitleExcludeText).

每个线程保留自己的 "上次找到的" 窗口值, 这意味着如果当前线程被其他线程中断, 当原始线程恢复时它仍会拥有它原来的 "上次找到的" 窗口值, 而不是中断线程的值.

如果上次找到的窗口是一个隐藏的 Gui 窗口, 那么即使 DetectHiddenWindows 被关闭, 也可以使用它. 这通常与 GUI 的 +LastFound 选项一起使用.

下面的例子打开记事本, 等待直到它存在并激活:

Run "Notepad"
WinWait "Untitled - Notepad"
; WinWait "无标题 - 记事本"
WinActivate  ; 使用由 WinWait 找到的窗口.

下面的例子是激活并最大化由上面的 WinExist 函数找到的记事本窗口:

if WinExist("Untitled - Notepad")
; if WinExist("无标题 - 记事本")
{
    WinActivate  ; 使用由 WinExist 找到的窗口.
    WinMaximize  ; 同上
    Send "Some text.{Enter}"
    return
}

如果计算器不存在, 下面的例子将返回, 否则计算器将被激活并移动到一个新的位置:

if not WinExist("Calculator")
    return
else
{
    WinActivate  ; 使用由 WinExist 找到的窗口.
    WinMove 40, 40  ; 同上.
    return
}
unixetc