WinMove not moving windows in Windows 10

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
the1corrupted
Posts: 36
Joined: 25 Jan 2014, 23:01

WinMove not moving windows in Windows 10

12 Feb 2019, 20:41

[Moderator's note: Topic moved from Bug Reports.]

Hello, not sure if it's a known bug or not, but I have had issues with the WinMove command/function in Windows 10.

So to get around that, I had to directly call Microsoft's dll for a script to work seamlessly between Windows 7 and Windows 10. Nevermind that the window bounding coordinates are somehow off in Windows 10.

I borrowed a part of my function from someone else but made a few changes so I can use it with my particular script.

I wanted to see what monitor a window was displayed on, and if it was not displayed on that panel, I wanted to move the window automatically.

Microsoft DLL Reference: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-movewindow

Original post that led me down this path: https://autohotkey.com/board/topic/69464-how-to-determine-a-window-is-in-which-monitor/

So when I try WinMove, nothing occurs when I try this:

Code: Select all

WinMove, ahk_id <window_hwnd>, someX, someY
I haven't tried by title because I don't use window title in any reliable way. As the window is a web browser, the title can change. So I track it by window ID.

This is the raw function I came up with to actually move a window after determining which monitor it is on.

Code: Select all

Debug_Track(msg, useFile = true) {
	if (useFile) {
		FileAppend, `r`n%msg%, %A_WorkingDir%\debug.txt
		return
	}
	if (debug) {
		FileAppend, `r`n--->>>`tERROR MSG:`t%msg%, %A_WorkingDir%\debug.txt
	}
	MsgBox, 48, ERROR!!, %msg%
	return
}
GetMonitorFromHwnd(windowHandle, moveWinToScreen = false) {
	if (debug) {
		Debug_Track("FUNCTION CALL: " . A_ThisFunc . "('" . windowHandle . "', " . moveWinToScreen . ")")
	}
	if (!RegExMatch(windowHandle, "^0x[0-9a-f][0-9a-f][0-9a-f]") || !WinExist("ahk_id" . windowHandle)) {
		return false
	}
	SysGet, mCount, MonitorCount
	if (mCount = 1) {
		return 1
	}
	VarSetCapacity(monitorInfo, 40)
	NumPut(40, monitorInfo)
	isWin10 := (SubStr(A_OSVersion, 1, 2) = 10)
	if !(monitorHandle := DllCall("User32.dll\MonitorFromWindow", "uint", windowHandle, "uint", "MONITOR_DEFAULTTONEAREST")) {
		return false
	}
	if (isWin10) {
		if !(monitorInfo := DllCall("User32.dll\GetMonitorInfoA", "uint", monitorHandle, "uint", &monitorInfo)) {
			return false
		}
	} else {
		if !(monitorInfo := DllCall("User32.dll\GetMonitorInfo", "uint", monitorHandle, "uint", &monitorInfo)) {
			return false
		}
	}
	monitorLeft   := NumGet(monitorInfo,  4, "Int")
	monitorTop    := NumGet(monitorInfo,  8, "Int")
	monitorRight  := NumGet(monitorInfo, 12, "Int")
	monitorBottom := NumGet(monitorInfo, 16, "Int")
	workLeft      := NumGet(monitorInfo, 20, "Int")
	workTop       := NumGet(monitorInfo, 24, "Int")
	workRight     := NumGet(monitorInfo, 28, "Int")
	workBottom    := NumGet(monitorInfo, 32, "Int")
	isPrimary     := NumGet(monitorInfo, 36, "Int") & 1
	i := 1
	returnVal := false
	moveToTop := false
	moveToLeft := false
	while (i <= mCount) {
		SysGet, tempMon, Monitor, %i%
		if ((monitorLeft = tempMonLeft) && (monitorTop = tempMonTop) && (monitorRight = tempMonRight) && (monitorBottom = tempMonBottom)) {
			returnVal := i
			break
		}
		i++
	}
	if (debug) {
		Debug_Track("`tDetected at monitor: " . returnVal)
	}
	if (returnVal && moveWinToScreen > 0 && moveWinToScreen <= mCount) {
		SysGet, moveTo, Monitor, %moveWinToScreen%
		moveToTop += 1
		moveToLeft += 1
		if (debug) {
			Debug_Track("`tMove Window: " . windowHandle . " to monitor: " . moveWinToScreen)
			Debug_Track("`tTop: " . moveToTop . " Left: " . moveToLeft)
		}
		SetTitleMatchMode, 3
		WinGetPos, posX, posY, moveWidth, moveHeight, ahk_id %windowHandle%
		DllCall("User32.dll\MoveWindow", "uint", windowHandle, "int", moveToLeft, "int", moveToTop, "int", moveWidth, "int", moveHeight, "int", 1)
	}
	return returnVal
}
Automating work is twice as much fun
gregster
Posts: 9034
Joined: 30 Sep 2013, 06:48

Re: WinMove not moving windows in Windows 10

12 Feb 2019, 21:12

the1corrupted wrote:
12 Feb 2019, 20:41
So when I try WinMove, nothing occurs when I try this:

Code: Select all

WinMove, ahk_id <window_hwnd>, someX, someY
I am not surprised, if you really tried it like this. This is not the syntax of WinMove...

WinMove - Syntax Usage.png
WinMove - Syntax Usage.png (13.8 KiB) Viewed 5364 times
Your someX coordinate gets interpreted as WinText (and the window in question won't have this text, I imagine)
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: WinMove not moving windows in Windows 10

15 Feb 2019, 10:07

first, AHK's WinMove command simply wraps the microsoft MoveWindow api anyway. That's the whole point of AHK, to use 1 line of code instead of 20. You can see that here at line 2178:
https://github.com/Lexikos/AutoHotkey_L/blob/65cbbe1f16a4d6163429d28ec7190a01990cb227/source/script2.cpp#L2178

@gregster is right, your syntax is wrong in your example code. That's likely why its failing. You need to leave an empty parameter for the WinText

And, as far as the bounding rect being different in Win10, that's not true either. The problem you're seeing is, in Win10, the window borders (that you would normally drag to resize a window in earlier versions of Windows) are now invisible. They are still there. But they are transparent so you can't see them. Therefore the window is actually bigger than what you visibly see. More info:
https://www.autohotkey.com/boards/viewtopic.php?t=17955


Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Araphen, Bing [Bot], Google [Bot], Peiya, ShatterCoder and 306 guests