# WinTitle 参数 & 上次找到的窗口

各种命令, 函数和控制流语句都含有 WinTitle 参数用来标识要操作的窗口. 此参数可以为窗口的标题或部分标题和或此页面描述的其他条件.

快速参考

标题 | 匹配行为
A | 活动窗口
ahk_class | 窗口类
ahk_id | 唯一 ID/HWND
ahk_pid | 进程 ID
ahk_exe | 进程名称/路径
ahk_group | 窗口组
| 多重条件
(都为空) | 上次找到的窗口

## 匹配行为

SetTitleMatchMode 控制参数中的部分标题或完整标题与每个窗口标题的比较方式. 根据这个设置, WinTitle 可以为准确的标题或包含前面部分或标题任意位置的子字符串或正则模式. 这个设置还控制 ahk_class 和 ahk_exe 条件是否解释为正则模式.

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

只有在 DetectHiddenWindows 设置打开时, 才会检测隐藏窗口, 不过 WinShow 总是检测隐藏窗口.

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

## A(活动窗口)

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

以下示例检索并报告活动窗口的唯一 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 来识别它. 窗口的 ID 通常使用 WinExist() 或 WinGet 来获取. 控件的 ID 通常使用 ControlGet Hwnd, MouseGetPos 或 DllCall() 来获取. 此外, ahk_id 条件甚至可以操作于隐藏控件; 即, DetectHiddenWindows 的设置不影响控件.

下面的例子通过存储在 VarContainingID 中的唯一 ID 来激活窗口:

    WinActivate, ahk_id %VarContainingID%

### ahk_pid(进程 ID)

在 WinTitle 中使用 `ahk_pid PID` 来识别属于特定进程的窗口. 进程标识符(PID) 通常由 WinGet, Run 或 Process 检索. 窗口的进程 ID 可以通过 Window Spy 来显示.

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

    WinActivate, ahk_pid %VarContainingPID%

### ahk_exe(进程名称/路径) [v1.1.01+]

在 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, WinClose 和 WinKill 将对组中的 所有 窗口进行操作. 相比之下, 其他窗口命令, 函数或控制流语句(如 WinActivate, WinExist() 和 IfWinExist) 仅对组中最顶层的窗口进行操作.

下面的例子可以激活任何符合窗口组定义标准的窗口:

    ; 定义组: 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.

## 上次找到的窗口

这是由 IfWinExist, IfWinNotExist, WinExist(), IfWinActive, IfWinNotActive, WinActive(), WinWaitActive, WinWaitNotActive 或 WinWait 最近找到的窗口. 它可以使脚本更容易创建和维护, 因为目标窗口的 WinTitle 和 WinText 不需要在每个窗口命令, 函数或控制流语句中重复. 同时, 脚本会执行的更好, 因为在首次找到目标窗口后不需要再次搜索目标窗口.

除了 WinWait, WinActivateBottom, GroupAdd, WinGet Count 和 WinGet List 之外, 所有的窗口命令, 函数和控制流语句都可以使用上次找到的窗口. 要使用它, 只需省略所有四个窗口参数(WinTitle, WinText, ExcludeTitle 和 ExcludeText).

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

如果上次找到的窗口是隐藏的 Gui 窗口, 那么即使 DetectHiddenWindows 为 Off 时, 也可以使用它. 这通常与 Gui +LastFound 一起使用.

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

    Run Notepad
    WinWait Untitled - Notepad
    WinActivate ; 使用 WinWait 找到的窗口.

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

    if WinExist("Untitled - Notepad")
    {
        WinActivate ; 使用 WinExist 找到的窗口.
        WinMaximize ; 使用 WinExist 找到的窗口.
        Send, Some text.{Enter}
        return
    }

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

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

dftg