[Script] enlarge any window at "maximize" to max size to remain moveable on multiple monitors
Posted: 30 Jan 2018, 03:07
Hi
When maximize a window it can - under some circumstances - no longer be moved from one monitor to another.
At least this what I discovered in Win10.
The following script solved this by:
- work on any single window of any application
- check constantly if a window is maximized
- undo the maximize but extend the window to full screen width & height
- "maximize" a such full screen window will normalize the window back to size fefore first "maximize" action was triggered
- Same behaviour if you click on the maximize icon in the title bar or doubleclick on the titlebar
- Maximize a window keep the window at the current monitor
- Undo the maximize also keep the window at the current monitor
The script has been tested with 2 monitors of same size & resolution. It has been tested on a variety of applications like IE, Edge, MS Office, Notepad++, Total Comander, and several more.
During development, I get various help here in the forum. Thanks for !
Enjoy
When maximize a window it can - under some circumstances - no longer be moved from one monitor to another.
At least this what I discovered in Win10.
The following script solved this by:
- work on any single window of any application
- check constantly if a window is maximized
- undo the maximize but extend the window to full screen width & height
- "maximize" a such full screen window will normalize the window back to size fefore first "maximize" action was triggered
- Same behaviour if you click on the maximize icon in the title bar or doubleclick on the titlebar
- Maximize a window keep the window at the current monitor
- Undo the maximize also keep the window at the current monitor
The script has been tested with 2 monitors of same size & resolution. It has been tested on a variety of applications like IE, Edge, MS Office, Notepad++, Total Comander, and several more.
During development, I get various help here in the forum. Thanks for !
Enjoy
Code: Select all
; ===============================================
; enlarge any window at "maximize" to max size to remain moveable on multiple monitors
; ===============================================
; Wolfgang Studer, 2018
; ===============================================
#Persistent
#SingleInstance, force
MaximizedWindows := {}
SetTimer, WatchMaximizedWindow, 1000
return
; See : https://autohotkey.com/boards/viewtopic.php?f=5&t=43488&p=197401#p197401
WatchMaximizedWindow:
global MaximizedWindows
WinGet, WinId, List,,, Program Manager
Loop, % WinId
{
hwnd := WinId%A_Index%
this_key := "ahk_id " . hwnd
; get current window positions
WinGetPos, winX, winY, WinW, WinH, % this_key
; and Minimum/Maximum status
winGet, isMinMax, MinMax, % this_key
if ( isMinMax = 1 )
{
; get monitor Number
winMonitorNbr := getMonitorIndexFromWindow(this_key)
; check if current id is in list of maximzed windows
; if yes, remove from list and continue with next window
if ( MaximizedWindows.HasKey( this_key ) = True && MaximizedWindows[this_key].IsMax = 1 )
{
if ( MaximizedWindows[this_key].HasKey( "Monitor" ) = False )
MaximizedWindows[this_key]["Monitor"] := winMonitorNbr ; should theoretically never happen but ....
; adapt windows position if monitor has been changed
if ( MaximizedWindows[this_key].Monitor != winMonitorNbr )
{
sysGet, monOld, monitor, % MaximizedWindows[this_key].Monitor
sysGet, monNew, monitor, % winMonitorNbr
if ( monOldLeft != monNewLeft )
MaximizedWindows[this_key].winX += ( monNewLeft - monOldLeft )
if ( monOldTop != monNewTop )5
MaximizedWindows[this_key].winY += ( monNewTop - monOldTop )
}
; reset maximized flag
MaximizedWindows[this_key]["IsMax"] := 0
; move to last known size & position
winMoveSmooth( hwnd, MaximizedWindows[this_key].winX, MaximizedWindows[this_key].winY, MaximizedWindows[this_key].winW, MaximizedWindows[this_key].winH )
; continue with next window
continue
}
; Save maximized flag and monitor Number
MaximizedWindows[this_key]["IsMax"] := 1
MaximizedWindows[this_key]["Monitor"] := winMonitorNbr ; needed only when window is maximized
; check which monitor it's on (SysGet) and move (WinMove)
sysGet, mon, monitor, % winMonitorNbr
winMoveSmooth( hwnd, monLeft, monTop, monRight - monLeft, monBottom - monTop )
}
; save if not maximized
if ( MaximizedWindows.HasKey( this_key ) = False || MaximizedWindows[this_key].IsMax != 1 )
MaximizedWindows[this_key] := { winX: winX, winY: winY, winW: winW, winH: winH }
}
return
getMonitorIndexFromWindow( winTitle="A", byref monRet="")
{
winGet,hwnd, id, % winTitle
varSetCapacity(monInfo,40),numPut(40, monInfo)
mon := []
if( monHandle:=dllCall("MonitorFromWindow","UInt",hwnd,"UInt",0x2))
&& dllCall("GetMonitorInfo","UInt",monHandle,"UInt",&monInfo)
{
loop 4 ; x, y, w, h
mon[a_index]:= numGet(monInfo,4*a_index,"Int")
sysGet,monCount,monitorCount
loop % monCount
{
sysGet,iMon,Monitor,% a_index
; Compare location to determine the monitor index.
if(mon[1]=iMonLeft && mon[2]=iMonTop && mon[3]=iMonRight && mon[4]=iMonBottom)
{
monIndex := a_index
break
}
}
}
if(monRet)
monRet:=mon
return monIndex?monIndex:1
}
winMoveSmooth( hwnd, tgtX, tgtY, tgtW, tgtH )
{
; https://autohotkey.com/board/topic/63504-hidden-window-shows-when-moved/
; Initialize WINDOWPLACEMENT structure.
VarSetCapacity(wp, 44, 0), NumPut(44, wp, 0, "uint")
; Get current placement.
DllCall("GetWindowPlacement", "ptr", hwnd, "ptr", &wp)
; wp_length := NumGet(wp, 0, "UInt")
; wp_flags := NumGet(wp, 4, "UInt")
; wp_showCmd := NumGet(wp, 8, "UInt")
; wp_ptMinPosition_X := NumGet(wp, 12, "Int")
; wp_ptMinPosition_Y := NumGet(wp, 16, "Int")
; wp_ptMaxPosition_X := NumGet(wp, 20, "Int")
; wp_ptMaxPosition_Y := NumGet(wp, 24, "Int")
; wp_rcNormalPosition_left := NumGet(wp, 28, "Int")
; wp_rcNormalPosition_top := NumGet(wp, 32, "Int")
; wp_rcNormalPosition_right := NumGet(wp, 36, "Int")
; wp_rcNormalPosition_bottom := NumGet(wp, 40, "Int")
; overwrite settings
wp_flags := 4 ; WPF_ASYNCWINDOWPLACEMENT
wp_showCmd := 1 ; SW_SHOWNORMAL
wp_rcNormalPosition_left := tgtX
wp_rcNormalPosition_top := tgtY
wp_rcNormalPosition_right := tgtX + tgtW
wp_rcNormalPosition_bottom := tgtY + tgtH
; update placement
NumPut(wp_flags, wp, 4, "uint")
NumPut(wp_showCmd, wp, 8, "uint")
NumPut(wp_rcNormalPosition_left, wp, 28, "int")
NumPut(wp_rcNormalPosition_top, wp, 32, "int")
NumPut(wp_rcNormalPosition_right, wp, 36, "int")
NumPut(wp_rcNormalPosition_bottom, wp, 40, "int")
; Set new placement.
DllCall("SetWindowPlacement", "ptr", hwnd, "ptr", &wp)
}