确定焦点 window 在哪个监视器上?

Determine which monitor the focus window is on?

确定焦点 window 在哪个显示器上的小型 AHK 函数。

我正在编写一个脚本,该脚本需要焦点 window 位于哪个监视器上的上下文。我找到了很多解决方案,但是 none 太容易理解了,或者比需要的要复杂一些。

下文将为您介绍。 AHK中的监控索引供您参考。

GetFocusWindowMonitorIndex(){
    ;Get number of monitor
    SysGet, monCount, MonitorCount
    
    ;Iterate through each monitor
    Loop %monCount%{
        ;Get Monitor working area
        SysGet, workArea, Monitor, % A_Index
        
        ;Get the position of the focus window
        WinGetPos, X, Y, , , A
        
        ;Check if the focus window in on the current monitor index
        if (X >= workAreaLeft && X < workAreaRight && Y >= workAreaTop && Y < workAreaBottom ){
            ;Return the monitor index since its within that monitors borders.
            return % A_Index
        }
    }
}

注意下面是修改后的版本,其中 window 作为参数传递,而不是默认值;焦点 window

GetFocusWindowMonitorIndex(thisWindow){
    ;Get number of monitor
    SysGet, monCount, MonitorCount
    
    ;Iterate through each monitor
    Loop %monCount%{
        ;Get Monitor working area
        SysGet, workArea, Monitor, % A_Index
        
        ;Get the position of the focus window
        WinGetPos, X, Y, , , %thisWindow%
        
        ;Check if the focus window in on the current monitor index
        if (X >= workAreaLeft && X < workAreaRight && Y >= workAreaTop && Y < workAreaBottom ){
            ;Return the monitor index since it's within that monitors borders.
            return % A_Index
        }
    }
}

即使这能帮助更多人,我也会称之为胜利。

编辑:

如果你需要工作区(不包括工作区中的tarkbar)使用这个功能。

GetFocusWindowMonitorIndex(){
    ;Get number of monitor
    SysGet, monCount, MonitorCount
    
    ;Iterate through each monitor
    Loop %monCount%{
        ;Get Monitor working area
        SysGet, workArea, MonitorWorkArea , % A_Index
        
        ;Get the position of the focus window
        WinGetPos, X, Y, , , A
        
        ;Check if the focus window in on the current monitor index
        if (X >= workAreaLeft && X < workAreaRight && Y >= workAreaTop && Y < workAreaBottom ){
            ;Return the monitor index since its within that monitors borders.
            return % A_Index
        }
    }
}

我想指出,如果出现以下情况,之前的答案将无效:

  1. 你有一个最大化的 window(window 会略微超出显示器边界,在我的例子中,每个方向都超出 10 个像素)
  2. window 与多个 windows 重叠。在那种情况下,最合适的做法是查看哪个监视器包含最大的活动 window.
GetFocusWindowMonitorIndex(){
    ;Get number of monitor
    SysGet, monCount, MonitorCount

    ;Get the position of the focus window
    WinGetPos, WindowX, WindowY, WindowWidth, WindowHeight, A

    ;Make an array to hold the sub-areas of the window contained within each monitor
    monitorSubAreas := []

    ;Iterate through each monitor
    Loop %monCount%{
        ;Get Monitor working area
        SysGet, Monitor, MonitorWorkArea , % A_Index
    
        ;Calculate sub-area of the window contained within each monitor
        xStart := max(WindowX,  MonitorLeft)
        xEnd :=  min(WindowX + WindowWidth,  MonitorRight)
        yStart := max(WindowY, MonitorTop)
        yEnd :=  min(WindowY + WindowHeight,  MonitorBottom)
        area := (xEnd - xStart) * (yEnd - yStart)
        
        ;Remember these areas, and which monitor they were associated with
        monitorSubAreas.push({"area": area, "index": A_Index})
    }
    ;If there is only one monitor in the array, then you already have your answer
    if(monitorSubAreas.length() == 1) {
        return monitorSubAreas[1].index
    }
    
    
    ;Otherwise, loop to figure out which monitor's recorded sub-area was largest
    winningMonitor := 0
    winningArea := 0
    for index, monitor in monitorSubAreas {
        winningMonitor := monitor.area > winningArea ? monitor.index : winningMonitor
        winningArea := monitor.area > winningArea ?  monitor.area : winningArea
    }
    return winningMonitor
}