You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinMove函数失效:跨显示器窗口移动与分辨率适配问题排查

问题修复:AutoHotkey跨显示器窗口移动+分辨率适配

核心问题定位

你的代码里WinMove失效主要是语法参数顺序错误,另外缩放因子未实际生效,全屏窗口处理逻辑冗余,以下是针对性修复:

1. WinMove语法修正

AutoHotkey的WinMove标准语法是:

WinMove, WinTitle, WinText, X, Y, Width, Height

原代码中WinMove, ahk_id %ActiveWinID% , %NewX% , %CurrentY% , %NewWidth%, %NewHeight%的问题是:WinText参数被省略但未留空占位,导致参数错位。正确写法需要在窗口标题后保留WinText的位置(即使为空):

WinMove, ahk_id %ActiveWinID%, , %NewX%, %CurrentY%, %NewWidth%, %NewHeight%

2. 真实分辨率缩放适配

原代码中缩放因子固定为1,无法处理不同分辨率显示器的适配。可以通过SysGet获取显示器真实分辨率,计算缩放比例:

; 获取显示器分辨率(放在脚本开头)
SysGet, Monitor1, Monitor, 1
SysGet, Monitor2, Monitor, 2
; 按宽度比例计算缩放因子,可按需替换为高度
ScaleFactor := Monitor2Right / Monitor1Right

3. 全屏/最大化窗口逻辑优化

原代码重复判断IsMaximized且移动时机错误,应先恢复窗口再移动,最后重新最大化:

else if (WinX < 0 || WinY < 0) {
    WinGet, IsMaximized, MinMax, ahk_id %thisID%
    if (IsMaximized) {
        WinRestore, ahk_id %thisID%  ; 先恢复窗口才能调整位置
        SwapToScreen(thisID, Monitor2X, Monitor1X, WinY, Monitor1X)
        WinMaximize, ahk_id %thisID%  ; 移动完成后重新最大化
    }
}

完整修复代码

#SingleInstance Force
#DPIAware  ; 启用高DPI感知,避免坐标偏移

; 初始化显示器参数
SysGet, Monitor1, Monitor, 1
SysGet, Monitor2, Monitor, 2
Monitor1X := Monitor1Left
Monitor1EndX := Monitor1Right
Monitor2X := Monitor2Left
Monitor2EndX := Monitor2Right

; 主逻辑部分
{...
; 从显示器1移到2
    if (WinX >= Monitor1X && WinX < Monitor1EndX) {
        SwapToScreen(thisID, Monitor2X, WinX, WinY, Monitor1X, 2)
        MsgBox , 1 to 2, %Title%
    }
    ; 从显示器2移到1
    else if (WinX >= Monitor2X && WinX < Monitor2EndX) {
        SwapToScreen(thisID, Monitor1X, WinX, WinY, Monitor2X, 1)
        MsgBox, 2 to 1, %Title%
    }
    ; 处理全屏/最大化窗口
    else if (WinX < 0 || WinY < 0) {
        WinGet, IsMaximized, MinMax, ahk_id %thisID%
        if (IsMaximized) {
            WinRestore, ahk_id %thisID%
            SwapToScreen(thisID, Monitor2X, Monitor1X, WinY, Monitor1X, 2)
            WinMaximize, ahk_id %thisID%
        }
    }
    else {
        MsgBox, Active window is not within defined screen boundaries.
    }
}
}

SwapToScreen(ActiveWinID, TargetMonitorX, CurrentX, CurrentY, SourceMonitorX, TargetMonitorNum) {
    NewX := TargetMonitorX + (CurrentX - SourceMonitorX)
    WinGetPos, OldX, OldY, OldWidth, OldHeight, ahk_id %ActiveWinID%

    ; 计算目标显示器的缩放因子
    SysGet, SourceMonitor, Monitor, % (TargetMonitorNum = 1 ? 2 : 1)
    SysGet, TargetMonitor, Monitor, %TargetMonitorNum%
    ScaleFactor := TargetMonitorRight / SourceMonitorRight

    NewWidth := Round(OldWidth * ScaleFactor)
    NewHeight := Round(OldHeight * ScaleFactor)

    ; 修正后的WinMove执行
    WinMove, ahk_id %ActiveWinID%, , %NewX%, %CurrentY%, %NewWidth%, %NewHeight%
    
    ; 调试信息(可选保留)
    MsgBox, 窗口ID: %ActiveWinID% 已移动到`X: %NewX%, Y: %CurrentY%`,尺寸调整为`%NewWidth%x%NewHeight%`
}

额外注意事项

  • 对于UWP应用或特殊边框窗口,可尝试添加WinSet, Style, -0xC00000, ahk_id %ActiveWinID%移除边框后再移动,避免位置偏移。

内容的提问来源于stack exchange,提问作者Gökhan Dumlupınar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:43:10