Autohotkey 使用自动热键切换到活动监视器中最近打开的应用程序?

Autohotkey 使用自动热键切换到活动监视器中最近打开的应用程序?,autohotkey,multiple-monitors,alt-tab,Autohotkey,Multiple Monitors,Alt Tab,我一直在使用一个简短的自动热键脚本,用鼠标中键模拟Windows 10上的Alt Tab,这样我就可以快速打开最近打开的应用程序,或者通过单击按钮在两个应用程序之间切换。这就是我用的 Mbutton::SendEvent {Alt Down}{Tab}{Alt Up} 但我最近使用了两台显示器,我真正想做的是切换到活动显示器(或鼠标当前所在的显示器)上最近打开的应用程序。单独使用Alt选项卡显然不起作用,因为最近打开的应用程序通常在另一个监视器上,我只想将最近使用的应用程序的窗口向前移动,如果

我一直在使用一个简短的自动热键脚本,用鼠标中键模拟Windows 10上的Alt Tab,这样我就可以快速打开最近打开的应用程序,或者通过单击按钮在两个应用程序之间切换。这就是我用的

Mbutton::SendEvent {Alt Down}{Tab}{Alt Up}

但我最近使用了两台显示器,我真正想做的是切换到活动显示器(或鼠标当前所在的显示器)上最近打开的应用程序。单独使用Alt选项卡显然不起作用,因为最近打开的应用程序通常在另一个监视器上,我只想将最近使用的应用程序的窗口向前移动,如果它在我当前使用的监视器中。有没有人知道这是否可能,以及我将如何着手去做

我正在粘贴我的脚本。它非常难看,但它在我的两个监视器设置上工作,如您所述:切换到上一个(对于您单击中间按钮的监视器)活动窗口

#WinActivateForce
#SingleInstance
#Persistent

CoordMode, Mouse, Screen
CoordMode, ToolTip, Screen

DetectHiddenWindows, On
SetTitleMatchMode , 2
SetBatchLines , -1
SetWorkingDir %A_ScriptDir%

Thread, interrupt, 0
SetTimer, UpdateCurrentWindow, 100

isDebug := true

SysGet, monitors_total, MonitorCount
SysGet, monitor_primary, MonitorPrimary

Hotkey, MButton, SwitchToLastWindow, On

return


SwitchToLastWindow:

WinGet, active_id, ID, A

Loop , %monitors_total%
{
    if (A_Index != current_monitor)
        continue

    switch_to_window := (active_id = winlast%A_Index%)
                      ? winprelast%A_Index%
                      : winlast%A_Index%
}

WinActivate , ahk_id %switch_to_window%

return



UpdateCurrentWindow:

WinGet, active_id, ID, A
monitor_index := GetMonitorIndexFromWindow(active_id)

current_monitor := GetMonitorIndexFromMouse()

if (monitor_index > monitors_total)
    monitors_total := monitor_index

if (winlast%monitor_index% != active_id)
{
    winprelast%monitor_index% := winlast%monitor_index%
    winlast%monitor_index% := active_id
}

if isDebug
{
    DebugToolTip := ""
    Loop , %monitors_total%
    {
        DebugToolTip .= "Monitor # " . A_Index
                     . ":`n`nLast window: "  . winlast%A_Index%
                     . "`nPre-last window: " . winprelast%A_Index% . "`n`n"
    }

    MouseGetPos, xpos, ypos
    DebugToolTip .= "x: " . xpos . "`ny: " . ypos . "`ncurrent_monitor: " . current_monitor
                 . "`n`nA_ScreenHeight: " . A_ScreenHeight . "`nA_ScreenWidth: " . A_ScreenWidth
                 . "`n`nmonitors_total: " . monitors_total . "`nmonitor_primary: " . monitor_primary

    ToolTip , %DebugToolTip%, 10, 10
}

return


; only done for one case: total 2 monitors, monitor to the left is primary
; need to redo for the generic case

GetMonitorIndexFromMouse()
{
    SysGet, monitors_total, MonitorCount
    SysGet, monitor_primary, MonitorPrimary
    MouseGetPos, xpos, ypos
    current_monitor := (xpos > A_ScreenWidth) ? 2 : 1

    return current_monitor
}


; this function is from autohotkey.com/board/topic/69464-how-to-determine-a-window-is-in-which-monitor/?p=440355

GetMonitorIndexFromWindow(windowHandle)
{
    ; Starts with 1.
    monitorIndex := 1

    VarSetCapacity(monitorInfo, 40)
    NumPut(40, monitorInfo)

    if (monitorHandle := DllCall("MonitorFromWindow", "uint", windowHandle, "uint", 0x2)) 
        && DllCall("GetMonitorInfo", "uint", monitorHandle, "uint", &monitorInfo) 
    {
        monitorLeft   := NumGet(monitorInfo,  4, "Int")
        monitorTop    := NumGet(monitorInfo,  8, "Int")
        monitorRight  := NumGet(monitorInfo, 12, "Int")
        monitorBottom := NumGet(monitorInfo, 16, "Int")
        workLeft      := NumGet(monitorInfo, 20, "Int")
        workTop       := NumGet(monitorInfo, 24, "Int")
        workRight     := NumGet(monitorInfo, 28, "Int")
        workBottom    := NumGet(monitorInfo, 32, "Int")
        isPrimary     := NumGet(monitorInfo, 36, "Int") & 1

        SysGet, monitorCount, MonitorCount

        Loop, %monitorCount%
        {
            SysGet, tempMon, Monitor, %A_Index%

            ; Compare location to determine the monitor index.
            if ((monitorLeft = tempMonLeft) and (monitorTop = tempMonTop)
                and (monitorRight = tempMonRight) and (monitorBottom = tempMonBottom))
            {
                monitorIndex := A_Index
                break
            }
        }
    }

    return monitorIndex
}
其中一个函数(
GetMonitorIndexFromWindow(windowHandle)
)不是我的,是我的

请注意,我没有时间为我的
GetMonitorIndexFromMouse()
函数处理通用情况,因此它只适合我的特定情况(2个监视器,左侧一个作为主监视器)


我这里有
isDebug:=true
,这样您就可以看到带有变量的工具提示− 如果脚本适合您,您可以随意将其更改为
isDebug:=false
当然可以。

我可以想象您可以编写一个脚本,跟踪四个(在两个监视器的情况下)窗口的ID− 每个显示器最近打开的两个窗口。它会定期检查和更新它们。当按下热键时,它应该检测什么是当前监视器、当前窗口,然后检查此监视器的两个最近窗口列表。如果第一个与当前激活的相同,它将切换到第二个;当然不是− 感谢两位中的第一位。是的,我认为这样做可能会奏效。问题是我不能从头开始!我希望能在网上找到一些我可以适应的东西,但还没有。这并不简单。以下是如何检查窗口所在的屏幕: