Moving window to each quarter of screen - help with one of them too high

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
maxkill
Posts: 158
Joined: 11 Apr 2016, 13:03

Moving window to each quarter of screen - help with one of them too high

13 Nov 2021, 12:20

Hello!

The lowest left one in the quadrant is too high unlike the rest which all make correct height, what's wrong with it?

upon further inspection the same lower left quadrant also appears to be a few pixels too wide aswell
the upper left is few pixels too wide aswell :headwall:

(4k monitor)

Code: Select all

; *********************************************************************************
; 		Automatic Mapping of All Monitors, Move & Resize Windows  -STA

; *********************************************************************************

; Initialization of Arrays used
; Variables used for Temporary Monitor Number used to later organize Monitors in Ascending Order
; (1D Arrays)
MonTopTemp := []
MonBtmTemp := []
MonLftTemp := []
MonRgtTemp := []

; Variables used for Definitive Monitor Number in Ascending Order
; (1D Arrays)
MonTop := []
MonBtm := []
MonLft := []
MonRgt := []

; Variables used for Monitor Dimensions for Resizing to Half or Monitor and for Moving to another Monitor
; (1D Arrays)
MonHlfLft := []
MonHlfRgt := []
MonWdt := []
MonHlfWdt := []
MonHgt := []

; Variables of Definitive Monitor Number used to Move Windows Up and Down between Rows
; (2D Arrays)
MtxTop := []
MtxBtm := []
MtxLft := []
MtxRgt := []
MtxWdt := []
MtxHgt := []
MtxLstRow := []
MtxRowQty := []
Col_RowQty := []

; Variables used for Monitor Dimensions for Resizing to Quadrant of Monitor per Monitor Number
; (2D Arrays)
MonQdrTop := []
MonQdrLft := []
MonQdrBtm := []
MonQdrRgt := []
MonQdrWdt := []
MonQdrHgt := []

; Variables used for Monitor Dimensions for Resizing to Quadrant of Monitor per Column
; (3D Arrays)
MtxQdrTop := []
MtxQdrLft := []
MtxQdrBtm := []
MtxQdrRgt := []
MtxQdrWdt := []
MtxQdrHgt := []


; Variables used for Row Alignment with Bottom of Monitors
MonDIMBtmT := []

; Retrieve the Quantity of Monitors connected to system
SysGet, MonQty, MonitorCount

; Retrieve Coordinates and Dimensions of each Monitor
Loop, %MonQty%
{
	SysGet, MonWRKA, MonitorWorkArea, %A_Index%
	SysGet, MonDIM, Monitor, %A_Index%

	MonTopTemp[A_Index] := MonWRKATop
	MonBtmTemp[A_Index] := MonWRKABottom
	MonLftTemp[A_Index] := MonWRKALeft
	MonRgtTemp[A_Index] := MonWRKARight

	RowCntTemp = %RowCntTemp%, %MonWRKATop%
	ColCntTemp = %ColCntTemp%, %MonWRKALeft%

	; Variables used for Row Alignment with Bottom of Monitors
	; Options to Define Rows with Bottom of Monitors are Indicated Further in the Script
	MonDIMBtmT[A_Index] := MonDIMBottom
	RowCntBtmT = %RowCntBtmT%, %MonDIMBottom%
}

; Trim the first character (a comma ",") 
StringTrimLeft, RowCnt, RowCntTemp, 1
StringTrimLeft, ColCnt, ColCntTemp, 1
; Bottom of Row Alignment
StringTrimLeft, RowBtmCnt, RowCntBtmT, 1

; List out each unique value of Row and Column, defining boundaries
Sort RowCnt, N U D,
Sort ColCnt, N U D,
; Bottom of Row Alignment
Sort RowBtmCnt, N U D,

; Count the number of Rows and Columns
Loop, Parse, RowCnt, `,
{
	RowQty := A_Index
}
Loop, Parse, ColCnt, `,
{
	ColQty := A_Index
}
; Bottom of Row Alignment
Loop, Parse, RowBtmCnt, `,
{
	RowBtmQty := A_Index
}

; Separates each value of Row and Column into an Array Variable
RowValues := StrSplit(RowCnt, ",", " ")
ColValues := StrSplit(ColCnt, ",", " ")
; Bottom of Row Alignment
RowBtmValues := StrSplit(RowBtmCnt, ",", " ")

; ***** Monitor Mapping Initialization *****
; After counting how many Rows and Columns there are, the script will verify if
; there is a Monitor in each of the Rows/Columns Positions. If there is a gap
; (no Monitor in a Row/Column), the Space should not register in the Mapping

; Counter to Assign Monitor Number, from Top Left to Bottom Right
MonOrdr := 1

Loop, %RowQty%
; ******************************************************************
; Option ➔ Bottom of Row Alignment / Put in Comments the Line above
; Loop, %RowBtmQty%
; ******************************************************************
{
	; Keep the current Row in Memory
	RowPosA_Index := A_Index
	
	Loop, %ColQty%
	{
		; Keep the current Column in Memory
		ColPosA_Index := A_Index
		
		Loop, %MonQty%
		{
			; Keep the current Monitor Number in Memory
			MonNrA_Index := A_Index
			
			If (ColValues[ColPosA_Index] == MonLftTemp[MonNrA_Index] AND RowValues[RowPosA_Index] == MonTopTemp[MonNrA_Index])
			; *********************************************************************************************************************
			; Option ➔ Bottom of Row Alignment / Put in Comments the Line above
			; If (ColValues[ColPosA_Index] == MonLftTemp[MonNrA_Index] AND RowBtmValues[RowPosA_Index] == MonDIMBtmT[MonNrA_Index])
			; *********************************************************************************************************************
			{
				; Assign COORDINATES and DIMENSIONS of Monitors in Order, per MONITOR NUMBER, from Top Left to Bottom Right
				MonTop[MonOrdr] := MonTopTemp[MonNrA_Index]
				MonLft[MonOrdr] := MonLftTemp[MonNrA_Index]
				MonBtm[MonOrdr] := MonBtmTemp[MonNrA_Index]
				MonRgt[MonOrdr] := MonRgtTemp[MonNrA_Index]

				; Calculate COORDINATES and DIMENSIONS, per MONITOR NUMBER, to move Window to HALF OF MONITOR and to Another Monitor
				MonHlfLft[MonOrdr] := MonLft[MonOrdr]
				MonHlfRgt[MonOrdr] := Floor((MonLft[MonOrdr] + MonRgt[MonOrdr]) / 2)
				MonWdt[MonOrdr] := MonRgt[MonOrdr] - MonLft[MonOrdr]
				MonHlfWdt[MonOrdr] := Floor((MonRgt[MonOrdr] - MonLft[MonOrdr]) / 2)
				MonHgt[MonOrdr] := MonBtm[MonOrdr] - MonTop[MonOrdr]


				; ***** For Each Monitor Found, Assign Coordinates and Dimensions to 4 Quadrants *****
				; Quadrant Q1 of Current Monitor: TOP LEFT
				MonQdrTop[MonOrdr, 1] := MonTopTemp[MonNrA_Index]
				MonQdrLft[MonOrdr, 1] := MonLftTemp[MonNrA_Index]
				MonQdrBtm[MonOrdr, 1] := Floor(MonBtmTemp[MonNrA_Index] / 2)
				MonQdrRgt[MonOrdr, 1] := Floor(MonRgtTemp[MonNrA_Index] / 2)
				MonQdrWdt[MonOrdr, 1] := Floor((MonRgtTemp[MonNrA_Index] - MonLftTemp[MonNrA_Index]) / 2)
				MonQdrHgt[MonOrdr, 1] := Floor((MonBtmTemp[MonNrA_Index] - MonTopTemp[MonNrA_Index]) / 2)

				; Quadrant Q2 of Current Monitor: BOTTOM LEFT
				MonQdrTop[MonOrdr, 2] := Floor(MonTopTemp[MonNrA_Index] + (MonBtmTemp[MonNrA_Index] - MonTopTemp[MonNrA_Index]) / 2)
				MonQdrLft[MonOrdr, 2] := MonLftTemp[MonNrA_Index]
				MonQdrBtm[MonOrdr, 2] := MonBtmTemp[MonNrA_Index]
				MonQdrRgt[MonOrdr, 2] := Floor(MonRgtTemp[MonNrA_Index] / 2)
				MonQdrWdt[MonOrdr, 2] := Floor((MonRgtTemp[MonNrA_Index] - MonLftTemp[MonNrA_Index]) / 2)
				MonQdrHgt[MonOrdr, 2] := Floor((MonBtmTemp[MonNrA_Index] - MonTopTemp[MonNrA_Index]) / 2)

				; Quadrant Q3 of Current Monitor: TOP RIGHT
				MonQdrTop[MonOrdr, 3] := MonTopTemp[MonNrA_Index]
				MonQdrLft[MonOrdr, 3] := Floor(MonLftTemp[MonNrA_Index] + (MonRgtTemp[MonNrA_Index] - MonLftTemp[MonNrA_Index]) / 2)
				MonQdrBtm[MonOrdr, 3] := Floor(MonBtmTemp[MonNrA_Index] / 2)
				MonQdrRgt[MonOrdr, 3] := MonRgtTemp[MonNrA_Index]
				MonQdrWdt[MonOrdr, 3] := Floor((MonRgtTemp[MonNrA_Index] - MonLftTemp[MonNrA_Index]) / 2)
				MonQdrHgt[MonOrdr, 3] := Floor((MonBtmTemp[MonNrA_Index] - MonTopTemp[MonNrA_Index]) / 2)

				; Quadrant Q4 of Current Monitor: BOTTOM RIGHT
				MonQdrTop[MonOrdr, 4] := Floor(MonTopTemp[MonNrA_Index] + (MonBtmTemp[MonNrA_Index] - MonTopTemp[MonNrA_Index]) / 2)
				MonQdrLft[MonOrdr, 4] := Floor(MonLftTemp[MonNrA_Index] + (MonRgtTemp[MonNrA_Index] - MonLftTemp[MonNrA_Index]) / 2)
				MonQdrBtm[MonOrdr, 4] := MonBtmTemp[MonNrA_Index]
				MonQdrRgt[MonOrdr, 4] := MonRgtTemp[MonNrA_Index]
				MonQdrWdt[MonOrdr, 4] := Floor((MonRgtTemp[MonNrA_Index] - MonLftTemp[MonNrA_Index]) / 2)
				MonQdrHgt[MonOrdr, 4] := Floor((MonBtmTemp[MonNrA_Index] - MonTopTemp[MonNrA_Index]) / 2)
				; **************************************************************************** 


				; When a Monitor is found at this ROW and COLUMN Position, increment Count for Next Monitor
				MonOrdr += 1
				; Once Matching Monitor Found, Skip to Next Column
				Break
			}
		}
	}
}

; ***** Monitor Mapping Initialization *****
; This part of the Script will Organize Monitors in Order, from Top to Bottom
Loop, %ColQty%
{
	ColPosA_Index := A_Index
	; On every new Column, Start Counting Rows at 1
	VrtMonOrdr := 1
	Loop, %RowQty%
	; ******************************************************************
	; Option ➔ Bottom of Row Alignment / Put in Comments the Line above
	; Loop, %RowBtmQty%
	; ******************************************************************
	{
		RowPosA_Index := A_Index
		Loop, %MonQty%
		{
			VrtMonNrA_Index := A_Index
			If (ColValues[ColPosA_Index] == MonLftTemp[VrtMonNrA_Index] AND RowValues[RowPosA_Index] == MonTopTemp[VrtMonNrA_Index])
			; ***************************************************************************************************************************
			; Option ➔ Bottom of Row Alignment / Put in Comments the Line above
			; If (ColValues[ColPosA_Index] == MonLftTemp[VrtMonNrA_Index] AND RowBtmValues[RowPosA_Index] == MonDIMBtmT[VrtMonNrA_Index])
			; ***************************************************************************************************************************
			{
				; Assign COORDINATES and DIMENSIONS of Monitors in Order, per ROW and COLUMN COLUMN (MATRIX), from Top to Bottom for each Column
				MtxTop[VrtMonOrdr, ColPosA_Index] := MonTopTemp[VrtMonNrA_Index]
				MtxLft[VrtMonOrdr, ColPosA_Index] := MonLftTemp[VrtMonNrA_Index]
				MtxBtm[VrtMonOrdr, ColPosA_Index] := MonBtmTemp[VrtMonNrA_Index]
				MtxRgt[VrtMonOrdr, ColPosA_Index] := MonRgtTemp[VrtMonNrA_Index]
				
				; Calculate COORDINATES and DIMENSIONS, per ROW and COLUMN COLUMN (MATRIX), to move Window to Another Monitor
				MtxWdt[VrtMonOrdr, ColPosA_Index] := MonRgtTemp[VrtMonNrA_Index] - MonLftTemp[VrtMonNrA_Index]
				MtxHgt[VrtMonOrdr, ColPosA_Index] := MonBtmTemp[VrtMonNrA_Index] - MonTopTemp[VrtMonNrA_Index]
				

				; ***** For Each Monitor Found, Assign Coordinates and Dimensions to 4 Quadrants *****
				; Quadrant Q1 of Current Monitor: TOP LEFT
				; Floor Function to be used in case there is a division of an odd number which would leave a "0.5".  Comparisons (Full Height and Quadrants) do not work without it.
				MtxQdrTop[VrtMonOrdr, ColPosA_Index, 1] := MonTopTemp[VrtMonNrA_Index]
				MtxQdrLft[VrtMonOrdr, ColPosA_Index, 1] := MonLftTemp[VrtMonNrA_Index]
				MtxQdrBtm[VrtMonOrdr, ColPosA_Index, 1] := Floor(MonBtmTemp[VrtMonNrA_Index] / 2)
				MtxQdrRgt[VrtMonOrdr, ColPosA_Index, 1] := Floor(MonRgtTemp[VrtMonNrA_Index] / 2)
				MtxQdrWdt[VrtMonOrdr, ColPosA_Index, 1] := Floor((MonRgtTemp[VrtMonNrA_Index] - MonLftTemp[VrtMonNrA_Index]) / 2)
				MtxQdrHgt[VrtMonOrdr, ColPosA_Index, 1] := Floor((MonBtmTemp[VrtMonNrA_Index] - MonTopTemp[VrtMonNrA_Index]) / 2)

				; Quadrant Q2 of Current Monitor: BOTTOM LEFT
				MtxQdrTop[VrtMonOrdr, ColPosA_Index, 2] := Floor(MonTopTemp[VrtMonNrA_Index] + (MonBtmTemp[VrtMonNrA_Index] - MonTopTemp[VrtMonNrA_Index]) / 2)
				MtxQdrLft[VrtMonOrdr, ColPosA_Index, 2] := MonLftTemp[VrtMonNrA_Index]
				MtxQdrBtm[VrtMonOrdr, ColPosA_Index, 2] := MonBtmTemp[VrtMonNrA_Index]
				MtxQdrRgt[VrtMonOrdr, ColPosA_Index, 2] := Floor(MonRgtTemp[VrtMonNrA_Index] / 2)
				MtxQdrWdt[VrtMonOrdr, ColPosA_Index, 2] := Floor((MonRgtTemp[VrtMonNrA_Index] - MonLftTemp[VrtMonNrA_Index]) / 2)
				MtxQdrHgt[VrtMonOrdr, ColPosA_Index, 2] := Floor((MonBtmTemp[VrtMonNrA_Index] - MonTopTemp[VrtMonNrA_Index]) / 2)

				; Quadrant Q3 of Current Monitor: TOP RIGHT
				MtxQdrTop[VrtMonOrdr, ColPosA_Index, 3] := MonTopTemp[VrtMonNrA_Index]
				MtxQdrLft[VrtMonOrdr, ColPosA_Index, 3] := Floor(MonLftTemp[VrtMonNrA_Index] + (MonRgtTemp[VrtMonNrA_Index] - MonLftTemp[VrtMonNrA_Index]) / 2)
				MtxQdrBtm[VrtMonOrdr, ColPosA_Index, 3] := Floor(MonBtmTemp[VrtMonNrA_Index] / 2)
				MtxQdrRgt[VrtMonOrdr, ColPosA_Index, 3] := MonRgtTemp[VrtMonNrA_Index]
				MtxQdrWdt[VrtMonOrdr, ColPosA_Index, 3] := Floor((MonRgtTemp[VrtMonNrA_Index] - MonLftTemp[VrtMonNrA_Index]) / 2)
				MtxQdrHgt[VrtMonOrdr, ColPosA_Index, 3] := Floor((MonBtmTemp[VrtMonNrA_Index] - MonTopTemp[VrtMonNrA_Index]) / 2)

				; Quadrant Q4 of Current Monitor: BOTTOM RIGHT
				MtxQdrTop[VrtMonOrdr, ColPosA_Index, 4] := Floor(MonTopTemp[VrtMonNrA_Index] + (MonBtmTemp[VrtMonNrA_Index] - MonTopTemp[VrtMonNrA_Index]) / 2)
				MtxQdrLft[VrtMonOrdr, ColPosA_Index, 4] := Floor(MonLftTemp[VrtMonNrA_Index] + (MonRgtTemp[VrtMonNrA_Index] - MonLftTemp[VrtMonNrA_Index]) / 2)
				MtxQdrBtm[VrtMonOrdr, ColPosA_Index, 4] := MonBtmTemp[VrtMonNrA_Index]
				MtxQdrRgt[VrtMonOrdr, ColPosA_Index, 4] := MonRgtTemp[VrtMonNrA_Index]
				MtxQdrWdt[VrtMonOrdr, ColPosA_Index, 4] := Floor((MonRgtTemp[VrtMonNrA_Index] - MonLftTemp[VrtMonNrA_Index]) / 2)
				MtxQdrHgt[VrtMonOrdr, ColPosA_Index, 4] := Floor((MonBtmTemp[VrtMonNrA_Index] - MonTopTemp[VrtMonNrA_Index]) / 2)
				; **************************************************************************** 


				; Assign Numbering to Monitor on this Column
				Col_RowQty[ColPosA_Index] := VrtMonOrdr

				; When a Monitor is found at this ROW and COLUMN Position, increment Count for Next Monitor in this Column
				VrtMonOrdr += 1

				; Once Matching Monitor Found, Skip to Next Row
				Break
			}
		}
	}
}
 

; 	  HOTKEY
; **************
; Move and Resize Active Window to UPPER LEFT Corner (Quadrant 1) of Current Monitor OR to BOTTOM LEFT Corner (Quadrant 2) of Current Monitor
 
; SubRoutine Label. To be Retrieved when "Move Active Window to PREVIOUS Monitor" is Activated and there is only 1 Monitor in Monitor Configuration
PrevQdr:
{
	GoSub, ExcludPrgrm
	If (IgnorePrgrm == True)
	{
		Return
	}

	WinGetPos, WinHrz, WinVrt, WinWdt, WinHgt, A
	WinGet, WinMMax, MinMax, A
	GoSub, WinCurntMon
	; Retrieves in which Quadrant Number of Current Monitor the Active Window is on.
	GoSub, WinCurntQdr
	GoSub, CrctnFctr

	If (WinMMax == 1)
	{
		WinRestore, A
	}
	
	; If Active Window is TOP LEFT Corner (Quadrant 1) OR in BOTTOM RIGHT Corner (Quadrant 4) of Current Monitor, Move and Resize Active Window to LOWER LEFT Corner (Quadrant 2) of Current Monitor
	If (OnQuadrant == 1 OR OnQuadrant == 4)
	{
		WinMove, A, , MonQdrLft[OnMonitor, 2] + HrzCrctn, MonQdrTop[OnMonitor, 2], MonQdrWdt[OnMonitor, 2] + WdtCrctn, MonQdrHgt[OnMonitor, 2] + HgtCrctn
		Return
	}
	; Else Move Active Window to TOP LEFT Corner (Quadrant 1) of Current Monitor
	Else
	{
		WinMove, A, , MonQdrLft[OnMonitor, 1] + HrzCrctn, MonQdrTop[OnMonitor, 1], MonQdrWdt[OnMonitor, 1] + WdtCrctn, MonQdrHgt[OnMonitor, 1] + HgtCrctn
		Return
	}
}

; 	  HOTKEY
; **************
; Move and Resize Active Window to UPPER Right Corner (Quadrant 3) of Current Monitor OR to BOTTOM RIGHT Corner (Quadrant 4) of Current Monitor for other circumstances


; SubRoutine Label. To be Retrieved when "Move Active Window to NEXT Monitor" is Activated and there is only 1 Monitor in Monitor Configuration
NextQdr:
{
	WinGetPos, WinHrz, WinVrt, WinWdt, WinHgt, A
	WinGet, WinMMax, MinMax, A
	GoSub, WinCurntMon
	GoSub, WinCurntQdr
	GoSub, CrctnFctr

	If (WinMMax == 1)
	{
		WinRestore, A
	}
	
	; If Active Window is in UPPER RIGHT Corner (Quadrant 3) OR in LOWER LEFT Corner (Quadrant 2) of Current Monitor, Move and Resize Active Window to LOWER RIGHT Corner (Quadrant 4) of Current Monitor
	If (OnQuadrant == 3 OR OnQuadrant == 2)
	{
		WinMove, A, , MonQdrLft[OnMonitor, 4] + HrzCrctn, MonQdrTop[OnMonitor, 4], MonQdrWdt[OnMonitor, 4] + WdtCrctn, MonQdrHgt[OnMonitor, 4] + HgtCrctn
		Return
	}
	; Else Move Active Window to UPPER RIGHT Corner (Quadrant 3) of Current Monitor
	Else
	{
		WinMove, A, , MonQdrLft[OnMonitor, 3] + HrzCrctn, MonQdrTop[OnMonitor, 3], MonQdrWdt[OnMonitor, 3] + WdtCrctn, MonQdrHgt[OnMonitor, 3] + HgtCrctn
		Return
	}
}

; 	  HOTKEY
; **************
; Move and Resize Active Window to UPPER LEFT Corner of Current Monitor (Quadrant 1)

Rshift & up::
{
	WinGetPos, WinHrz, WinVrt, WinWdt, WinHgt, A
	GoSub, WinCurntMon
	GoSub, WinCurntQdr
	GoSub, CrctnFctr
	WinGet, WinMMax, MinMax, A
	If (WinMMax == 1)
	{
		WinRestore, A
	}
	
	WinMove, A, , MonQdrLft[OnMonitor, 1] + HrzCrctn, MonQdrTop[OnMonitor, 1], MonQdrWdt[OnMonitor, 1] + WdtCrctn, MonQdrHgt[OnMonitor, 1] + HgtCrctn
	Return
}

; 	  HOTKEY
; **************
; Move and Resize Active Window to LOWER LEFT Corner of Current Monitor (Quadrant 2)


Rshift & left::
{
	WinGetPos, WinHrz, WinVrt, WinWdt, WinHgt, A
	GoSub, WinCurntMon
	GoSub, WinCurntQdr
	GoSub, CrctnFctr
	WinGet, WinMMax, MinMax, A
	If (WinMMax == 1)
	{
		WinRestore, A
	}
	
	WinMove, A, , MonQdrLft[OnMonitor, 2] + HrzCrctn, MonQdrTop[OnMonitor, 2], MonQdrWdt[OnMonitor, 2] + WdtCrctn, MonQdrHgt[OnMonitor, 2] + HgtCrctn
	Return
}

; 	  HOTKEY
; **************
; Move and Resize Active Window to UPPER RIGHT Corner of Current Monitor (Quadrant 3)


Rshift & right::
{
	WinGetPos, WinHrz, WinVrt, WinWdt, WinHgt, A
	GoSub, WinCurntMon
	GoSub, WinCurntQdr
	GoSub, CrctnFctr
	WinGet, WinMMax, MinMax, A
	If (WinMMax == 1)
	{
		WinRestore, A
	}
	
	WinMove, A, , MonQdrLft[OnMonitor, 3] + HrzCrctn, MonQdrTop[OnMonitor, 3], MonQdrWdt[OnMonitor, 3] + WdtCrctn, MonQdrHgt[OnMonitor, 3] + HgtCrctn
	Return
}

; 	  HOTKEY
; **************
; Move and Resize Active Window to LOWER RIGHT Corner of Current Monitor (Quadrant 4)


Rshift & down::
{
	WinGetPos, WinHrz, WinVrt, WinWdt, WinHgt, A
	GoSub, WinCurntMon
	GoSub, WinCurntQdr
	GoSub, CrctnFctr
	WinGet, WinMMax, MinMax, A
	If (WinMMax == 1)
	{
		WinRestore, A
	}
	
	WinMove, A, , MonQdrLft[OnMonitor, 4] + HrzCrctn, MonQdrTop[OnMonitor, 4], MonQdrWdt[OnMonitor, 4] + WdtCrctn, MonQdrHgt[OnMonitor, 4] + HgtCrctn
	Return
}

;     User Defined Values and Programs
; ****************************************
; ***** Gosub Label *****
; Correction Factor to implement for specific Programs
CrctnFctr:
{
	WinGet, PNameWin, ProcessName, A
	If (PNameWin == "Code.exe" OR PNameWin == "Spotify.exe" OR PNameWin == "OUTLOOK.EXE" OR PNameWin == "lync.exe" OR PNameWin == "slack.exe" OR PNameWin == "WINWORD.EXE" OR PNameWin == "EXCEL.EXE" OR PNameWin == "Revu.exe")
	{
		HrzCrctn = 0
		HgtCrctn = 0
		WdtCrctn = 0
		Return
	}
	; For some reason, there is an offset when working with Explorer and Chrome
	Else
	{
		HrzCrctn = -7
		HgtCrctn = 7
		WdtCrctn = 14
		Return
	}
}

;     User Defined Values and Programs
; ****************************************
; ***** Gosub Label *****
; Exluded Programs, where the HotKeys will NOT WORK
ExcludPrgrm:
{
	WinGetClass, CNameHlfLft, A
	ExcludPrgrm := False
	; WorkerW ➔ Desktop
	If (CNameHlfLft == "WorkerW")
	{
		IgnorePrgrm := True
	}
	Return
}

; ***** Gosub Label *****
; Retrieves on which Monitor Number the Active Window is on
; Used to Move Window from Right to Left Monitors
WinCurntMon:
{
	WinGetPos, WinHrz, WinVrt, WinWdt, WinHgt, A
	WinHgtCtr := WinVrt + WinHgt / 2
	WinHrzCtr := WinHrz + WinWdt / 2

	Loop, %MonQty%
	{
		; If Center of Active Window is Located between defined Boundaries, Active Window is Located on Monitor #X
		If (WinHgtCtr >= MonTop[A_Index] AND WinHgtCtr <= MonBtm[A_Index] AND WinHrzCtr >= MonLft[A_Index] AND WinHrzCtr <= MonRgt[A_Index])
		{
			OnMonitor := A_Index
			; Once Matching Monitor Found, Stop the Search
			Break
		}
	}
	Return
}

; ***** Gosub Label *****
; Finds on which Monitor Row and Column (Matrix) the Active Window is on
; Used to Move Window from Upper to Lower Monitors
WinCurntMtx:
{
	WinGetPos, WinHrz, WinVrt, WinWdt, WinHgt, A
	WinHgtCtr := WinVrt + WinHgt / 2
	WinHrzCtr := WinHrz + WinWdt / 2
	
	Loop, %ColQty%
	{
		ColPosA_Index := A_Index
		Col_RowQtyLoop := Col_RowQty[ColPosA_Index]
		Loop, %Col_RowQtyLoop%
		{
			VrtMtxOrdrA_Index := A_Index
			; If Center of Active Window is Located between defined Boundaries, Active Window is Located on Row #X and Column #X
			If (WinHgtCtr >= MtxTop[VrtMtxOrdrA_Index, ColPosA_Index] AND WinHgtCtr <= MtxBtm[VrtMtxOrdrA_Index, ColPosA_Index] AND WinHrzCtr >= MtxLft[VrtMtxOrdrA_Index, ColPosA_Index] AND WinHrzCtr <= MtxRgt[VrtMtxOrdrA_Index, ColPosA_Index])
			{
				OnMtxRow := VrtMtxOrdrA_Index
				OnMtxCol := ColPosA_Index
				OnMtxRowQty := Col_RowQty[ColPosA_Index]
				; Once Matching Monitor Found, Stop the Search
				Break
			}
		}
	}
	Return
}

; ***** Gosub Label *****
; Retrieves in which Quadrant Number of Current Monitor the Active Window is on.
WinCurntQdr:
{
	WinGetPos, WinHrz, WinVrt, WinWdt, WinHgt, A
	; If it is not on any Quadrant, OnQuadrant = 0
	OnQuadrant := 0
	Loop, 4
	{
		; If Active Window is Located on one of the 4 Quadrants, Active Window is Located on Quadrant #X
		If (WinHrz == MonQdrLft[OnMonitor, A_Index] + HrzCrctn AND WinVrt == MonQdrTop[OnMonitor, A_Index] AND WinWdt == MonQdrWdt[OnMonitor, A_Index] + WdtCrctn AND WinHgt == MonQdrHgt[OnMonitor, A_Index] + HgtCrctn)
		{
			OnQuadrant := A_Index
			; Once Matching Quadrant is Found, Stop the Search
			Break
		}
	}
	Return
}

; *******************************************************************************
; 		Automatic Mapping of All Monitors, Move & Resize Windows  -END-
; *******************************************************************************
doubledave22
Posts: 343
Joined: 08 Jun 2019, 17:36

Re: Moving window to each quarter of screen - help with one of them too high

13 Nov 2021, 13:04

Certain windows (mostly ones with a Windows-esque Title Bar) hide the frame that was once visible on Windows 7 and below. Winmove includes these in the Width parameter but X and Y values need to be modified to place windows to line up exactly with edges. This has been discussed at length on the forums and there's no intentions to change the behaviour. You'll just have to work with it if you happen to be a perfectionist like me.

From the docs:
sysget -> 32, 33
"SM_CXSIZEFRAME, SM_CYSIZEFRAME: Thickness of the sizing border around the perimeter of a window that can be resized, in pixels. SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border. Synonymous with SM_CXFRAME and SM_CYFRAME."

This value will scale as DPI increases. You could also just use a hard coded value of 8 * (a_screendpi/96) since the default SM_CXSIZEFRAME is 8 pixels I believe. I found at 125-175% windows scaling SM_CXSIZEFRAME was a little small for my needs. You can try either and see what works.

So basically you'll need to do something like subtract SM_CXSIZEFRAME from each X value in your winmove. You may need to adjust your calculations on determining widths as well. It's a real pain but I don't see any other way around it.
Rohwedder
Posts: 7774
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Moving window to each quarter of screen - help with one of them too high

13 Nov 2021, 13:22

Just out of interest, does my script work for you?
Hotkeys: Win keys & Numpad digits, left Win key for left monitor, right Win key for right monitor.

Code: Select all

SysGet, MoN, 80
Loop,% MoN
{
	SysGet, Mo%A_Index%, MonitorWorkArea,%A_Index%
	Mo%A_Index%Width2:=.5*Mo%A_Index%Width:=Mo%A_Index%Right-Mo%A_Index%Left
	Mo%A_Index%Height2:=.5*Mo%A_Index%Height:=Mo%A_Index%Bottom-Mo%A_Index%Top
}
Return
#Numpad1::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT+%MN%Height2
,%MN%Width2+2*FR
,%MN%Height2+FB
#Numpad2::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT+%MN%Height2
,%MN%Width+2*FR
,%MN%Height2+FB
#Numpad3::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT+%MN%Height2
,%MN%Width2+2*FR
,%MN%Height2+FB
#Numpad4::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height+2*FB
#Numpad5::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width+2*FR
,%MN%Height+2*FB
#Numpad6::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height+2*FB
#Numpad7::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height2+FB
#Numpad8::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width+2*FR
,%MN%Height2+FB
#Numpad9::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height2+FB
Return
FL()
{ Global
	MN := (GetKeyState("RWin","P") And MoN > 1)?"Mo2":"Mo1"
	WinGet, MinMax, MinMax, A
	IF MinMax
	{
		WinRestore, A
		Sleep, 100
	}
	Frames("A")
	Return, FL
}
Frames(WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{	Global FL, FT, FR, FB, FW, FH ; Frame: Left, Top, Right, Bottom
	Static M := {0:"L",4:"T",8:"R",12:"B"}
	Hwnd := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText)
	VarSetCapacity(RC, 16, 0), DllCall("GetWindowRect", "Ptr", Hwnd , "Ptr", &RC)
	For k,v in M
		F%v% := NumGet(RC, k, "Int")
	DllCall("Dwmapi.dll\DwmGetWindowAttribute", "Ptr", Hwnd, "UInt", 9, "Ptr", &RC, "UInt", 16)
	For k,v in M
		F%v% -= NumGet(RC, k, "Int")
	VarSetCapacity(RC, 60, 0),NumPut(60, RC, "Uint")
	DllCall("GetWindowInfo", "Ptr", Hwnd, "Ptr", &RC)
	FW := NumGet(RC, 48, "UInt"), FH := NumGet(RC, 52, "UInt")
}
maxkill
Posts: 158
Joined: 11 Apr 2016, 13:03

Re: Moving window to each quarter of screen - help with one of them too high

13 Nov 2021, 13:57

Rohwedder wrote:
13 Nov 2021, 13:22
Just out of interest, does my script work for you?
Hotkeys: Win keys & Numpad digits, left Win key for left monitor, right Win key for right monitor.

Code: Select all

SysGet, MoN, 80
Loop,% MoN
{
	SysGet, Mo%A_Index%, MonitorWorkArea,%A_Index%
	Mo%A_Index%Width2:=.5*Mo%A_Index%Width:=Mo%A_Index%Right-Mo%A_Index%Left
	Mo%A_Index%Height2:=.5*Mo%A_Index%Height:=Mo%A_Index%Bottom-Mo%A_Index%Top
}
Return
#Numpad1::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT+%MN%Height2
,%MN%Width2+2*FR
,%MN%Height2+FB
#Numpad2::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT+%MN%Height2
,%MN%Width+2*FR
,%MN%Height2+FB
#Numpad3::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT+%MN%Height2
,%MN%Width2+2*FR
,%MN%Height2+FB
#Numpad4::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height+2*FB
#Numpad5::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width+2*FR
,%MN%Height+2*FB
#Numpad6::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height+2*FB
#Numpad7::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height2+FB
#Numpad8::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width+2*FR
,%MN%Height2+FB
#Numpad9::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height2+FB
Return
FL()
{ Global
	MN := (GetKeyState("RWin","P") And MoN > 1)?"Mo2":"Mo1"
	WinGet, MinMax, MinMax, A
	IF MinMax
	{
		WinRestore, A
		Sleep, 100
	}
	Frames("A")
	Return, FL
}
Frames(WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{	Global FL, FT, FR, FB, FW, FH ; Frame: Left, Top, Right, Bottom
	Static M := {0:"L",4:"T",8:"R",12:"B"}
	Hwnd := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText)
	VarSetCapacity(RC, 16, 0), DllCall("GetWindowRect", "Ptr", Hwnd , "Ptr", &RC)
	For k,v in M
		F%v% := NumGet(RC, k, "Int")
	DllCall("Dwmapi.dll\DwmGetWindowAttribute", "Ptr", Hwnd, "UInt", 9, "Ptr", &RC, "UInt", 16)
	For k,v in M
		F%v% -= NumGet(RC, k, "Int")
	VarSetCapacity(RC, 60, 0),NumPut(60, RC, "Uint")
	DllCall("GetWindowInfo", "Ptr", Hwnd, "Ptr", &RC)
	FW := NumGet(RC, 48, "UInt"), FH := NumGet(RC, 52, "UInt")
}

Does not work at all, moves windows to extra screeen (not main screen) and position and size random
maxkill
Posts: 158
Joined: 11 Apr 2016, 13:03

Re: Moving window to each quarter of screen - help with one of them too high

13 Nov 2021, 14:01

doubledave22 wrote:
13 Nov 2021, 13:04
Certain windows (mostly ones with a Windows-esque Title Bar) hide the frame that was once visible on Windows 7 and below. Winmove includes these in the Width parameter but X and Y values need to be modified to place windows to line up exactly with edges. This has been discussed at length on the forums and there's no intentions to change the behaviour. You'll just have to work with it if you happen to be a perfectionist like me.

From the docs:
sysget -> 32, 33
"SM_CXSIZEFRAME, SM_CYSIZEFRAME: Thickness of the sizing border around the perimeter of a window that can be resized, in pixels. SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border. Synonymous with SM_CXFRAME and SM_CYFRAME."

This value will scale as DPI increases. You could also just use a hard coded value of 8 * (a_screendpi/96) since the default SM_CXSIZEFRAME is 8 pixels I believe. I found at 125-175% windows scaling SM_CXSIZEFRAME was a little small for my needs. You can try either and see what works.

So basically you'll need to do something like subtract SM_CXSIZEFRAME from each X value in your winmove. You may need to adjust your calculations on determining widths as well. It's a real pain but I don't see any other way around it.
interesting
so how do I actually put the code in? an example would be great
2 windows need to narrow just a tad from the middle (of active screen) towards the edge belonging to quadrant (the two left ones in quadrant)
1 window need to also have it's upper edge come down towards lower screen border about 1/10th of screen height or more
doubledave22
Posts: 343
Joined: 08 Jun 2019, 17:36

Re: Moving window to each quarter of screen - help with one of them too high

13 Nov 2021, 15:55

To see if this is even your problem try a simple:

Code: Select all

^t::
sysget,Border_Size, 32
winmove, A, , 0 - Border_Size, 0
return

^r::
sysget,Border_Size, 32
wingetpos, , , WinWidth, WinHeight, A
Right_Edge := 3440 ; change to yours here
winmove, A, , Right_Edge - WinWidth + Border_Size, 0
return

If this brings the window right up to the edge where you want it in the top left (Ctrl+T) or top right (Ctrl+R) then you need to factor in these borders when building your slots.
User avatar
Kellyzkorner_NJ
Posts: 84
Joined: 20 Oct 2017, 18:33

Re: Moving window to each quarter of screen - help with one of them too high

06 Jun 2022, 13:33

ni
Rohwedder wrote:
13 Nov 2021, 13:22

Rohwedder, I love this script, works great on my main monitor but I don't have a right win key on my keyboard, how do I implement that? I tried changing RWin to RAlt, thinking that was only pointing to the second monitor part of the script but it didn't work. The RWin version, if placed on a window in second monitor does reposition it but only after moving that window to main monitor. The only better thing generally was if this could just plain maximize and center in the window. Thanks in advance.

Kelly

Just out of interest, does my script work for you?
Hotkeys: Win keys & Numpad digits, left Win key for left monitor, right Win key for right monitor.

Code: Select all

SysGet, MoN, 80
Loop,% MoN
{
	SysGet, Mo%A_Index%, MonitorWorkArea,%A_Index%
	Mo%A_Index%Width2:=.5*Mo%A_Index%Width:=Mo%A_Index%Right-Mo%A_Index%Left
	Mo%A_Index%Height2:=.5*Mo%A_Index%Height:=Mo%A_Index%Bottom-Mo%A_Index%Top
}
Return
#Numpad1::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT+%MN%Height2
,%MN%Width2+2*FR
,%MN%Height2+FB
#Numpad2::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT+%MN%Height2
,%MN%Width+2*FR
,%MN%Height2+FB
#Numpad3::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT+%MN%Height2
,%MN%Width2+2*FR
,%MN%Height2+FB
#Numpad4::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height+2*FB
#Numpad5::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width+2*FR
,%MN%Height+2*FB
#Numpad6::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height+2*FB
#Numpad7::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height2+FB
#Numpad8::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT
,%MN%Width+2*FR
,%MN%Height2+FB
#Numpad9::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT
,%MN%Width2+2*FR
,%MN%Height2+FB
Return
FL()
{ Global
	MN := (GetKeyState("RWin","P") And MoN > 1)?"Mo2":"Mo1"
	WinGet, MinMax, MinMax, A
	IF MinMax
	{
		WinRestore, A
		Sleep, 100
	}
	Frames("A")
	Return, FL
}
Frames(WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{	Global FL, FT, FR, FB, FW, FH ; Frame: Left, Top, Right, Bottom
	Static M := {0:"L",4:"T",8:"R",12:"B"}
	Hwnd := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText)
	VarSetCapacity(RC, 16, 0), DllCall("GetWindowRect", "Ptr", Hwnd , "Ptr", &RC)
	For k,v in M
		F%v% := NumGet(RC, k, "Int")
	DllCall("Dwmapi.dll\DwmGetWindowAttribute", "Ptr", Hwnd, "UInt", 9, "Ptr", &RC, "UInt", 16)
	For k,v in M
		F%v% -= NumGet(RC, k, "Int")
	VarSetCapacity(RC, 60, 0),NumPut(60, RC, "Uint")
	DllCall("GetWindowInfo", "Ptr", Hwnd, "Ptr", &RC)
	FW := NumGet(RC, 48, "UInt"), FH := NumGet(RC, 52, "UInt")
}
Rohwedder
Posts: 7774
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Moving window to each quarter of screen - help with one of them too high

07 Jun 2022, 09:22

Now two Alt keys instead of two Win keys.
Hotkeys: Alt keys & Numpad digits, left Alt key for left monitor, right Alt key for right monitor:

Code: Select all

SysGet, MoN, 80
Loop,% MoN
{
	SysGet, Mo%A_Index%, MonitorWorkArea,%A_Index%
	Mo%A_Index%Width2:=.5*Mo%A_Index%Width:=Mo%A_Index%Right-Mo%A_Index%Left
	Mo%A_Index%Height2:=.5*Mo%A_Index%Height:=Mo%A_Index%Bottom-Mo%A_Index%Top
}
Return
!Numpad1::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT+%MN%Height2,%MN%Width2+2*FR,%MN%Height2+FB
!Numpad2::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT+%MN%Height2,%MN%Width+2*FR,%MN%Height2+FB
!Numpad3::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT+%MN%Height2,%MN%Width2+2*FR,%MN%Height2+FB
!Numpad4::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT,%MN%Width2+2*FR,%MN%Height+2*FB
!Numpad5::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT,%MN%Width+2*FR,%MN%Height+2*FB
!Numpad6::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT,%MN%Width2+2*FR,%MN%Height+2*FB
!Numpad7::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT,%MN%Width2+2*FR,%MN%Height2+FB
!Numpad8::WinMove, A,,FL()+%MN%Left
,%MN%Top+FT,%MN%Width+2*FR,%MN%Height2+FB
!Numpad9::WinMove, A,,FL()+%MN%Left+%MN%Width2
,%MN%Top+FT,%MN%Width2+2*FR,%MN%Height2+FB
Return
FL()
{ Global
	MN := (GetKeyState("RAlt","P") And MoN > 1)?"Mo2":"Mo1"
	WinGet, MinMax, MinMax, A
	IF MinMax
	{
		WinRestore, A
		Sleep, 100
	}
	Frames("A")
	Return, FL
}
Frames(WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")
{	Global FL, FT, FR, FB, FW, FH ; Frame: Left, Top, Right, Bottom
	Static M := {0:"L",4:"T",8:"R",12:"B"}
	Hwnd := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText)
	VarSetCapacity(RC, 16, 0), DllCall("GetWindowRect", "Ptr", Hwnd , "Ptr", &RC)
	For k,v in M
		F%v% := NumGet(RC, k, "Int")
	DllCall("Dwmapi.dll\DwmGetWindowAttribute", "Ptr", Hwnd, "UInt", 9, "Ptr", &RC, "UInt", 16)
	For k,v in M
		F%v% -= NumGet(RC, k, "Int")
	VarSetCapacity(RC, 60, 0),NumPut(60, RC, "Uint")
	DllCall("GetWindowInfo", "Ptr", Hwnd, "Ptr", &RC)
	FW := NumGet(RC, 48, "UInt"), FH := NumGet(RC, 52, "UInt")
}
User avatar
Kellyzkorner_NJ
Posts: 84
Joined: 20 Oct 2017, 18:33

Re: Moving window to each quarter of screen - help with one of them too high

13 Mar 2023, 18:16

@Rohwedder Thanks for this, it's awesome and so are you.

Kelly

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], Marium0505, mcl and 342 guests