Modify ↓
#4112 new Feature Request
_WinAPI_MapWindowPoints addition
| Reported by: | MattyD | Owned by: | |
|---|---|---|---|
| Milestone: | Component: | Standard UDFs | |
| Version: | Severity: | None | |
| Keywords: | Cc: |
Description
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. Microsoft Documentation.
Thanks,
Matt
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.)
#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@@
Attachments (0)
Note:
See TracTickets
for help on using tickets.
