convert coordinates between Client/Screen/Window modes

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

convert coordinates between Client/Screen/Window modes

17 Oct 2017, 17:51

I have produced 6 functions to convert an (X,Y) pair between different coordinate modes (Client / Screen / Window). Note for XYWH coordinates, X/Y changes but W/H remains the same.

Simpler:
JEE_ClientToScreen/JEE_ScreenToClient
JEE_ScreenToWindow/JEE_WindowToScreen

Slightly longer (client to screen to window, and window to screen to client):
JEE_ClientToWindow/JEE_WindowToClient

I have two scripts, one which recreates the generation of the A_CaretX and A_CaretY values, the other which test converting between coordinate modes.

Code: Select all

;note: this is based on the AHK source code, another approach is to use GetCaretPos
q:: ;recreate A_CaretX and A_CaretY built-in variables
WinGet, hWnd, ID, A
VarSetCapacity(GUITHREADINFO, A_PtrSize=8?72:48, 0)
NumPut(A_PtrSize=8?72:48, &GUITHREADINFO, 0, "UInt") ;cbSize
vTID := DllCall("user32\GetWindowThreadProcessId", Ptr,hWnd, UIntP,0, UInt)
DllCall("user32\GetGUIThreadInfo", UInt,vTID, Ptr,&GUITHREADINFO)
hWndC := NumGet(&GUITHREADINFO, A_PtrSize=8?48:28, "Ptr") ;hwndCaret
vPosX := NumGet(&GUITHREADINFO, A_PtrSize=8?56:32, "Int") ;rcCaret ;x
vPosY := NumGet(&GUITHREADINFO, A_PtrSize=8?60:36, "Int") ;rcCaret ;y
JEE_ClientToScreen(hWndC, vPosX, vPosY, vPosXS, vPosYS)
JEE_ClientToScreen(hWnd, 0, 0, vOgnXC, vOgnYC)
JEE_WindowToScreen(hWnd, 0, 0, vOgnXW, vOgnYW)
vPosXC := vPosXS - vOgnXC
vPosYC := vPosYS - vOgnYC
vPosXW := vPosXS - vOgnXW
vPosYW := vPosYS - vOgnYW
vOutput1 := Format("{} {}`r`n{} {}`r`n{} {}", vPosXC, vPosYC, vPosXS, vPosYS, vPosXW, vPosYW)

vOutput2 := ""
vList := "Client,Screen,Window"
Loop, Parse, vList, % ","
{
	CoordMode, Caret, % A_LoopField
	Sleep, 1
	vOutput2 .= (A_Index=1?"":"`r`n") A_CaretX " " A_CaretY
}
MsgBox, % (vOutput1 = vOutput2) "`r`n`r`n" vOutput1 "`r`n`r`n" vOutput2
return

;==================================================

w:: ;test converting between coordinate modes
WinGet, hWnd, ID, A
vOutput := ""
vList := "Client,Screen,Window"
Loop, Parse, vList, % ","
{
	CoordMode, Caret, % A_LoopField
	vChar := SubStr(A_LoopField, 1, 1)
	Sleep, 1
	vPosX%vChar% := A_CaretX
	vPosY%vChar% := A_CaretY
	vOutput .= (A_Index=1?"":"`r`n") vPosX%vChar% " " vPosY%vChar%
}
MsgBox, % vOutput

oArray := {C:"Client",S:"Screen",W:"Window"}
vList := "CS,CW,SC,SW,WC,WS"
Loop, Parse, vList, % ","
{
	vTemp1 := SubStr(A_LoopField, 1, 1)
	vTemp2 := SubStr(A_LoopField, 2, 1)
	vFunc := "JEE_" oArray[vTemp1] "To" oArray[vTemp2]
	%vFunc%(hWnd, vPosX%vTemp1%, vPosY%vTemp1%, vPosX, vPosY)
	vIsMatch := (vPosX%vTemp2% " " vPosY%vTemp2% = vPosX " " vPosY)
	MsgBox, % A_LoopField "`r`n" vIsMatch "`r`n" Format("{} {}`r`n{} {}", vPosX%vTemp2%, vPosY%vTemp2%, vPosX, vPosY)
}
return

;==================================================

JEE_ClientToScreen(hWnd, vPosX, vPosY, ByRef vPosX2, ByRef vPosY2)
{
	VarSetCapacity(POINT, 8)
	NumPut(vPosX, &POINT, 0, "Int")
	NumPut(vPosY, &POINT, 4, "Int")
	DllCall("user32\ClientToScreen", Ptr,hWnd, Ptr,&POINT)
	vPosX2 := NumGet(&POINT, 0, "Int")
	vPosY2 := NumGet(&POINT, 4, "Int")
}

;==================================================

JEE_ScreenToClient(hWnd, vPosX, vPosY, ByRef vPosX2, ByRef vPosY2)
{
	VarSetCapacity(POINT, 8)
	NumPut(vPosX, &POINT, 0, "Int")
	NumPut(vPosY, &POINT, 4, "Int")
	DllCall("user32\ScreenToClient", Ptr,hWnd, Ptr,&POINT)
	vPosX2 := NumGet(&POINT, 0, "Int")
	vPosY2 := NumGet(&POINT, 4, "Int")
}

;==================================================

JEE_ScreenToWindow(hWnd, vPosX, vPosY, ByRef vPosX2, ByRef vPosY2)
{
	VarSetCapacity(RECT, 16)
	DllCall("user32\GetWindowRect", Ptr,hWnd, Ptr,&RECT)
	vWinX := NumGet(&RECT, 0, "Int")
	vWinY := NumGet(&RECT, 4, "Int")
	vPosX2 := vPosX - vWinX
	vPosY2 := vPosY - vWinY
}

;==================================================

JEE_WindowToScreen(hWnd, vPosX, vPosY, ByRef vPosX2, ByRef vPosY2)
{
	VarSetCapacity(RECT, 16, 0)
	DllCall("user32\GetWindowRect", Ptr,hWnd, Ptr,&RECT)
	vWinX := NumGet(&RECT, 0, "Int")
	vWinY := NumGet(&RECT, 4, "Int")
	vPosX2 := vPosX + vWinX
	vPosY2 := vPosY + vWinY
}

;==================================================

JEE_ClientToWindow(hWnd, vPosX, vPosY, ByRef vPosX2, ByRef vPosY2)
{
	VarSetCapacity(POINT, 8)
	NumPut(vPosX, &POINT, 0, "Int")
	NumPut(vPosY, &POINT, 4, "Int")
	DllCall("user32\ClientToScreen", Ptr,hWnd, Ptr,&POINT)
	vPosX2 := NumGet(&POINT, 0, "Int")
	vPosY2 := NumGet(&POINT, 4, "Int")

	VarSetCapacity(RECT, 16)
	DllCall("user32\GetWindowRect", Ptr,hWnd, Ptr,&RECT)
	vWinX := NumGet(&RECT, 0, "Int")
	vWinY := NumGet(&RECT, 4, "Int")
	vPosX2 -= vWinX
	vPosY2 -= vWinY
}

;==================================================

JEE_WindowToClient(hWnd, vPosX, vPosY, ByRef vPosX2, ByRef vPosY2)
{
	VarSetCapacity(RECT, 16, 0)
	DllCall("user32\GetWindowRect", Ptr,hWnd, Ptr,&RECT)
	vWinX := NumGet(&RECT, 0, "Int")
	vWinY := NumGet(&RECT, 4, "Int")

	VarSetCapacity(POINT, 8)
	NumPut(vPosX+vWinX, &POINT, 0, "Int")
	NumPut(vPosY+vWinY, &POINT, 4, "Int")
	DllCall("user32\ScreenToClient", Ptr,hWnd, Ptr,&POINT)
	vPosX2 := NumGet(&POINT, 0, "Int")
	vPosY2 := NumGet(&POINT, 4, "Int")
}

;==================================================
==================================================

[EDIT:] Here are two additional functions: JEE_WinGetPosClient and JEE_CtlGetPosClient.
[EDIT:] See lower down also for: JEE_CaretGetPos.

Code: Select all

q:: ;window - get position, client area
WinGet, hWnd, ID, A
;e.g. get position
WinGetPos, vWinX, vWinY, vWinW, vWinH, % "ahk_id " hWnd
;e.g. get position client area
JEE_WinGetPosClient(hWnd, vWinX2, vWinY2, vWinW2, vWinH2)
vCoords1 := Format("x{} y{} w{} h{}", vWinX, vWinY, vWinW, vWinH)
vCoords2 := Format("x{} y{} w{} h{}", vWinX2, vWinY2, vWinW2, vWinH2)
MsgBox, % vCoords1 "`r`n" vCoords2
return

JEE_WinGetPosClient(hWnd, ByRef vWinX, ByRef vWinY, ByRef vWinW, ByRef vWinH)
{
	VarSetCapacity(RECT, 16, 0)
	DllCall("user32\GetClientRect", Ptr,hWnd, Ptr,&RECT)
	DllCall("user32\ClientToScreen", Ptr,hWnd, Ptr,&RECT)
	vWinX := NumGet(&RECT, 0, "Int"), vWinY := NumGet(&RECT, 4, "Int")
	vWinW := NumGet(&RECT, 8, "Int"), vWinH := NumGet(&RECT, 12, "Int")
}

JEE_WinGetPosClientAlt(hWnd, ByRef vWinX, ByRef vWinY, ByRef vWinW, ByRef vWinH)
{
	VarSetCapacity(RECT, 16, 0)
	DllCall("user32\GetClientRect", Ptr,hWnd, Ptr,&RECT)
	DllCall("user32\MapWindowPoints", Ptr,hWnd, Ptr,0, Ptr,&RECT, UInt,1)
	vWinX := NumGet(&RECT, 0, "Int"), vWinY := NumGet(&RECT, 4, "Int")
	vWinW := NumGet(&RECT, 8, "Int"), vWinH := NumGet(&RECT, 12, "Int")
}

Code: Select all

q:: ;control - get position, client area
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
;e.g. get position relative to window
ControlGetPos, vCtlX, vCtlY, vCtlW, vCtlH,, % "ahk_id " hCtl
;e.g. get position relative to window's client area
JEE_CtlGetPosClient(hWnd, hCtl, vCtlX2, vCtlY2, vCtlW2, vCtlH2)
vCoords1 := Format("x{} y{} w{} h{}", vCtlX, vCtlY, vCtlW, vCtlH)
vCoords2 := Format("x{} y{} w{} h{}", vCtlX2, vCtlY2, vCtlW2, vCtlH2)
MsgBox, % vCoords1 "`r`n" vCoords2
return

;hWnd is the parent window hWnd, hCtl is the child control hWnd
JEE_CtlGetPosClient(hWnd, hCtl, ByRef vCtlX, ByRef vCtlY, ByRef vCtlW, ByRef vCtlH)
{
	VarSetCapacity(RECT, 16, 0)
	DllCall("user32\GetWindowRect", Ptr,hCtl, Ptr,&RECT)
	DllCall("user32\MapWindowPoints", Ptr,0, Ptr,hWnd, Ptr,&RECT, UInt,2)
	vCtlX := NumGet(&RECT, 0, "Int"), vCtlY := NumGet(&RECT, 4, "Int")
	vCtlW := NumGet(&RECT, 8, "Int")-vCtlX, vCtlH := NumGet(&RECT, 12, "Int")-vCtlY
}
Last edited by jeeswg on 20 Nov 2018, 05:51, edited 4 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: convert coordinates between Client/Screen/Window modes

19 Oct 2017, 16:42

Hello jeeswg, thanks for sharing. :thumbup:
Slightly longer (client to screen to window, and window to screen to client):
JEE_ClientToWindow/JEE_WindowToClient
Slightly shorter,

Code: Select all

JEE_ClientToWindow(...){
	JEE_ClientToScreen(...)
	JEE_ScreenToWindow(...)	
}
JEE_WindowToClient(...){
	JEE_WindowToScreen(...)
	JEE_ScreenToClient(...)
}
:angel:
I have two scripts, one which recreates the generation of the A_CaretX and A_CaretY values
Dear :xmas: , I wish you had made it a (v2) function, GetCaretPos(outX, outY) where outX, outY adheres to A_CoordModeCaret.
Thanks for your efforts, cheers ☕

Edit: Why not use wingetpos() instead of dllcall(GetWindowRect)?
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: convert coordinates between Client/Screen/Window modes

19 Oct 2017, 16:56

Yes, a wise angel, I had realised that I could write the functions as two function calls. I always write functions as stand-alone or pretty much stand-alone where possible, for a quick copy-and-paste without/with few dependencies.

Haha if people start making Christmas requests for functions I won't have time for anything else this year. I did anticipate that you might request this, or wish to request this, based on that other thread, I'll give it a go. Btw would such a function be very useful to you?

I'm quite glad to have written these functions now, because they were confusing me for a long time.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: convert coordinates between Client/Screen/Window modes

19 Oct 2017, 17:16

for a quick copy-and-paste without/with few dependencies.
That is reasonable.
Btw would such a function be very useful to you?
Not really at moment. However, you made most of the work already, so it slightly bothers me, that once I need it, there is work waiting ;) . But please, no hurry or presure in the matter, not for me at least.
I'm quite glad to have written these functions now
They are very useful functions, I have made at least some of them when needed, I don't think I collected them though. I will refer back here when needed :thumbup:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: convert coordinates between Client/Screen/Window modes

19 Oct 2017, 17:25

Oh you don't need them that much, next year then hehe.

Yes when you mentioned it before I envisaged a function that would get the caret position according to A_CoordModeCaret, but that could also return the raw numbers retrieved from GUITHREADINFO if specified by the optional mode parameter. Or indeed that you could manually specify Caret/Screen/Window, bypassing AHK's variable.

A-ha, here's the original thread:

CoordMode needs a pause to update - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 14&t=38467

Code: Select all

q:: ;caret - get position
vList := "Client,Screen,Window"
vOutput := ""
JEE_CaretGetPos(vPosX, vPosY, "")
vOutput .= vPosX " " vPosY "`r`n`r`n"
Loop, Parse, vList, % ","
{
	CoordMode, Caret, % A_LoopField
	Sleep, 1
	JEE_CaretGetPos(vPosX, vPosY)
	vOutput .= vPosX " " vPosY "`r`n" A_CaretX " " A_CaretY "`r`n`r`n"
}
MsgBox, % SubStr(vOutput, 1, -4)
return

;==================================================

;vMode: a: AutoHotkey (based on A_CoordModeCaret)
;vMode: c: relative to window client area
;vMode: r (or blank): raw, relative to control (or window) client area
;vMode: s: relative to screen
;vMode: w: relative to window
JEE_CaretGetPos(ByRef vPosX, ByRef vPosY, vMode:="a")
{
	WinGet, hWnd, ID, A
	VarSetCapacity(GUITHREADINFO, A_PtrSize=8?72:48, 0)
	NumPut(A_PtrSize=8?72:48, &GUITHREADINFO, 0, "UInt") ;cbSize
	vTID := DllCall("user32\GetWindowThreadProcessId", Ptr,hWnd, UIntP,0, UInt)
	DllCall("user32\GetGUIThreadInfo", UInt,vTID, Ptr,&GUITHREADINFO)
	hWndC := NumGet(&GUITHREADINFO, A_PtrSize=8?48:28, "Ptr") ;hwndCaret
	vPosX := NumGet(&GUITHREADINFO, A_PtrSize=8?56:32, "Int") ;rcCaret ;x
	vPosY := NumGet(&GUITHREADINFO, A_PtrSize=8?60:36, "Int") ;rcCaret ;y
	vMode := SubStr(vMode, 1, 1)
	if (vMode = "") || (vMode = "r") ;raw
		return
	else if (vMode = "a") ;AutoHotkey
		vMode := SubStr(A_CoordModeCaret, 1, 1)
	JEE_ClientToScreen(hWndC, vPosX, vPosY, vPosX, vPosY)
	if (vMode = "s") ;screen
		return
	else if (vMode = "c") ;client
		JEE_ClientToScreen(hWnd, 0, 0, vOgnX, vOgnY)
	else if (vMode = "w") ;window
		JEE_WindowToScreen(hWnd, 0, 0, vOgnX, vOgnY)
	vPosX -= vOgnX, vPosY -= vOgnY
}
Last edited by jeeswg on 06 Nov 2017, 13:50, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: convert coordinates between Client/Screen/Window modes

19 Oct 2017, 17:31

That was quick :lol:

Code: Select all

vMode:="AHK"
Excellent idea. :thumbup:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: convert coordinates between Client/Screen/Window modes

13 Feb 2018, 15:46

A slight variant to allow specifying an hWnd. Based on comments by Drugwash here:
commands as functions (AHK v2 functions for AHK v1) - Page 2 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 60#p200260

Code: Select all

;vMode: a: AutoHotkey (based on A_CoordModeCaret)
;vMode: c: relative to window client area
;vMode: r (or blank): raw, relative to control (or window) client area
;vMode: s: relative to screen
;vMode: w: relative to window
JEE_CaretGetPos(ByRef vPosX, ByRef vPosY, vMode:="a", hWnd:="")
{
	if !hWnd
		hWnd := WinExist("A")
	VarSetCapacity(GUITHREADINFO, A_PtrSize=8?72:48, 0)
	NumPut(A_PtrSize=8?72:48, &GUITHREADINFO, 0, "UInt") ;cbSize
	vTID := DllCall("user32\GetWindowThreadProcessId", Ptr,hWnd, UIntP,0, UInt)
	DllCall("user32\GetGUIThreadInfo", UInt,vTID, Ptr,&GUITHREADINFO)
	hWndC := NumGet(&GUITHREADINFO, A_PtrSize=8?48:28, "Ptr") ;hwndCaret
	vPosX := NumGet(&GUITHREADINFO, A_PtrSize=8?56:32, "Int") ;rcCaret ;x
	vPosY := NumGet(&GUITHREADINFO, A_PtrSize=8?60:36, "Int") ;rcCaret ;y
	vMode := SubStr(vMode, 1, 1)
	if (vMode = "") || (vMode = "r") ;raw
		return
	else if (vMode = "a") ;AutoHotkey
		vMode := SubStr(A_CoordModeCaret, 1, 1)
	JEE_ClientToScreen(hWndC, vPosX, vPosY, vPosX, vPosY)
	if (vMode = "s") ;screen
		return
	else if (vMode = "c") ;client
		JEE_ClientToScreen(hWnd, 0, 0, vOgnX, vOgnY)
	else if (vMode = "w") ;window
		JEE_WindowToScreen(hWnd, 0, 0, vOgnX, vOgnY)
	vPosX -= vOgnX, vPosY -= vOgnY
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
stealzy
Posts: 91
Joined: 01 Nov 2015, 13:43

Re: convert coordinates between Client/Screen/Window modes

13 Feb 2018, 16:51

Do not need convert, if you get all coordinate at once:

Code: Select all

p := WinGetP(WinActive("A"))
MsgBox % p.x " | " p.ClientScr.x " | " p.ClientWin.x

WinGetP(hwnd) {
	WinGetPos, x, y, w, h, ahk_id %hwnd%
	WinP := {x:x, y:y, w:w, h:h}
	VarSetCapacity(pt, 16)
	NumPut(x, pt, 0) || NumPut(y, pt, 4) || NumPut(w, pt, 8) || NumPut(h, pt, 12)
	if (!DllCall("GetClientRect", "uint", hwnd, "uint", &pt))
		Return
	if (!DllCall("ClientToScreen", "uint", hwnd, "uint", &pt))
		Return
	x := NumGet(pt, 0, "int"), y := NumGet(pt, 4, "int")
	w := NumGet(pt, 8, "int"), h := NumGet(pt, 12, "int")
	ClientScr := {x:x, y:y, w:w, h:h}
	ClientWin := {x:x-WinP.x, y:y-WinP.y, w:w, h:h}
	Return WinP := {x:WinP.x, y:WinP.y, w:WinP.w, h:WinP.h, ClientWin:ClientWin, ClientScr:ClientScr}
}
User avatar
Drugwash
Posts: 850
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania
Contact:

Re: convert coordinates between Client/Screen/Window modes

13 Feb 2018, 18:49

Another vMode: f (forced, to focus window/control if not focused, otherwise coordinates will be null).
That'd be purrfect. :)
Now I can go to sleep.
Part of my AHK work can be found here.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: convert coordinates between Client/Screen/Window modes

27 Oct 2018, 17:35

Here are some ControlGetPos / ControlMove variants. They require 'AHK v2 functions for AHK v1'.

Code: Select all

;commands as functions (AHK v2 functions for AHK v1) - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=37&t=29689

q:: ;control get position
ControlGet, hCtl, Hwnd,, Edit1, A
vOutput := ""
JEE_CtlGetPosScreen(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)
vOutput .= Format("x{} y{} w{} h{}", vCtlX, vCtlY, vCtlW, vCtlH) "`r`n"
JEE_CtlGetPosWin(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)
vOutput .= Format("x{} y{} w{} h{}", vCtlX, vCtlY, vCtlW, vCtlH) "`r`n"
JEE_CtlGetPosClient(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)
vOutput .= Format("x{} y{} w{} h{}", vCtlX, vCtlY, vCtlW, vCtlH) "`r`n"
JEE_CtlGetPosScreenAlt(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)
vOutput .= Format("x{} y{} w{} h{}", vCtlX, vCtlY, vCtlW, vCtlH) "`r`n"
MsgBox, % vOutput
return

w:: ;control move
ControlGet, hCtl, Hwnd,, Edit1, A
vCtlX := vCtlY := 300
vCtlW := vCtlH := 100
JEE_CtlMoveScreen(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)
Sleep, 2000
JEE_CtlMoveWin(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)
Sleep, 2000
JEE_CtlMoveClient(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)
return

;==================================================

;e.g. JEE_CtlGetPosClient(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)

;works like ControlGetPos (AHK v2) (on AHK v1/v2)
JEE_CtlGetPosClient(hCtl:=0, ByRef vCtlX:="", ByRef vCtlY:="", ByRef vCtlW:="", ByRef vCtlH:="")
{
	local
	hWnd := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
	WinGetClientPos(vWinX, vWinY,,, "ahk_id " hWnd)
	WinGetPos(vCtlX, vCtlY, vCtlW, vCtlH, "ahk_id " hCtl)
	vCtlX -= vWinX, vCtlY -= vWinY
}

;==================================================

;e.g. JEE_CtlGetPosScreen(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)

JEE_CtlGetPosScreen(hCtl:=0, ByRef vCtlX:="", ByRef vCtlY:="", ByRef vCtlW:="", ByRef vCtlH:="")
{
	local
	WinGetPos(vCtlX, vCtlY, vCtlW, vCtlH, "ahk_id " hCtl)
}

;==================================================

;e.g. JEE_CtlGetPosWin(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)

;note: relative to window
;works like ControlGetPos (AHK v1) (on AHK v1/v2)
JEE_CtlGetPosWin(hCtl:=0, ByRef vCtlX:="", ByRef vCtlY:="", ByRef vCtlW:="", ByRef vCtlH:="")
{
	local
	hWnd := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
	WinGetPos(vWinX, vWinY,,, "ahk_id " hWnd)
	WinGetPos(vCtlX, vCtlY, vCtlW, vCtlH, "ahk_id " hCtl)
	vCtlX -= vWinX, vCtlY -= vWinY
}

;==================================================

;e.g. JEE_CtlGetPosScreenAlt(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)

JEE_CtlGetPosScreenAlt(hCtl:=0, ByRef vCtlX:="", ByRef vCtlY:="", ByRef vCtlW:="", ByRef vCtlH:="")
{
	local
	hWnd := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
	VarSetCapacity(RECT, 16, 0)
	DllCall("user32\GetWindowRect", Ptr,hCtl, Ptr,&RECT)
	DllCall("user32\MapWindowPoints", Ptr,0, Ptr,hWnd, Ptr,&RECT, UInt,2)
	vCtlX := NumGet(&RECT, 0, "Int"), vCtlY := NumGet(&RECT, 4, "Int")
	vCtlW := NumGet(&RECT, 8, "Int")-vCtlX, vCtlH := NumGet(&RECT, 12, "Int")-vCtlY
}

;==================================================

;e.g. JEE_CtlMoveClient(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)

;works like ControlMove (AHK v2) (on AHK v1/v2)
JEE_CtlMoveClient(hCtl:=0, vCtlX:="", vCtlY:="", vCtlW:="", vCtlH:="")
{
	local
	WinMove(vCtlX, vCtlY, vCtlW, vCtlH, "ahk_id " hCtl)
}

;==================================================

;e.g. JEE_CtlMoveScreen(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)

JEE_CtlMoveScreen(hCtl:=0, vCtlX:="", vCtlY:="", vCtlW:="", vCtlH:="")
{
	local
	hWnd := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
	WinGetClientPos(vWinX, vWinY,,, "ahk_id " hWnd)
	WinMove(vCtlX-vWinX, vCtlY-vWinY, vCtlW, vCtlH, "ahk_id " hCtl)
}

;==================================================

;e.g. JEE_CtlMoveWin(hCtl, vCtlX, vCtlY, vCtlW, vCtlH)

;note: relative to window
;works like ControlMove (AHK v1) (on AHK v1/v2)
JEE_CtlMoveWin(hCtl:=0, vCtlX:="", vCtlY:="", vCtlW:="", vCtlH:="")
{
	local
	hWnd := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
	WinGetPos(vWinX, vWinY,,, "ahk_id " hWnd)
	WinGetClientPos(vCWinX, vCWinY,,, "ahk_id " hWnd)
	WinMove(vCtlX+vWinX-vCWinX, vCtlY+vWinY-vCWinY, vCtlW, vCtlH, "ahk_id " hCtl)
}

;==================================================
These functions were developed during tests for ControlGetPos1 / ControlMove1 functions, which are available here:
conversion logic, v1 = -> v1 := -> v2, two-way compatibility - Page 7 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 25#p246325
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
panhartstuff
Posts: 25
Joined: 21 Jan 2018, 07:40

Re: convert coordinates between Client/Screen/Window modes

13 Dec 2019, 11:38

What are the ByRef vPosX2, ByRef vPosY2 variables?

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: furqan, kashmirLZ and 76 guests