Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Another Multi Monitor Window Mover...


  • Please log in to reply
3 replies to this topic
That_Guy
  • Members
  • 2 posts
  • Last active: Feb 24 2011 04:28 PM
  • Joined: 22 Feb 2011
Original Post:
I didn't find this out there when looking (probably to lazy to commit to the search effort...).
(code removed)

Edit:
After fragman replied to my first post (first AutoHotkey script as well) I thought it might be worth my while to take a more in depth look at AutoHotkey's capabilities. That lead to an overhaul of the original script. Still has the same purpose, but it's lost a lot of the hard values.

Updated to add up/down and center. May be a little buggy, not 100% tested. I finally have some work to get to...

Version 2.2:
/*
Script:
	MoveWindows V - 2.2
	
Version:
	2.2 Added Up and Down
	2.1 Added Center
	2.0 Rebuild of 1.0	
	
Author:
	That_Guy

Purpose:
	Move Windows any direction between any number of monitors.

Assumptions:
	You are working with monitors set to an equal size and lined up.
	Your taskbar is at the bottom of a monitor.
	
Notes:
	Complete overhaul of V1 (aka First AutoHotkey Script)
	Designed with XP in mind.
	
Credits:
	wcoenen @ SuperUser for V1 base script.
	fragman @ AutoHotkey for SysGet hint and consequential redesign.
*/


;Windows Key + Right Arrow
#Right::
Move("Right")
Return

;Windows +  Left Arrow
#Left::
Move("Left")
Return

;Windows +  Up Arrow
#Up::
Move("Up")
Return

;Windows +  Down Arrow
#Down::
Move("Down")
Return

;Windows + c
#c::
Center()
Return

Move(direction)
{
	SysGet, monCount, MonitorCount
	WinGetPos, winX, winY, winW, winH, A
	WinGet, mm, MinMax, A
	
	;Use center of window as base for comparison.
	baseX := winx + winw / 2
	baseY := winy + winh / 2
	
	curMonNum := GetMonitorNumber(baseX, baseY, winX, winY, monCount)
	curMonWidth := GetMonitorWorkArea("width", curMonNum)
	curMonHeight := GetMonitorWorkArea("height", curMonNum)
	SysGet, curMon, Monitor, %curMonNum%

	;Check for monitor in corresponding direction.
	gosub GetXYForExists
	monitorExists := DoesMonitorExist(tmpWinX, tmpWinY, monCount)
	
	;Move to new monitor.
	If (monitorExists = "true")
	{	
		goSub GetXYForMove
		
		If (mm = 1)
		{
			WinRestore, A
			WinMove, A,, newWinX, newWinY
			WinMaximize, A
		}
		Else
		{
			WinMove, A,, newWinX, newWinY
		}
	}
	;New monitor not found, let's re-align in current monitor.
	Else If (monitorExists = "false")
	{
		monForReAlign := curMonNum
		
		gosub ReAlignX
		gosub ReAlignY
		
		WinMove, A,, newWinX, newWinY
	}
	
	Return

GetXYForExists:
	If (direction = "Right")
	{
		tmpWinX := baseX + curMonWidth
		tmpWinY := baseY
	}
	Else If (direction = "Left")
	{
		tmpWinX := baseX - curMonWidth
		tmpWinY := baseY
	}
	Else If (direction = "Up")
	{
		tmpWinX := baseX
		tmpWinY := baseY - curMonHeight
	}
	Else If (direction = "Down")
	{
		tmpWinX := baseX
		tmpWinY := baseY + curMonHeight
	}
	Return
	
GetXYForMove:
	/*
	Maximized winows are -4 x + -4 y of their current monitor.
	Acount for this here.
	*/
	If (mm = 1)
	{
		winX := winX + 4
		winY := winY + 4
	}
	gosub SetReAlignMon
	gosub ReAlignX
	gosub ReAlignY
	
	Return

SetReAlignMon:
	If (direction = "Right")
	{
		newBaseX := baseX + curMonWidth
		newBaseY := baseY
		monForReAlign := GetMonitorNumber(newBaseX, newBaseY, null, null, monCount)
	}
	Else If (direction = "Left")
	{
		newBaseX := baseX - curMonWidth
		newBaseY := baseY
		monForReAlign := GetMonitorNumber(newBaseX, newBaseY, null, null, monCount)
	}
	Else If (direction = "Up")
	{
		newBaseX := baseX 
		newBaseY := baseY - curMonHeight
		monForReAlign := GetMonitorNumber(newBaseX, newBaseY, null, null, monCount)
	}
	Else If (direction = "Down")
	{
		newBaseX := baseX
		newBaseY := baseY + curMonHeight
		monForReAlign := GetMonitorNumber(newBaseX, newBaseY, null, null, monCount)
	}
	Return
	
;ReAlignX and ReAlignY work to keep the window in a monitor.
ReAlignX:
	{
		If (direction = "Right")
		{
			SysGet, newMon, Monitor, %monForReAlign%
			newMonWidth := GetMonitorWorkArea("width", monForReAlign)
			;adjust by setup, not fully tested.
			padding := 0 ;curMonRight - curMonLeft - newMonWidth
			
			If ((winX + winW + curMonWidth) > newMonRight)
			{
				newWinX := (newMonRight - winW) + padding 
			}
			Else If ((winX + curMonWidth) < newMonLeft)
			{
				newWinX := newMonLeft + padding 
			}
			Else
			{
				newWinX := (winX + newMonWidth) + padding 
			}
		}
		Else If (direction = "Left")
		{
			SysGet, newMon, Monitor, %monForReAlign%
			newMonWidth := GetMonitorWorkArea("width", monForReAlign)
			;adjust by setup, not fully tested.
			padding := 0 ;curMonRight - curMonLeft - newMonWidth
			
			If ((winX - curMonWidth) < newMonLeft)
			{
				newWinX := newMonLeft - padding
			}
			Else If ((winX + winW - curMonWidth) > newMonRight)
			{
				newWinX := (newMonRight - winW) - padding
			}
			Else
			{
				newWinX := (winX - newMonWidth) - padding
			}
		}
		Else If (direction = "Up" or direction = "Down")
		{
			SysGet, newMon, Monitor, %monForReAlign%
			newMonWidth := GetMonitorWorkArea("width", monForReAlign)
		
			If (winX < newMonLeft)
			{
				newWinX := newMonLeft
			}
			Else If ((winX + winW) > (newMonWidth + newMonLeft))
			{
				newWinX := (newMonWidth + newMonLeft) - winW
			}
			Else
			{
				newWinX := winX
			}
		}
		Return
	}
	
ReAlignY:
	{
		If(direction = "Right" or direction = "Left")
		{
			SysGet, newMon, Monitor, %monForReAlign%
			newMonHeight := GetMonitorWorkArea("height", monForReAlign)
			
			If (winY < newMonTop)
			{
				newWinY := newMonTop
			}
			Else If ((winY + winH) > (newMonHeight + newMonTop))
			{
				newWinY := (newMonHeight + newMonTop) - winH
			}
			Else
			{
				newWinY := winY
			}
		}
		Else If (Direction = "Up")
		{
			SysGet, newMon, Monitor, %monForReAlign%
			newMonHeight := GetMonitorWorkArea("height", monForReAlign)
			;adjust by setup, not fully tested.
			padding := 0 ;curMonBottom - curMonTop - newMonHeight

			If ((winY - curMonHeight) < newMonTop)
			{
				newWinY := newMonTop + padding
			}
			Else If ((winY + winH - curMonHeight) > (newMonTop + newMonHeight))
			{
				newWinY := ((newMonTop + newMonHeight) - winH) - padding
			}
			Else
			{
				newWinY := (winY - newMonHeight) - padding
			}
		}
		Else If (Direction = "Down")
		{
			SysGet, newMon, Monitor, %monForReAlign%
			newMonHeight := GetMonitorWorkArea("height", monForReAlign)
			padding := curMonBottom - curMonTop - newMonHeight

			If ((winY + winH + curMonHeight) > newMonBottom)
			{
				newWinY := (newMonBottom - winH) - padding
			}
			Else If ((winY + curMonHeight) < newMonTop)
			{
				newWinY := newMonTop + padding
			}
			Else
			{
				newWinY := (winY + newMonHeight)  + padding
			}
		}
		Return
	}
}

Center()
{
	WinGet, mm, MinMax, A
	If (mm <> 1)
	{
		SysGet, monCount, MonitorCount
		WinGetPos, winX, winY, winW, winH, A
		
		;Use center of window as base for comparison.
		baseX := winx + winw / 2
		baseY := winy + winh / 2
		
		curMonNum := GetMonitorNumber(baseX, baseY, winX, winY, monCount)
		curMonWidth := GetMonitorWorkArea("width", curMonNum)
		curMonHeight := GetMonitorWorkArea("height", curMonNum)
		
		SysGet, curMon, Monitor, %curMonNum%
		
		newWinX := (curMonWidth - winW)/2 + curMonLeft
		newWinY := (curMonHeight - winH)/2 + curMonTop
		
		WinMove, A,, newWinX, newWinY
	}
	Return
}
	
GetMonitorNumber(baseX, baseY, winX, winY, monCount)
{
	i := 0
	monFound := 0

	Loop %monCount%
    {   
		i := i+1
		SysGet, tmpMon, Monitor, %i%
        if (baseX >= tmpMonLeft and baseX <= tmpMonRight and baseY >= tmpMonTop and baseY <= tmpMonBottom)
		{
            monFound := i
		}
    }
	;If we couldn't find a monitor through the assumed x/y, lets check by window x/y.
	If (monFound = 0)
	{
		{
			i := 0
			Loop %monCount%
			{   
				i := i+1
				SysGet, tmpMon, Monitor, %i%
				if (winX >= tmpMonLeft and winX <= tmpMonRight and winY >= tmpMonTop and winY <= tmpMonBottom)
				{
					monFound := i
				}
			}
		}
	}
	Return monFound
}

GetMonitorWorkArea(measurement, monToGet)
{
    SysGet, tmpMon, MonitorWorkArea, %monToGet%
	If (measurement = "width")
	{
		tmpMonWidth  := tmpMonRight - tmpMonLeft
		Return tmpMonWidth
	}
	Else If (measurement = "height")
	{
		tmpMonHeight := tmpMonBottom - tmpMonTop
		Return tmpMonHeight
	}
}

DoesMonitorExist(newWinX, newWinY, monCount)
{
	i := 0
	monitorFound = false

	Loop %monCount%
    {   
		i := i+1
		SysGet, tmpMon, Monitor, %i%
        if (newWinX >= tmpMonLeft and newWinX <= tmpMonRight and newWinY >= tmpMonTop and newWinY <= tmpMonBottom)
		{
            monitorFound = true
			break
		}
    }
	Return monitorFound
}

Return


fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
It is possible to get the locations of the monitors using SysGet.

octal
  • Members
  • 102 posts
  • Last active: Jul 24 2015 03:14 AM
  • Joined: 21 Feb 2011
Heres a window manager for multiple monitors I use at work.

/*

Octal's Multi-Monitor Script.

I made this script to model the window management in windows 7 at work when I have to use windows xp.

Made for a dual-monitor setup. 

Win+1:		Move active window to first half of the first screen.
Win+2:		Move active window to second half of the first screen.
Win+3:		Move active window to first half of the second screen.
Win+4:		Move active window to second half of the second screen.

Win+q:		Move active window to fill the first screen.
Win+w:		Move active window to fill the second screen.

Win+left:	Move active window to the left half of the current monitor.
Win+right:	Move active window to the right half of the current monitor.
Win+up:		Move active window to fill the current monitor.
Win+`:		Move active window to fill the current monitor.



*/




ww:=a_screenwidth/2
ww2:=(a_screenwidth/2)+a_screenwidth


#1::
winmove,A,, 0,0,%ww%, %A_ScreenHeight%
return


#2::
winmove,A,, %ww%,0,%ww%, %A_ScreenHeight%
return

#3::
winmove,A,, %a_screenwidth%,0,%ww%, %A_ScreenHeight%
return

#4::
winmove,A,, %ww2%,0,%ww%, %A_ScreenHeight%
return

#`::
#up::
WinGetPos , xx, , , , A
if xx<%a_screenwidth%
{
winmove,A,, 0,0,%a_screenwidth%, %A_ScreenHeight%
}
else
{
winmove,A,, %a_screenwidth%,0,%a_screenwidth%, %A_ScreenHeight%
}
return


#q::

winmove,A,, 0,0,%a_screenwidth%, %A_ScreenHeight%
return

#w::

winmove,A,, %a_screenwidth%,0,%a_screenwidth%, %A_ScreenHeight%
return




#left::
WinGetPos , xx, , , , A
if xx<%a_screenwidth%
{
winmove,A,, 0,0,%ww%, %A_ScreenHeight%
}
else
{
winmove,A,, %a_screenwidth%,0,%ww%, %A_ScreenHeight%
}
return


#right::
WinGetPos , xx, , , , A
if xx<%a_screenwidth%
{
winmove,A,, %ww%,0,%ww%, %A_ScreenHeight%
}
else
{
winmove,A,, %ww2%,0,%ww%, %A_ScreenHeight%
}
return


That_Guy
  • Members
  • 2 posts
  • Last active: Feb 24 2011 04:28 PM
  • Joined: 22 Feb 2011
Updated Original post/script following some suggestions. It ain't perfect but I can't put any more time into it, you know, work and all that. Thanks for bearing with me.