人工智障编程失败:AHK v2实现用快捷键在同程序不同窗口间切换

想用Windows+`键在同个程序的不同窗口间切换,试了AltBacktick,可惜无法自定义,只能用Alt+`,不满足我的需求

试了Deepseek、腾讯混元、VSCode里的Copilot
结果全都是战五渣,前俩没报错但按下根本没反应
Copilot倒是搞了个半成品,但只能在2个窗口间切换,第3个及更多个窗口就始终切换不到
跟人工智障交互了半天,始终没能搞出来一个成品……

我跟Copilot的对话:

帮我写一个AHK脚本,用AHK v2语言。实现功能:按下Windows+`键,实现同个程序的不同窗口间切换

AI写了个报错的
; filepath: untitled:Untitled-3

#`::
{
    ; 获取当前活动窗口的进程ID
    WinGet, currentPID, PID, A

    ; 获取所有窗口的列表
    WinGet, windowList, List

    ; 遍历所有窗口
    Loop, % windowList
    {
        ; 获取窗口的进程ID
        WinGet, windowPID, PID, % "ahk_id " windowList[A_Index]

        ; 如果窗口的进程ID与当前活动窗口的进程ID相同
        if (windowPID = currentPID)
        {
            ; 激活该窗口
            WinActivate, % "ahk_id " windowList[A_Index]
            return
        }
    }
}

我:

报错了,以下为错误信息: Error: Function calls require a space or “(”. Use comma only between parameters.

AI改正代码:
#Requires AutoHotkey v2.0

#`::
{
    ; 获取当前活动窗口的进程ID
    currentPID := WinGetPID("A")

    ; 获取所有窗口的列表
    windowList := WinGetList()

    ; 遍历所有窗口
    for windowID in windowList
    {
        ; 获取窗口的进程ID
        windowPID := WinGetPID("ahk_id " windowID)

        ; 如果窗口的进程ID与当前活动窗口的进程ID相同
        if (windowPID = currentPID)
        {
            ; 激活该窗口
            WinActivate("ahk_id " windowID)
            return
        }
    }
}

我:

脚本依旧不管用,按下快捷键后没有任何反应

AI继续改代码:
#Requires AutoHotkey v2.0

#`::
{
    ; 获取当前活动窗口的进程ID
    currentPID := WinGetPID("A")

    ; 获取所有窗口的列表
    windowList := WinGetList()

    ; 标记是否找到当前窗口
    foundCurrent := false

    ; 遍历所有窗口
    for windowID in windowList
    {
        ; 获取窗口的进程ID
        windowPID := WinGetPID("ahk_id " windowID)

        ; 如果窗口的进程ID与当前活动窗口的进程ID相同
        if (windowPID = currentPID)
        {
            ; 如果已经找到当前窗口,则激活下一个窗口
            if (foundCurrent)
            {
                WinActivate("ahk_id " windowID)
                return
            }

            ; 如果当前窗口是活动窗口,标记为已找到
            if (WinActive("ahk_id " windowID))
            {
                foundCurrent := true
            }
        }
    }

    ; 如果没有找到下一个窗口,则激活第一个窗口
    if (foundCurrent)
    {
        WinActivate("ahk_id " windowList[1])
    }
}

我:

现在可以工作了,但你这个只能实现同个程序的两个窗口间切换,一旦有了超过2个窗口,就不好用了

AI改代码
#Requires AutoHotkey v2.0

#`::
{
    ; 获取当前活动窗口的进程ID
    currentPID := WinGetPID("A")

    ; 获取所有窗口的列表
    windowList := WinGetList()

    ; 标记是否找到当前窗口
    foundCurrent := false

    ; 遍历所有窗口
    for windowID in windowList
    {
        ; 获取窗口的进程ID
        windowPID := WinGetPID("ahk_id " windowID)

        ; 如果窗口的进程ID与当前活动窗口的进程ID相同
        if (windowPID = currentPID)
        {
            ; 如果已经找到当前窗口,则激活下一个窗口
            if (foundCurrent)
            {
                WinActivate("ahk_id " windowID)
                return
            }

            ; 如果当前窗口是活动窗口,标记为已找到
            if (WinActive("ahk_id " windowID))
            {
                foundCurrent := true
            }
        }
    }

    ; 如果没有找到下一个窗口,则激活第一个窗口
    if (foundCurrent)
    {
        WinActivate("ahk_id " windowList[1])
    }
    else
    {
        ; 如果当前窗口是最后一个窗口,则激活第一个窗口
        WinActivate("ahk_id " windowList[1])
    }
}

我:

依然是只能实现2个窗口间切换,无法实现3个及以上窗口来回切换

AI改代码
#Requires AutoHotkey v2.0

#`::
{
    ; 获取当前活动窗口的进程ID
    currentPID := WinGetPID("A")

    ; 获取所有窗口的列表
    windowList := WinGetList()

    ; 标记是否找到当前窗口
    foundCurrent := false

    ; 遍历所有窗口
    for windowID in windowList
    {
        ; 获取窗口的进程ID
        windowPID := WinGetPID("ahk_id " windowID)

        ; 如果窗口的进程ID与当前活动窗口的进程ID相同
        if (windowPID = currentPID)
        {
            ; 如果已经找到当前窗口,则激活下一个窗口
            if (foundCurrent)
            {
                WinActivate("ahk_id " windowID)
                return
            }

            ; 如果当前窗口是活动窗口,标记为已找到
            if (WinActive("ahk_id " windowID))
            {
                foundCurrent := true
            }
        }
    }

    ; 如果没有找到下一个窗口,则激活第一个窗口
    if (foundCurrent)
    {
        ; 再次遍历所有窗口,激活第一个匹配的窗口
        for windowID in windowList
        {
            windowPID := WinGetPID("ahk_id " windowID)
            if (windowPID = currentPID)
            {
                WinActivate("ahk_id " windowID)
                return
            }
        }
    }
}

我:

我想要实现的是能在同个程序的3个及以上不同窗口间切换,你的代码只能做到在2个窗口间切换,其他窗口根本就不会被切换到!

AI改代码
#Requires AutoHotkey v2.0

#`::
{
    ; 获取当前活动窗口的进程ID
    currentPID := WinGetPID("A")

    ; 获取所有窗口的列表
    windowList := WinGetList()

    ; 标记是否找到当前窗口
    foundCurrent := false

    ; 遍历所有窗口
    for windowID in windowList
    {
        ; 获取窗口的进程ID
        windowPID := WinGetPID("ahk_id " windowID)

        ; 如果窗口的进程ID与当前活动窗口的进程ID相同
        if (windowPID = currentPID)
        {
            ; 如果已经找到当前窗口,则激活下一个窗口
            if (foundCurrent)
            {
                WinActivate("ahk_id " windowID)
                return
            }

            ; 如果当前窗口是活动窗口,标记为已找到
            if (WinActive("ahk_id " windowID))
            {
                foundCurrent := true
            }
        }
    }

    ; 如果没有找到下一个窗口,则激活第一个窗口
    if (!foundCurrent)
    {
        ; 激活第一个匹配的窗口
        for windowID in windowList
        {
            windowPID := WinGetPID("ahk_id " windowID)
            if (windowPID = currentPID)
            {
                WinActivate("ahk_id " windowID)
                return
            }
        }
    }
    else
    {
        ; 如果当前窗口是最后一个窗口,则激活第一个窗口
        for windowID in windowList
        {
            windowPID := WinGetPID("ahk_id " windowID)
            if (windowPID = currentPID)
            {
                WinActivate("ahk_id " windowID)
                return
            }
        }
    }
}

我:

同一个程序有3个窗口,如何实现: 按下快捷键,从窗口1切换到窗口2 再按下快捷键,从窗口2切换到窗口3 再按下快捷键,从窗口3切换到窗口1
如果有更多窗口,也是这样的操作逻辑。请重写代码。要求语言:用Autohotkey 2。`

AI改代码
#Requires AutoHotkey v2.0

#`::
{
    ; 获取当前活动窗口的进程ID
    currentPID := WinGetPID("A")

    ; 获取所有窗口的列表
    windowList := WinGetList()

    ; 标记是否找到当前窗口
    foundCurrent := false

    ; 遍历所有窗口
    for windowID in windowList
    {
        ; 获取窗口的进程ID
        windowPID := WinGetPID("ahk_id " windowID)

        ; 如果窗口的进程ID与当前活动窗口的进程ID相同
        if (windowPID = currentPID)
        {
            ; 如果已经找到当前窗口,则激活下一个窗口
            if (foundCurrent)
            {
                WinActivate("ahk_id " windowID)
                return
            }

            ; 如果当前窗口是活动窗口,标记为已找到
            if (WinActive("ahk_id " windowID))
            {
                foundCurrent := true
            }
        }
    }

    ; 如果没有找到下一个窗口,则激活第一个窗口
    if (foundCurrent)
    {
        ; 再次遍历所有窗口,激活第一个匹配的窗口
        for windowID in windowList
        {
            windowPID := WinGetPID("ahk_id " windowID)
            if (windowPID = currentPID)
            {
                WinActivate("ahk_id " windowID)
                return
            }
        }
    }
}

我换成 Claude 3.5 Sonnet (Preview)模型

AI改代码
#Requires AutoHotkey v2.0

#`::
{
    ; 获取当前活动窗口的进程ID和窗口ID
    currentPID := WinGetPID("A")
    currentWinID := WinExist("A")
    
    ; 创建一个数组来存储同一进程的所有窗口
    sameProcessWindows := []
    
    ; 获取所有窗口并筛选出同一进程的窗口
    windowList := WinGetList()
    for windowID in windowList {
        if (WinGetPID("ahk_id " windowID) = currentPID) {
            sameProcessWindows.Push(windowID)
        }
    }
    
    ; 如果只有一个窗口,直接返回
    if (sameProcessWindows.Length <= 1) {
        return
    }
    
    ; 查找当前窗口在数组中的位置
    currentIndex := 0
    for index, windowID in sameProcessWindows {
        if (windowID = currentWinID) {
            currentIndex := index
            break
        }
    }
    
    ; 计算下一个要激活的窗口索引
    nextIndex := (currentIndex = sameProcessWindows.Length) ? 1 : currentIndex + 1
    
    ; 激活下一个窗口
    WinActivate("ahk_id " sameProcessWindows[nextIndex])
}

我:

试了你的代码,只能实现在2个窗口间切换,并不适合有超过2个窗口的情况

AI改代码

#Requires AutoHotkey v2.0

#`::
{
    ; 获取当前活动窗口的进程ID和窗口ID
    currentPID := WinGetPID("A")
    currentWinID := WinExist("A")

    ; 创建一个数组来存储同一进程的所有窗口
    sameProcessWindows := []

    ; 获取所有窗口并筛选出同一进程的窗口
    windowList := WinGetList()
    for windowID in windowList {
        windowPID := WinGetPID("ahk_id " windowID)
        if (windowPID = currentPID) {
            ; 只添加可见的窗口
            if (WinGetStyle("ahk_id " windowID) & 0x10000000) { ; WS_VISIBLE
                sameProcessWindows.Push(windowID)
            }
        }
    }

    ; 如果只有一个窗口,直接返回
    if (sameProcessWindows.Length <= 1) {
        return
    }

    ; 查找当前窗口在数组中的位置
    currentIndex := 0
    for index, windowID in sameProcessWindows {
        if (windowID = currentWinID) {
            currentIndex := index
            break
        }
    }

    ; 如果没有找到当前窗口,激活第一个窗口
    if (currentIndex = 0) {
        WinActivate("ahk_id " sameProcessWindows[1])
        return
    }

    ; 计算下一个要激活的窗口索引
    nextIndex := (currentIndex >= sameProcessWindows.Length) ? 1 : currentIndex + 1

    ; 激活下一个窗口
    WinActivate("ahk_id " sameProcessWindows[nextIndex])
    
    ; 强制重绘窗口以确保切换
    WinRedraw("ahk_id " sameProcessWindows[nextIndex])
}

最终还是只能在2个窗口间切换,我放弃

我觉得你的问题出现在没有说明白需求,你再试一下。这次你先让AI帮你把需求整理清楚,不要让他写代码。

我补充了跟AI的对话,你看看,我感觉需求已经非常明确了啊

略微修改了下。小众语言问AI还是会差点意思的。

代码
#Requires AutoHotkey v2.0

currentValidPID := 0
; 创建一个数组来存储同一进程的所有窗口
sameProcessWindows := []

#`::
{
	global
    ; 获取当前活动窗口的进程ID和窗口ID
    currentPID := WinGetPID("A")
    currentWinID := WinExist("A")

	if currentValidPID != currentPID {
		currentValidPID := currentPID
		; 创建一个数组来存储同一进程的所有窗口
		sameProcessWindows := []

		; 获取所有窗口并筛选出同一进程的窗口
		windowList := WinGetList()
		for windowID in windowList {
		    windowPID := WinGetPID("ahk_id " windowID)
		    if (windowPID = currentPID) {
		        ; 只添加可见的窗口
		        if (WinGetStyle("ahk_id " windowID) & 0x10000000) { ; WS_VISIBLE
		            sameProcessWindows.Push(windowID)
		        }
		    }
		}
	}


    ; 如果只有一个窗口,直接返回
    if (sameProcessWindows.Length <= 1) {
        return
    }

    ; 查找当前窗口在数组中的位置
    currentIndex := 0
    for index, windowID in sameProcessWindows {
        if (windowID = currentWinID) {
            currentIndex := index
            break
        }
    }

    ; 如果没有找到当前窗口,激活第一个窗口
    if (currentIndex = 0) {
        WinActivate("ahk_id " sameProcessWindows[1])
        return
    }

    ; 计算下一个要激活的窗口索引
    nextIndex := (currentIndex >= sameProcessWindows.Length) ? 1 : currentIndex + 1

    ; 激活下一个窗口
    WinActivate("ahk_id " sameProcessWindows[nextIndex])
    
    ; 强制重绘窗口以确保切换
    WinRedraw("ahk_id " sameProcessWindows[nextIndex])
}
2 个赞

人工智能不是真正的智能,它只是搜集(被灌输训练)了大量的信息
小众语言的信息少,它自然也就不熟练

感动&感谢!我来研究下人类是如何吊打人工智障的

类似 macOS 逻辑的切换同应用不同窗口,用【自荐】window-switcher: 类似 MacOS 的窗口切换器 就好了,配置文件里能修改 hotkey,可以不用造轮子的

更高级的还有最新新出的进阶版, AltTaber: 一款 MacOS 风格的 Alt+Tab 窗口/应用切换器,这款现在还不能换快捷键,但可以用 PowerToy 映射。

2 个赞