Gui Resizing

  • Hallo zusammen, ich hab ein kleines Problem.
    Ich möchte eine Gui mit 3 Group Controls erstellen, eine Art 3 Zeilen Ansicht.

    Im Prinzip soll beim Resize der Gui der Abstand zwischen "$GroupTop, $GroupMiddle" und "$GroupMiddle, $GroupBottom" immer 8 Pixel bleiben!
    Aber die Höhe von $GroupTop und $GroupMiddle soll sich Dynamisch anpassen.
    Nur leider wird der Abstand zwischen den Groups immer größer :(

    So weit bin ich bis jetzt gekommen:

    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

    [/autoit][autoit][/autoit][autoit]

    GUICreate("Gui", 500, 332, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_TABSTOP))
    Global $GroupTop = GUICtrlCreateGroup("Dock: Left, Right, Top", 8, 8, 484, 100)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $GroupMiddle = GUICtrlCreateGroup("Dock: Left, Right, Height, VCenter", 8, 116, 484, 100)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKHEIGHT+$GUI_DOCKVCENTER)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $GroupBottom = GUICtrlCreateGroup("Dock: Left, Right, Bottom", 8, 224, 484, 100)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKBOTTOM)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    GUISetState(@SW_SHOW)

    [/autoit][autoit][/autoit][autoit]

    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    ExitLoop
    EndSwitch
    WEnd

    [/autoit]

    Einmal editiert, zuletzt von Taz77 (23. Dezember 2013 um 09:00) aus folgendem Grund: Präfix auf gelöst gesetzt ;)

    • Offizieller Beitrag

    Soweit ich beim Rumprobieren mit dem Resizing erfahren habe, wird das Resize-Verhalten nicht nur auf die Ctrl sondern auch auf den gesamten GUI-Hintergrund angewendet. Somit kannst du einen fixen Abstand zw. Ctrls aber dynamische Änderung der Ctrl selbst nicht realisieren.

  • Soweit ich beim Rumprobieren mit dem Resizing erfahren habe, wird das Resize-Verhalten nicht nur auf die Ctrl sondern auch auf den gesamten GUI-Hintergrund angewendet. Somit kannst du einen fixen Abstand zw. Ctrls aber dynamische Änderung der Ctrl selbst nicht realisieren.

    Das habe ich fast befürchtet, aber Dankeschön für die Info.

    Mir Ist da gerade etwas eingefallen. Ich werde mal versuchen mit WM_SIZE etwas zu bauen, mal schauen ob das klappt.

    • Offizieller Beitrag

    Setze die 3 Gruppen auf Childguis, dann mußt du bei WM_SIZE nur die Childs in der Größe ändern.
    Die einzelnen Controls der Childs kannst du ja per GUICtrlSetResizing an die Childguis koppeln.

  • Spoiler anzeigen
    [autoit]


    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $iDefWinW = 500
    $iDefWinH = 332

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIResizeMode", $GUI_DOCKALL)

    [/autoit] [autoit][/autoit] [autoit]

    GUICreate("Gui", 500, 332, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_MAXIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_TABSTOP))
    GUIRegisterMsg($WM_SIZE, "_ResizeHandler")

    [/autoit] [autoit][/autoit] [autoit]

    Global $GroupTop = GUICtrlCreateGroup("Dock: Left, Right, Top", 8, 8, 484, 100)
    ;~ GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $GroupMiddle = GUICtrlCreateGroup("Dock: Left, Right, Height, VCenter", 8, 116, 484, 100)
    ;~ GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKVCENTER)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $GroupBottom = GUICtrlCreateGroup("Dock: Left, Right, Bottom", 8, 224, 484, 100)
    ;~ GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKBOTTOM+$GUI_DOCKHEIGHT)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    ExitLoop
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _ResizeHandler($hWnd, $iCtrl, $iWParam, $iLParam)
    $iW = _WinAPI_LoWord($iLParam)
    $iH = _WinAPI_HiWord($iLParam)
    ConsoleWrite("New Size: " & $iW & ":" & $iH & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ;GBottom soll die Position nicht verändern. Breite muss trotzdem angepasst werden.
    GUICtrlSetPos($GroupBottom, 8, $iH - $iDefWinH + 224, $iW - $iDefWinW + 484, 100)

    [/autoit] [autoit][/autoit] [autoit]

    ;GMiddle soll die Hälfte des Abstandes vom oberen Rand und GBottom einnehmen. Die Position und die Höhe muss sich daher anpassen.
    $iGMiddleHFactor = (($iH - 108) / ($iDefWinH - 108))
    GUICtrlSetPos($GroupMiddle, 8, 116 * $iGMiddleHFactor, $iW - $iDefWinW + 484, $iH - $iDefWinH + 224 - $iGMiddleHFactor * 116)

    [/autoit] [autoit][/autoit] [autoit]

    ;GTop soll die Position nicht verändern, nur die andere Hälfte des Abstandes zwischen dem oberen Rand und GBottom einnehmen.
    GUICtrlSetPos($GroupTop, 8, 8, $iW - $iDefWinW + 484, 116 * $iGMiddleHFactor - 8)
    EndFunc

    [/autoit]

    WM_SIZE ist der richtige Ansatz. :thumbup:

    lg

    Edit:
    Raupis Idee wäre evtl. auch nicht schlecht, wenn man sich die Berechnungen anschaut... ^^
    Dann muss immer nur die Child-GUI verändert werden.

    • Offizieller Beitrag

    Ich denke das in den Groups noch weiter Controls entstehen sollen. Schon alleine deshalb ist ein resizen der Childguis der geringere Aufwand. ;)

  • Setze die 3 Gruppen auf Childguis, dann mußt du bei WM_SIZE nur die Childs in der Größe ändern.
    Die einzelnen Controls der Childs kannst du ja per GUICtrlSetResizing an die Childguis koppeln.


    Super Idee :thumbup:

    Auch eine Super Idee, danke für den Code :thumbup:
    Nur soll GMiddle die Fixe Höhe haben, und nicht die GBottom.

  • Ich denke das in den Groups noch weiter Controls entstehen sollen. Schon alleine deshalb ist ein resizen der Childguis der geringere Aufwand. ;)

    Nein, in meinen Fall im Moment nicht. Ich habe in der Top & Bottom Gruppe Jeweils ein Child Fenster drin, welches aber keine AutoIt Anwendung ist. Wenn dem aber so wäre, ist deine Idee auf jeden Fall die weniger aufwendigere. :thumbup:
    Ich habe nur in der Mittleren Gruppe meine ganzen Controls.

    Ich habe mal versucht nur die Obere und Untere Gruppe zu verschieben, das war mein Lösungsansatz:

    Spoiler anzeigen
    [autoit]

    Func __WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    Local $iMargin = 16, $iWndHeight = BitShift($lParam, 16), $aPos = ControlGetPos($hWnd, '', $GroupMiddle)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetPos($GroupTop, Default, Default, $aPos[2], $aPos[1]-$iMargin)
    GUICtrlSetPos($GroupBottom, Default, $aPos[1]+$aPos[3]+($iMargin/2), $aPos[2], $iWndHeight - ($aPos[1]+$aPos[3]+$iMargin))
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit]


    Funktioniert auch soweit super, nur leider nicht wenn ich das Fenster Maximiere. ?(

    • Offizieller Beitrag

    So sollte es gehen:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $iDefWinW = 500
    $iDefWinH = 332

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIResizeMode", $GUI_DOCKALL)

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("Gui", 500, 332, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP))
    $iMinH = _WinAPI_GetWindowHeight($hGui);Höhe des Fensters mit Rahmen
    $iMinW = _WinAPI_GetWindowWidth($hGui);Breite des Fensters mit Rahmen

    [/autoit] [autoit][/autoit] [autoit]

    Global $GroupTop = GUICtrlCreateGroup("Dock: Left, Right, Top", 8, 8, 484, 100)
    ;~ GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $GroupMiddle = GUICtrlCreateGroup("Dock: Left, Right, Height, VCenter", 8, 116, 484, 100)
    ;~ GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKVCENTER)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    Global $GroupBottom = GUICtrlCreateGroup("Dock: Left, Right, Bottom", 8, 224, 484, 100)
    ;~ GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKBOTTOM+$GUI_DOCKHEIGHT)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_SIZE, "_ResizeHandler")
    GUIRegisterMsg($WM_GETMINMAXINFO, "MY_WM_GETMINMAXINFO");Resizen der GUI begrenzen
    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    ExitLoop
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _ResizeHandler($hWnd, $iCtrl, $iWParam, $iLParam)
    $iW = _WinAPI_LoWord($iLParam)
    $iH = _WinAPI_HiWord($iLParam)
    $iGrouphight = Int(($iH - 132) / 2)
    GUICtrlSetPos($GroupTop, 8, 8, $iW - $iDefWinW + 484, $iGrouphight)
    GUICtrlSetPos($GroupBottom, 8, $iGrouphight + 124, $iW - $iDefWinW + 484, $iGrouphight)
    GUICtrlSetPos($GroupMiddle, 8, $iGrouphight + 16, $iW - $iDefWinW + 484, 100)

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_ResizeHandler

    [/autoit] [autoit][/autoit] [autoit]

    Func MY_WM_GETMINMAXINFO($hWnd, $msg, $wParam, $lParam)
    If $hWnd = $hGui Then
    Local $minmaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
    DllStructSetData($minmaxinfo, 7, $iMinW) ; min Breite
    DllStructSetData($minmaxinfo, 8, $iMinH) ; min Höhe
    ;DllStructSetData($minmaxinfo, 9, 1024) ; max X
    ;DllStructSetData($minmaxinfo, 10, 180) ; max Y
    EndIf
    EndFunc ;==>MY_WM_GETMINMAXINFO

    [/autoit]


    Zusätzlich habe ich beim Resizen die Minimalgröße der GUI auf den Wert begrenzt, welche die Gui beim erstellen hatte.
    Sieht ziehmlich beknackt aus, wenn die GUI zu klein wird. ;)


  • Super, vielen lieben dank Raupi :thumbup:

    Ein dickes Dankeschön an alle!