Brief:
native WinMove() has a "speed" parameter for a more fluent movement. unfortunately, that applies to the change in position, but not the change in size. the position changes in the specified "speed", but size changes abruptly.
_WinPose() is similar to WinMove(), except that move and resize are simultaneous, both conform to the speed parameter.
UDF: (save as "WinPose.au3")
#include-once
#include <WinAPISysWin.au3>
; #FUNCTION# ====================================================================================================================
; Name ..........: _WinPose
; Description ...: same as native WinMove(), except that move and resize are simultaneous, both conform to the speed parameter.
; Syntax ........: _WinPose($hWnd, $sText, $x, $y, $w, $h[, $speed = 0])
; Parameters ....: $hWnd - the title/hWnd/class of the window to pose.
; $sText - the text of the window to pose.
; $x - X coordinate to move to.
; $y - Y coordinate to move to.
; $w - [optional] new width of the window.
; $h - [optional] new height of the window.
; $speed - [optional] the speed to pose the window (smaller value = faster speed, 0 = instantaneous).
; Return values .: Success - a handle to the window.
; Failure - 0 if the window is not found (also sets @error to non-zero).
; Author ........: orbs
; Modified ......:
; Remarks .......: parameters and return values are practically identical to those of the native WinMove() function.
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _WinPose($hWnd, $sText, $x, $y, $w = Default, $h = Default, $speed = 0)
; find the window to move
If Not IsHWnd($hWnd) Then
$hWnd = WinGetHandle($hWnd, $sText)
If @error Then Return SetError(1, 0, False)
EndIf
Local $aPos = WinGetPos($hWnd)
If @error Then Return SetError(2, 0, False)
; initialize variables
Local Enum $pos_x, $pos_y, $pos_w, $pos_h
Local Enum $aiCurrent, $aiTarget, $aiDelta, $aiRatio
Local $aPosTarget[4][4] = [[$aPos[$pos_x], $x, 0, 0], [$aPos[$pos_y], $y, 0, 0], [$aPos[$pos_w], $w, 0, 0], [$aPos[$pos_h], $h, 0, 0]]
; accomodate for Default keyword
For $iElement = 0 To 3
If $aPosTarget[$iElement][$aiTarget] = Default Then $aPosTarget[$iElement][$aiTarget] = $aPos[$iElement]
Next
; calculate delta
For $iElement = 0 To 3
$aPosTarget[$iElement][$aiDelta] = $aPosTarget[$iElement][$aiTarget] - $aPosTarget[$iElement][$aiCurrent]
Next
; find the maximum delta
Local $iMaxElement = 0, $iMaxDelta = 0
For $iElement = 0 To 3
If Abs($aPosTarget[$iElement][$aiDelta]) > $iMaxDelta Then
$iMaxElement = $iElement
$iMaxDelta = $aPosTarget[$iElement][$aiDelta]
EndIf
Next
; accomodate for negative delta
If ($aPosTarget[$iMaxElement][$aiTarget] - $aPos[$iMaxElement]) < 0 Then $iMaxDelta = -$iMaxDelta
; calculate ratio for all elements
For $iElement = 0 To 3
$aPosTarget[$iElement][$aiRatio] = $aPosTarget[$iElement][$aiDelta] / $iMaxDelta
Next
; move & resize the window gradually
For $iStep = 0 To $iMaxDelta
For $iElement = 0 To 3
$aPosTarget[$iElement][$aiCurrent] += $aPosTarget[$iElement][$aiRatio]
Next
For $i = 1 To $speed
_WinAPI_MoveWindow($hWnd, _
$aPosTarget[$pos_x][$aiCurrent], _
$aPosTarget[$pos_y][$aiCurrent], _
$aPosTarget[$pos_w][$aiCurrent], _
$aPosTarget[$pos_h][$aiCurrent], False)
Next
Next
; validate final outcome is as expected
Return WinMove($hWnd, '', $x, $y, $w, $h)
EndFunc ;==>_WinPose
Example:
#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#include <AutoItConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include 'WinPose.au3'
Global Const $iMinW = 250, $iMinH = 100
Global $x, $y, $w, $h, $speed
Global $hGUI = GUICreate('_WinPose() Example', $iMinW, $iMinH)
Global $gButton = GUICtrlCreateButton('Click Me!', 25, 25, 200, 50)
GUICtrlSetResizing(-1, $GUI_DOCKBORDERS)
GUISetState(@SW_SHOW)
Global $msg
While True
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $gButton
$w = Random($iMinW, @DesktopWidth / 3, 1)
$h = Random($iMinH, @DesktopHeight / 3, 1)
$x = Random(0, @DesktopWidth - $w, 1)
$y = Random(0, @DesktopHeight - $h, 1)
$speed = Random(10, 100, 1)
_WinPose($hGUI, '', $x, $y, $w, $h, $speed)
EndSwitch
WEnd
click the button to pose the window in a new random position and size, in a random speed.
enjoy 🙂