APP_EXE = Array("cmd.exe", "calc.exe") 'name of the application's executable
DEST_MON = Array(3, 0) 'number of the monitor the application should get moved to, zero to move it to the monitor with the mouse
ONLY_MOVE_ONCE = Array(True, False) 'if True, each window only gets moved once, otherwise windows get moved everytime they're on a monitor other than DEST_MON. enter only a single value if the same setting should be used for all applications
Const RESIZE_TO_FIT = True 'if True, the application window will only get resized if necessary, otherwise it will get resized proportionally
Const INTERVAL = 3 'number of seconds the script waits before enumerating running applications again

Set sys = CreateObject("UltraMon.System")
Set wnd = CreateObject("UltraMon.Window")
wndChangeFlags = 2
If RESIZE_TO_FIT = True Then wndChangeFlags = wndChangeFlags + 1

'create the two maps used to store positioned windows if ONLY_MOVE_ONCE is true
Set arrAdd = CreateObject("Scripting.Dictionary")
Set arrLookup = CreateObject("Scripting.Dictionary")

getMouseMon = False
For i = 0 To UBound(DEST_MON)
	If DEST_MON(i) = 0 Then
		getMouseMon = True
		Exit For
	End If
Next

onlyMoveOnceEnabled = False
For i = 0 To UBound(ONLY_MOVE_ONCE)
	If ONLY_MOVE_ONCE(i) = True Then
		onlyMoveOnceEnabled = True
		Exit For
	End If
Next

Do While True
	monWithMouse = 0
	If getMouseMon = True Then
		'get the monitor the mouse is on
		mouseX = sys.CursorPosX
		mouseY = sys.CursorPosY
		For Each mon In sys.Monitors
			If mon.Enabled = True Then
				If mouseX >= mon.Left And mouseX <= mon.Left + mon.Width And mouseY >= mon.Top And mouseY <= mon.Top + mon.Height Then
					monWithMouse = mon.ID
					Exit For
				End If
			End If
		Next
	End If

	'enumerate all application windows
	For Each w In wnd.GetAppWindows(false)
		'handle failure to get the exe name in case the window no longer exists
		exe = ""
		On Error Resume Next
		exe = w.ProcessExe
		On Error Goto 0
		pos = InStrRev(exe, "\")
		If pos > 0 Then
			For i = 0 To UBound(APP_EXE)
				If StrComp(Mid(exe, pos + 1), APP_EXE(i), 1) = 0 Then
					'this is one of ours
					move = True
					onlyMoveOnce = ONLY_MOVE_ONCE(0)
					If UBound(ONLY_MOVE_ONCE) > 0 Then onlyMoveOnce = ONLY_MOVE_ONCE(i)

					If onlyMoveOnce = True Then
						If arrLookup.Exists(w.HWnd) = True Then move = False
						arrAdd.Add w.HWnd, 0
					End If

					If move = True Then
						monDest = DEST_MON(i)
						If monDest = 0 Then monDest = monWithMouse

						If w.Monitor <> monDest Then
							w.Monitor = monDest
							w.ApplyChanges wndChangeFlags
						End If
					End If
				End If
			Next
		End If
	Next

	If onlyMoveOnceEnabled = True Then
		'swap maps, then clear arrAdd. this way we don't have entries for windows which no longer exist
		Set temp = arrLookup
		Set arrLookup = arrAdd
		Set arrAdd = temp
		Set temp = Nothing
		arrAdd.RemoveAll
	End If

	WScript.Sleep INTERVAL * 1000
Loop

