﻿id	summary	reporter	owner	description	type	status	milestone	component	version	severity	resolution	keywords	cc
4112	_WinAPI_MapWindowPoints addition	MattyD		"Hey JP,

I thought this one would probably be a good candidate for an adding to `WinAPIConv.au3`. FWIW I've thrown in the `$HWND_DESKTOP` definition to service it, but its not really necessary. [https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mapwindowpoints Microsoft Documentation].

Thanks,
Matt

{{{#!autoit
Global Const $HWND_DESKTOP = 0

Func _WinAPI_MapWindowPoints($hWndFom, $hWndTo, $tPoints, $iCount)
    Local $aCall = DllCall(""User32.dll"", ""int"", ""MapWindowPoints"", ""hwnd"", $hWndFom, ""hwnd"", $hWndTo, ""struct*"", $tPoints, ""int"", $iCount)
    If @error Then Return SetError(@error, @extended, $aCall)
    Return $aCall[0]
EndFunc
}}}

Example: (I can simplify if need be.)
{{{#!autoit
#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <WinAPI.au3>
#include <GuiConstants.au3>

Global $g_hMainWnd, $g_hChildWnd, $g_idWinPos, $g_idClientPos, $g_idButton

_Example()

Func _Example()
	GUIRegisterMsg($WM_MOVE, ""MoveSize"")
	GUIRegisterMsg($WM_SIZE, ""MoveSize"")

	$g_hMainWnd = GUICreate(""Main Window"", 500, 400, -1, -1, $WS_SIZEBOX)
	GUICtrlCreateLabel(""Popup window's rect, relative to the top-left of the main window's client area."", 10, 10, 500, 20)
	$g_idWinPos = GUICtrlCreateLabel("""", 10, 30, 500, 20)

	GUICtrlCreateLabel(""Popup's window's client rect, relative to the top-left of the main window's client area."", 10, 55, 500, 20)
	$g_idClientPos = GUICtrlCreateLabel("""", 10, 75, 500, 20)

	$g_hChildWnd = GUICreate(""Popup Window"", 200, 125, -1, -1, BitOR($WS_POPUP, $WS_CAPTION), 0, $g_hMainWnd)
	Local $sMsg = ""The popup will re-position itself relative to its parent."" & @CRLF & @CRLF & _
		 ""Move or resize the parent window to trigger the action.""
	GUICtrlCreateLabel($sMsg, 10, 10, 180, 80, $SS_CENTER)
	$g_idButton = GUICtrlCreateButton(""Re-Center"", 60, 90, 80, 25)

	GUISetState(@SW_SHOW, $g_hMainWnd)
	GUISetState(@SW_SHOW, $g_hChildWnd)

	While 1
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE
				ExitLoop
			Case $g_idButton
				PositionPopUpWindow($g_hChildWnd)
		EndSwitch
	WEnd

	GUIDelete($g_hChildWnd)
	GUIDelete($g_hMainWnd)
EndFunc

Func MoveSize($hWnd, $iMsg, $wParam, $lParam)

	Switch $hWnd
		Case $g_hMainWnd
			PositionPopUpWindow($g_hChildWnd)
			If $iMsg = $WM_SIZE Then UpdateLabels()

		Case $g_hChildWnd
			UpdateLabels()

	EndSwitch

	Return _WinAPI_DefWindowProcW($hWnd, $iMsg, $wParam, $lParam)
EndFunc

Func PositionPopUpWindow($hWnd)
	Local $hOwner = _WinAPI_GetWindow($hWnd, $GW_OWNER)

	Local $tWndPos = _WinAPI_GetWindowRect($hWnd)
	Local $iWndW =  DllStructGetData($tWndPos, ""Right"") - DllStructGetData($tWndPos, ""Left"")
	Local $iWndH =  DllStructGetData($tWndPos, ""Bottom"") - DllStructGetData($tWndPos, ""Top"")

	Local $tOwnerPos = _WinAPI_GetClientRect($hOwner)
	Local $iOwnerW =  DllStructGetData($tOwnerPos, ""Right"") - DllStructGetData($tOwnerPos, ""Left"")
	Local $iOwnerH =  DllStructGetData($tOwnerPos, ""Bottom"") - DllStructGetData($tOwnerPos, ""Top"")

	; Position window
	; (Convert point relative to main window -> screen coords)
	Local $tPoint = DllStructCreate($tagPOINT)
	DllStructSetData($tPoint, ""X"", ($iOwnerW - $iWndW)/2)
	DllStructSetData($tPoint, ""Y"", ($iOwnerH - $iWndH)/2)
	_WinAPI_MapWindowPoints($hOwner, 0, $tPoint, 1)

	_WinAPI_SetWindowPos($hWnd, $HWND_TOP, DllStructGetData($tPoint, ""X""), DllStructGetData($tPoint, ""Y""), _
			0, 0, BitOR($SWP_NOSIZE, $SWP_NOZORDER, $SWP_SHOWWINDOW, $SWP_NOACTIVATE))
EndFunc

Func UpdateLabels()
	; Popup window's non-client position relative to main window's client area.
	; (Convert screen coords -> points relative to main window)
	Local $tWndPos = _WinAPI_GetWindowRect($g_hChildWnd)
	_WinAPI_MapWindowPoints(0, $g_hMainWnd, $tWndPos, 2)
	GUICtrlSetData($g_idWinPos, _
		StringFormat(""Left: [ %4d ] Top: [ %4d ] Right: [ %4d ] Bottom: [ %4d ]"", _
		DllStructGetData($tWndPos, ""Left""), DllStructGetData($tWndPos, ""Top""), _
		DllStructGetData($tWndPos, ""Right""), DllStructGetData($tWndPos, ""Bottom"")))

	; Popup window's client position relative to main window's client area.
	; (Convert points relative to popup window -> points relative to main window)
	Local $tClientPos = _WinAPI_GetClientRect($g_hChildWnd)
	_WinAPI_MapWindowPoints($g_hChildWnd, $g_hMainWnd, $tClientPos, 2)
	GUICtrlSetData($g_idClientPos, _
		StringFormat(""Left: [ %4d ] Top: [ %4d ] Right: [ %4d ] Bottom: [ %4d ]"", _
		DllStructGetData($tClientPos, ""Left""), DllStructGetData($tClientPos, ""Top""), _
		DllStructGetData($tClientPos, ""Right""), DllStructGetData($tClientPos, ""Bottom"")))
EndFunc

Func _WinAPI_MapWindowPoints($hWndFom, $hWndTo, $tPoints, $iCount)
    Local $aCall = DllCall(""User32.dll"", ""int"", ""MapWindowPoints"", ""hwnd"", $hWndFom, ""hwnd"", $hWndTo, ""struct*"", $tPoints, ""int"", $iCount)
    If @error Then Return SetError(@error, @extended, $aCall)
    Return $aCall[0]
EndFunc
}}}

Suggested Documentation:
{{{
###User Defined Function###
_WinAPI_MapWindowPoints

###Description###
Converts a set of points from a coordinate space relative to one window to a coordinate space relative to another window.

###Syntax###
#include <WinAPIConv.au3>
_WinAPI_MapWindowPoints( $hWndFom, $hWndTo, $tPoints, $iCount )

###Parameters###
@@ParamTable@@
$hWndFrom
	A handle to the window from which points are converted. If this parameter is 0 or $HWND_DESKTOP, the points are presumed to be in screen coordinates.
$hWndTo
	A handle to the window to which points are converted. If this parameter is 0 or $HWND_DESKTOP, the points are converted to screen coordinates.
$tPoints
	A struct containing an array of POINT structures that contain the set of points to be converted.
$iCount
	The number of POINTs in the $tPoints struct.
@@End@@

###ReturnValue###
@@ReturnTable@@
Success:	low-order word: The number of pixels added to the horizontal coordinate of each source point.
	high-order word: The number of pixels added to the vertical coordinate of each source point.
Failure:	0. Call _WinAPI_SetLastError prior to calling this method to differentiate an error return value from a legitimate ""0"" return value.
@@End@@

###Remarks###
If hWndFrom or hWndTo (or both) have the $WS_EX_LAYOUTRTL extended style and precisely two points are passed in $tPoints, _WinAPI_MapWindowPoints will interpret those two points as a RECT and possibly automatically swap the left and right fields of that rectangle to ensure that left is not greater than right. If you need to map precisely two independent points and don't want the RECT logic applied to them by _WinAPI_MapWindowPoints, you must call _WinAPI_MapWindowPoints with one POINT at a time.

###Related###
_WinAPI_ScreenToClient, _WinAPI_ClientToScreen

###Example###
@@IncludeExample@@
}}}
"	Feature Request	new		Standard UDFs		None			
