Jump to content
Deye

GUI Resizing - Snapping - Centering

Recommended Posts

Deye

Since I have updated this a few times in the snippets thread (for corrections)
That will be the last update
Since the code has grown and if anything should change onwards ..will keep it here

To resize: hold the gui while dragging it (up or down) (left or right) with the mouse
Tip: test it about between different screen borders

 

#include <WindowsConstants.au3>
#include <GuiconstantsEx.au3>
#include <WinAPISys.au3>
#include <WinAPIGdi.au3>
#include <Misc.au3>

Opt("GUIResizeMode", 904)
$hDLL = DllOpen("user32.dll")
OnAutoItExitRegister("On_Exit")

Global $iWidth = 380, $iHeight = 180

Global $hGUI = GUICreate("X", $iWidth, $iHeight, -1, -1)
GUISetBkColor(0X5c6e8c, $hGUI)

$iWidth = _WinAPI_GetClientWidth($hGUI)
$iHeight = _WinAPI_GetClientHeight($hGUI)
$ButtonWidth = 40
$ButtonHeight = 20
$idnew = GUICtrlCreateButton("Change Dimension", ($iWidth / 2) - (3 * $ButtonWidth / 2), ($iHeight / 2) - (4 * $ButtonHeight / 2), 3 * $ButtonWidth, $ButtonHeight)
$idCenter = GUICtrlCreateButton("x", ($iWidth / 2) - ($ButtonWidth / 2), ($iHeight / 2) - ($ButtonHeight / 2), $ButtonWidth, $ButtonHeight)

Global $moving = False, $PMon = _WinAPI_MonitorFromWindow($hGUI), $aMax = GetMonitorRect($PMon)

DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $hGUI, "int", 500, "long", 0x00040010)

GUIRegisterMsg($WM_ENTERSIZEMOVE, "WM_ENTERSIZEMOVE")
GUIRegisterMsg($WM_EXITSIZEMOVE, "WM_EXITSIZEMOVE")

GUISetState()

$aGPos = WinGetPos($hGUI)
$iWidth = $aGPos[2]
$iHeight = $aGPos[3]

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_close
            Exit
        Case $idnew
            $iWidth = Random(150, 550, 1)
            $iHeight = Random(150, 550, 1)
            _NewDimension($iWidth, $iHeight)

        Case $idCenter
            _CenterToScreen()

        Case $GUI_EVENT_PRIMARYDOWN
            If $moving Then ContinueLoop
            OnDrag()
    EndSwitch
    Sleep(10)
WEnd

Func OnDrag()
    Local $aPos, $iRoll, $X, $Y, $PH, $PW = 0, $aCurInfo = GUIGetCursorInfo($hGUI)
    If $aCurInfo[4] <> 0 Then Return ; Mouse is over a control

    Local $aGPos = WinGetPos($hGUI)
    Local $aMPos = MouseGetPos()
    Local $width = $aGPos[2]
    Local $height = $aGPos[3]

    While _IsPressed("01", $hDLL)
        $aPos = MouseGetPos()
        $iRoll = (($aMPos[1] - $aPos[1]) - ($aMPos[0] - $aPos[0])) * 100 / 50

        $height = Round(($aGPos[3] / $aGPos[2]) * ($aGPos[2] + $iRoll))
        If $height < $iHeight Then ExitLoop

        If $height >= $aMax[3] - $aMax[1] Then $height = $aMax[3] - $aMax[1]
        $width = Round(($aGPos[2] / $aGPos[3]) * $height)

        If $width > ($aMax[2] - $aMax[0]) Then
            $width = ($aMax[2] - $aMax[0])
            $height = Round(($aGPos[3] / $aGPos[2]) * $width)
        EndIf

        ;Store as Previous Width & Height
        $PW = $width
        $PH = $height

        $X = Round(($aGPos[2] / 2) + $aGPos[0] - ($width / 2))
        $Y = Round(($aGPos[3] / 2) + $aGPos[1] - ($height / 2))

        If $X < $aMax[0] Then
            $X = $aMax[0]
        ElseIf ($X + $width) > $aMax[2] Then
            $X = Round($aMax[2] - $width)
        EndIf

        If $Y < $aMax[1] Then
            $Y = $aMax[1]
        ElseIf ($Y + $height) > $aMax[3] Then
            $Y = Round($aMax[3] - $height)
        EndIf

        WinMove($hGUI, "", $X, $Y, $width, $height)

        Sleep(20)
    WEnd
    If $height < $iHeight And $PW <> 0 Then
        $tRect = _WinAPI_GetWindowRect($hGUI)
        WinMove($hGUI, "", (($PW / 2) + DllStructGetData($tRect, "Left")) - ($iWidth / 2), Ceiling(($PH / 2) + DllStructGetData($tRect, "Top")) - ($iHeight / 2), $iWidth, $iHeight)
    EndIf
EndFunc

Func _NewDimension($width, $height)
    Local $aPos = WinGetPos($hGUI)
    WinMove($hGUI, "", ($aPos[2] / 2) + $aPos[0] - ($width / 2), ($aPos[3] / 2) + $aPos[1] - ($height / 2), $width, $height)
EndFunc   ;==>_NewDimension

Func _SnapToScreen(ByRef $aPos, ByRef $aMax) ; Snap the gui back to its full view when moved off screen
    Local $t0 = $aPos[0], $t1 = $aPos[1]
    If $aPos[0] < $aMax[0] Then
        $aPos[0] = $aMax[0]
    ElseIf ($aPos[0] + $aPos[2]) > $aMax[2] Then
        $aPos[0] = ($aMax[2] - $aPos[2])
    EndIf
    If $aPos[1] < $aMax[1] Then
        $aPos[1] = $aMax[1]
    ElseIf ($aPos[1] + $aPos[3]) > $aMax[3] Then
        $aPos[1] = ($aMax[3] - $aPos[3])
    EndIf
    If $t0 <> $aPos[0] Or $t1 <> $aPos[1] Then Return 1
EndFunc

Func _CenterToScreen($Snap = False) ; Center & Resize the gui dimension if off screen
    Local $a = WinGetPos($hGUI)
    Local $Mon = _WinAPI_MonitorFromWindow($hGUI)
    If $Mon <> $PMon Then
        $PMon = $Mon
        $aMax = GetMonitorRect($PMon)
    EndIf
    If $a[3] > ($aMax[3] - $aMax[1]) Then
        $a[2] = Round(($a[2] / $a[3]) * ($aMax[3] - $aMax[1])) ;New Width
        $a[3] = $aMax[3] - $aMax[1] ;New Height
    EndIf
    If $a[2] > ($aMax[2] - $aMax[0]) Then
        $a[3] = Round(($a[3] / $a[2]) * ($aMax[2] - $aMax[0])) ;New Height
        $a[2] = $aMax[2] - $aMax[0] ;New Width
    EndIf
    If $Snap Then
        If _SnapToScreen($a, $aMax) Then Return WinMove($hGUI, "", $a[0], $a[1], $a[2], $a[3])
        Return
    EndIf
    WinMove($hGUI, "", (($aMax[2] + $aMax[0]) / 2) - ($a[2] / 2), (($aMax[1] + $aMax[3]) / 2) - ($a[3] / 2), $a[2], $a[3])
EndFunc

Func GetMonitorRect($hMonitor)
    Local $aData = _WinAPI_GetMonitorInfo($hMonitor)
    Local $s = DllStructGetData($aData[1], 1) & ',' & DllStructGetData($aData[1], 2) & ',' & DllStructGetData($aData[1], 3) & ',' & DllStructGetData($aData[1], 4)
    Local $a = StringSplit($s, ',', 2)
    Return $a
EndFunc

Func WM_ENTERSIZEMOVE($hWnd, $Msg, $wParam, $lParam)
    If $hWnd = $hGUI Then $moving = True
    Return "GUI_RUNDEFMSG"
EndFunc

Func WM_EXITSIZEMOVE($hWnd, $Msg, $wParam, $lParam)
    If $hWnd = $hGUI Then
        $moving = False
        _CenterToScreen(1)
    EndIf
    Return "GUI_RUNDEFMSG"
EndFunc

Func On_Exit()
    DllClose($hDLL)
EndFunc

 

Edited by Deye
polished
  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×