Sign in to follow this  
Followers 0

GUIExtender - Original version

124 posts in this topic

Posted (edited)

New version 21 Feb 12

New: You can now choose the manner in which the GUI extends/retracts by adding a parameter to _GUIExtender_Init. This parameter sets the fixed point of the GUI: Left/Top (default and current behaviour), Centre, Right/Bottom. This fixed point can be overridden for a specific section by using a similar parameter in a _GUIExtender_Section_Extend call. See the new examples for more details.

Thanks to mechaflash213 for the idea. :blink:

This is a non-scriptbreaking change - all current scripts will perform as before. :nuke:

New UDF, examples and zip in this post. ;)

Previous updates:

New version 6/12/11

2 new functions _GUIExtender_ActionCheck and _GUIExtender_UDFCtrlCheck have been added to allow you to use UDF-created controls within the GUI. All you need to do is to check whether a section has been actioned using _GUIExtender_ActionCheck and then call _GUIExtender_UDFCtrlCheck for each UDF-created control in the GUI - GUIExtender then determines whether and where to display the control.

_GUIExtender_ActionCheck returns True/False to indicate if a section has been actioned. If it has then _GUIExtender_UDFCtrlCheck should be called with these 4 parameters for each control:

_GUIExtender_UDFCtrlCheck($hControl_Handle, $iSection, $iX, $iY)
; Parameters ....: $hControl_Handle - Handle of UDF-created control
;                  $iSection        - Section within which control is situated
;                  $iX, $iY         - Coords of control - relative to section not to GUI <<<<<<

Two examples have been added to show the functions in action in both MessageLoop and OnEvent modes.

Thanks to Tippex who pushed me to develop it.


New Version 28/02/11

Fixed - UDF crashed if reused on a new GUI within the same script - the data array was corrupted when the new GUI was created. An example of this would be the deletion and recreation of a child GUI with extendable sections. (Thanks Lupo73)

A new function _GUIExtender_Clear has been added to reset the data array. Call it when a GUI with extendable sections is deleted so that the data array is reset ready for the next GUI to use the UDF. There is a linked code change to _GUIExtender_Init - this will fail if the data array has not been reset, so a check for @error will show the UDF has not been initialised correctly.

Note that if you only use the UDF on the main GUI in your script which remains in existence until the script exits, there is no requirement to call the _GUIExtender_Clear function on exit. It is only required if you are destroying and then recreating GUIs which use the UDF within the same script - as in the child example which found the problem. No other syntax changes required.


BugFix Version 27/12/10

Fixed - Variable not declared error if a conditional statement went the other way. (Thanks shanet)


New Version 17/11/10

GUIExtender now works correctly with embedded objects and tabs (thanks JohnOne for the initial bug reports and trancexx for the code to fix the object bug).

The object problem arose because there is no direct link between the ControlID returned by GUICtrlCreateObj and the original object. So I have introduced a new function for the user to tell AutoIt about the 2 valuess - the UDF then works its magic to make the link:

_GUIExtender_Obj_Data($iCID, $oObj)

$iCID = ControlID returned by GUICtrlCreateObj

$iObj = Original object reference returned by ObjCreate

The tab problem occurred because internal TabItems are given a ControlID by AutoIt, but do not actually exist as separate copntrols as far as Windows is concerned. The UDF now ignores them and just works with the Tab container.


New Version 3/09/10

GUIExtender now restores the GUI correctly after a MINIMIZE/RESTORE cycle.

If you are in OnEvent mode or if you already call _GUIExtender_Action then you need to take no action as the necessary function is called automatically.

If you are in GetMessage mode and are NOT using any UDF-created action controls, you need to add the following to your GUIGetMsg loop:

Case $GUI_EVENT_RESTORE
    _GUIExtender_Restore()


New Version 5/08/10

GUIExtender can now can open sections horizontally or vertically. All sections must use the same orientation.

A recent forum question asked how to have expandable sections in a GUI. Although the coding to do this was not too difficult, it was a bit messy and not too easy to modify for another GUI - as subsequent posts in the thread showed.

So I thought I might develop a UDF to do the same thing, but in as transparent manner as possible - and came up with GUIExtender. This UDF allows you to have multiple sections within a GUI which can be static or extendable. The extendable sections can be extended and retracted either by UDF created buttons or programmatically. The controls on the sections are fully functional and there is no overlap problem when retracted (see the details section if you want to know how). And the UDF can be used in both MessageLoop and OnEvent modes.

Here are several examples:

The first 2 are identical except for the GUI mode used. The first uses MessageLoop mode:

#include <guiconstantsex.au3>

#include "GUIExtender.au3"

$hGUI = GUICreate("Test", 300, 390)

_GUIExtender_Init($hGUI)

_GUIExtender_Section_Start(0, 60)
GUICtrlCreateGroup(" 1 - Static ", 10, 10, 280, 50)
_GUIExtender_Section_Action(2, "", "", 270, 40, 15, 15) ; Normal button
_GUIExtender_Section_End()

_GUIExtender_Section_Start(60, 110)
GUICtrlCreateGroup(" 2 - Extendable ", 10, 70, 280, 100)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(170, 60)
GUICtrlCreateGroup(" 3 - Static", 10, 180, 280, 50)
_GUIExtender_Section_Action(4, "Close 4", "Open 4", 225, 195, 60, 20, 1) ; Push button
_GUIExtender_Section_End()

_GUIExtender_Section_Start(230, 60)
GUICtrlCreateGroup(" 4 - Extendable ", 10, 240, 280, 50)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(290, 90)
GUICtrlCreateGroup(" 5 - Static", 10, 300, 280, 80)
_GUIExtender_Section_Action(0, "Close All", "Open All", 20, 340, 60, 20) ; Normal button
_GUIExtender_Section_End()

GUICtrlCreateGroup("", -99, -99, 1, 1)

_GUIExtender_Section_Extend(4, False)

GUISetState()

While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    _GUIExtender_Action($iMsg) ; Check for click on Action control
WEnd

And this one uses OnEvent mode:

#include <guiconstantsex.au3>

#include "GUIExtender.au3"

Opt("GUIOnEventMode", 1)

$hGUI = GUICreate("Test", 300, 390)
GUISetOnEvent($GUI_EVENT_CLOSE, "On_Exit")

_GUIExtender_Init($hGUI)

_GUIExtender_Section_Start(0, 70)
GUICtrlCreateGroup(" 1 - Static ", 10, 10, 280, 50)
_GUIExtender_Section_Action(2, "", "", 270, 40, 15, 15, 0, 1) ; Normal button
_GUIExtender_Section_End()

_GUIExtender_Section_Start(70, 110)
GUICtrlCreateGroup("2 - Extendable ", 10, 70, 280, 100)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(180, 60)
GUICtrlCreateGroup(" 3 - Static ", 10, 180, 280, 50)
$iRet = _GUIExtender_Section_Action(4, "Close 4", "Open 4", 225, 205, 60, 20, 1, 1) ; Push button
ConsoleWrite($iRet & @CRLF)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(240, 60)
GUICtrlCreateGroup("4 - Extendable ", 10, 240, 280, 50)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(300, 90)
GUICtrlCreateGroup(" 5 - Static ", 10, 300, 280, 80)
_GUIExtender_Section_Action(0, "Close All", "Open All", 20, 340, 60, 20, 0, 1) ; Normal button
_GUIExtender_Section_End()

GUICtrlCreateGroup("", -99, -99, 1, 1)

_GUIExtender_Section_Extend(4, False)

GUISetState()

While 1
    Sleep(10)
WEnd

Func On_Exit()
    Exit
EndFunc

While this example shows very similar sections opening horizontally:

#include <guiconstantsex.au3>

#include "GUIExtender.au3"

$hGUI = GUICreate("Test", 500, 200)

; Set the horizontal parameter
_GUIExtender_Init($hGUI, 1)

_GUIExtender_Section_Start(0, 100)
GUICtrlCreateGroup(" 1 - Static ", 10, 10, 80, 180)
_GUIExtender_Section_Action(2, "", "", 70, 20, 15, 15)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(100, 100)
GUICtrlCreateGroup(" 2 - Extendable ", 110, 10, 80, 180)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(200, 100)
GUICtrlCreateGroup(" 3 - Static", 210, 10, 80, 180)
_GUIExtender_Section_Action(4, "Close 4", "Open 4", 220, 90, 60, 20, 1) ; Push button
_GUIExtender_Section_End()

_GUIExtender_Section_Start(300, 100)
GUICtrlCreateGroup(" 4 - Extendable", 310, 10, 80, 180)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(400, 100)
GUICtrlCreateGroup(" 5 - Static", 410, 10, 80, 180)
_GUIExtender_Section_Action(0, "Close All", "Open All", 420, 160, 60, 20) ; Normal button
_GUIExtender_Section_End()

GUICtrlCreateGroup("", -99, -99, 1, 1)

_GUIExtender_Section_Extend(2, False)

GUISetState()

While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    _GUIExtender_Action($iMsg) ; Check for click on Action control
WEnd

Here is a complete commented example showing how the various sections are fully functional and how they can be actioned by other controls (menu items in this case). Try synchronising the Progress with the Slider - or adding a Combo value to the List:

#include <guiconstantsex.au3>
#include <progressconstants.au3>
#include <sendmessage.au3>

#include "GUIExtender.au3"

; Create GUI full size
$hGUI = GUICreate("Test", 300, 380)

; Create menu
$mFileMenu = GUICtrlCreateMenu("&File")
$mExit_Menu_Item = GUICtrlCreateMenuItem("&Exit", $mFileMenu)
$mViewMenu = GUICtrlCreateMenu("&View")
$mCode_Menu_Item = GUICtrlCreateMenuItem("&Menu Only", $mViewMenu)
$mMore_Menu_Item = GUICtrlCreateMenuItem("&More", $mViewMenu)
$mEdit_Menu_Item = GUICtrlCreateMenuItem("&Edit", $mViewMenu)

; Initialise UDF
_GUIExtender_Init($hGUI)

; Create the controls as normal - but add the section start, end and action lines where needed

$iCode_Section = _GUIExtender_Section_Start(0, 30)
; Here we are creating a action control for this section to be used programmatically - so no parameters required
_GUIExtender_Section_Action($iCode_Section)
GUICtrlCreateLabel("GUIExtender UDF from Melba23.  I hope you like it!", 10, 10, 250, 20)
_GUIExtender_Section_End()

$iThis_Section = _GUIExtender_Section_Start(30, 50)
$hButton_1 = GUICtrlCreateButton("About", 20, 45, 80, 25)
GUICtrlCreateLabel("More...", 235, 60, 35, 15)
; Here we are creating an action control to appear on the GUI
_GUIExtender_Section_Action($iThis_Section + 1, "", "", 270, 60, 15, 15) ; Note easy way to denote next section
_GUIExtender_Section_End()

$iMore_Section = _GUIExtender_Section_Start(80, 110) ; Save the section ID as a variable to use later
$hButton_2 = GUICtrlCreateButton("Sync", 20, 95, 80, 25)
GUIStartGroup()
$hRadio_1 = GUICtrlCreateRadio("Green", 120, 95, 60, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$hRadio_2 = GUICtrlCreateRadio("Red", 180, 95, 60, 20)
$hRadio_3 = GUICtrlCreateRadio("Yellow", 240, 95, 60, 20)
$hProgress = GUICtrlCreateProgress(25, 130, 250, 15)
GUICtrlSetData(-1, 50)
$hSlider = GUICtrlCreateSlider(25, 155, 250, 20)
GUICtrlSetData(-1, 50)

_GUIExtender_Section_End()

$iThis_Section = _GUIExtender_Section_Start(190, 140)
$hCombo = GUICtrlCreateCombo("", 20, 200, 260, 20)
GUICtrlSetData(-1, "Alpha|Bravo|Charlie|Delta", "Alpha")
$hList = GUICtrlCreateList("", 25, 240, 180, 80, 0x00200000)
GUICtrlSetData(-1, "One|Two|Three")
; Another action control to appear on the GUI
_GUIExtender_Section_Action($iThis_Section + 1, "Close", "Input", 210, 290, 60, 20, 1)
_GUIExtender_Section_End()

$iInput_Section = _GUIExtender_Section_Start(330, 40)
$hInput = GUICtrlCreateInput("Your input goes here", 20, 330, 180, 20)
$hButton_3 = GUICtrlCreateButton("OK", 210, 330, 60, 20)
_GUIExtender_Section_End()

GUICtrlCreateGroup("", -99, -99, 1, 1)

; Retract all extendable sections
_GUIExtender_Section_Extend(0, False)

GUISetState()

While 1

    $iMsg = GUIGetMsg()
    ; Check for normal AutoIt controls
    Switch $iMsg
        Case $GUI_EVENT_CLOSE, $mExit_Menu_Item
            Exit
        Case $mMore_Menu_Item
            If BitAND(GUICtrlRead($mMore_Menu_Item), $GUI_CHECKED) = $GUI_CHECKED Then
                _GUIExtender_Section_Extend($iMore_Section, False)
                GUICtrlSetState($mMore_Menu_Item, $GUI_UNCHECKED)
            Else
                _GUIExtender_Section_Extend($iMore_Section)
                GUICtrlSetState($mMore_Menu_Item, $GUI_CHECKED)
            EndIf
        Case $mEdit_Menu_Item
            If BitAND(GUICtrlRead($mEdit_Menu_Item), $GUI_CHECKED) = $GUI_CHECKED Then
                _GUIExtender_Section_Extend($iInput_Section, False)
                GUICtrlSetState($mEdit_Menu_Item, $GUI_UNCHECKED)
            Else
                _GUIExtender_Section_Extend($iInput_Section)
                GUICtrlSetState($mEdit_Menu_Item, $GUI_CHECKED)
            EndIf
        Case $mCode_Menu_Item
            If BitAND(GUICtrlRead($mCode_Menu_Item), $GUI_CHECKED) = $GUI_CHECKED Then
                _GUIExtender_Section_Extend($iCode_Section, False)
                GUICtrlSetState($mCode_Menu_Item, $GUI_UNCHECKED)
            Else
                _GUIExtender_Section_Extend($iCode_Section)
                GUICtrlSetState($mCode_Menu_Item, $GUI_CHECKED)
            EndIf
        Case $hButton_1
            MsgBox(0, "GUIExtender Demo", "Use the various buttons and menu items" & @CRLF & "to extend and retract hidden areas of the GUI")
        Case $hButton_2
            GUICtrlSetData($hProgress, GUICtrlRead($hSlider) + 1)
            GUICtrlSetData($hProgress, GUICtrlRead($hSlider))
        Case $hRadio_1
            _SendMessage(GUICtrlGetHandle($hProgress), $PBM_SETSTATE, 1)
        Case $hRadio_2
            _SendMessage(GUICtrlGetHandle($hProgress), $PBM_SETSTATE, 2)
        Case $hRadio_3
            _SendMessage(GUICtrlGetHandle($hProgress), $PBM_SETSTATE, 3)
        Case $hCombo
            GUICtrlSetData($hInput, GUICtrlRead($hCombo))
        Case $hButton_3
            GUICtrlSetData($hList, GUICtrlRead($hInput))


    EndSwitch
    ; Check for GUIExtender controls
    _GUIExtender_Action($iMsg)

    ; Keep menu items in sync with the section state
    If _GUIExtender_Section_State($iMore_Section) = 0 And BitAND(GUICtrlRead($mMore_Menu_Item), $GUI_CHECKED) = $GUI_CHECKED Then
        GUICtrlSetState($mMore_Menu_Item, $GUI_UNCHECKED)
    ElseIf _GUIExtender_Section_State($iMore_Section) = 1 And BitAND(GUICtrlRead($mMore_Menu_Item), $GUI_CHECKED) <> $GUI_CHECKED Then
        GUICtrlSetState($mMore_Menu_Item, $GUI_CHECKED)
    EndIf
    If _GUIExtender_Section_State($iInput_Section) = 0 And BitAND(GUICtrlRead($mEdit_Menu_Item), $GUI_CHECKED) = $GUI_CHECKED Then
        GUICtrlSetState($mEdit_Menu_Item, $GUI_UNCHECKED)
    ElseIf _GUIExtender_Section_State($iInput_Section) = 1 And BitAND(GUICtrlRead($mEdit_Menu_Item), $GUI_CHECKED) <> $GUI_CHECKED Then
        GUICtrlSetState($mEdit_Menu_Item, $GUI_CHECKED)
    EndIf

WEnd

Here is an example showing how you can create a multirole GUI which varies in function depending on what you want at that moment. Note that this example is for proof of concept only and the sections are non-functional - if you want them to work - write the code yourself! : But to compensate for this the example shows what I think is the easiest way to write the section code - look for the <<<<<<<<< lines: :>

#include <guiconstantsex.au3>

#include "GUIExtender.au3"

$hGUI = GUICreate("Multirole GUI", 280, 530)

_GUIExtender_Init($hGUI)

$hButton_1 = GUICtrlCreateButton("Edit",  10, 5, 80, 20)
$hButton_2 = GUICtrlCreateButton("Check", 100, 5, 80, 20)
$hButton_3 = GUICtrlCreateButton("Combo", 190, 5, 80, 20)

; I have found this to be the best way to set the section dimensions - see further comments below  <<<<<<<<<<<<<
$iEdit_Section_Start = 30
$iEdit_Section_Height = 260
$iEdit_Section = _GUIExtender_Section_Start($iEdit_Section_Start, $iEdit_Section_Height)
_GUIExtender_Section_Action($iEdit_Section)
; All control positions can then be related to the section start rather than the GUI  <<<<<<<<<<<<<
GUICtrlCreateEdit("This is an edit", 10, $iEdit_Section_Start + 10, 260, 200)
GUICtrlCreateButton("Cancel", 10, $iEdit_Section_Start + 220, 80, 30)
GUICtrlCreateButton("Save", 180, $iEdit_Section_Start + 220, 80, 30)
; Now you can check that the _Section_Height is correct and amend if necessary  <<<<<<<<<<<<<
_GUIExtender_Section_End()

; And it is really easy to set the new section start  <<<<<<<<<<<<<
$iCheck_Section_Start = $iEdit_Section_Start + $iEdit_Section_Height
$iCheck_Section_Height = 100
$iCheck_Section = _GUIExtender_Section_Start($iCheck_Section_Start, $iCheck_Section_Height)
_GUIExtender_Section_Action($iCheck_Section)
GUICtrlCreateCheckbox(" Option 1", 20, $iCheck_Section_Start + 10, 130, 20)
GUICtrlCreateCheckbox(" Option 2", 150, $iCheck_Section_Start + 10, 130, 20)
GUICtrlCreateCheckbox(" Option 3", 20, $iCheck_Section_Start + 30, 130, 20)
GUICtrlCreateCheckbox(" Option 4", 150, $iCheck_Section_Start + 30, 130, 20)
GUICtrlCreateButton("Save", 180, $iCheck_Section_Start + 60, 80, 30)
_GUIExtender_Section_End()

$iCombo_Section_Start = $iCheck_Section_Start + $iCheck_Section_Height
$iCombo_Section_Height = 140
$iCombo_Section = _GUIExtender_Section_Start($iCombo_Section_Start, $iCombo_Section_Height)
_GUIExtender_Section_Action($iCombo_Section)
GUICtrlCreateCombo("", 20, $iCombo_Section_Start + 10, 240, 20)
GUICtrlSetData(-1, "Alpha|Bravo|Charlie", "Alpha")
GUICtrlCreateCombo("", 20, $iCombo_Section_Start + 40, 240, 20)
GUICtrlSetData(-1, "Lima|Mike|November", "Mike")
GUICtrlCreateCombo("", 20, $iCombo_Section_Start + 70, 240, 20)
GUICtrlSetData(-1, "Xray|Yankee|Zulu", "Zulu")
GUICtrlCreateButton("Confirm", 100, $iCombo_Section_Start + 100, 80, 30)
; And here you can check the overall GUI height to make sure it all fits in!  <<<<<<<<<<<<<
_GUIExtender_Section_End()

_GUIExtender_Section_Extend(0, False)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        ; Run Restore function if GUI is restored from MINIMIZE
        Case $GUI_EVENT_RESTORE
            _GUIExtender_Restore()
        ; If section required
        Case $hButton_1
            ; Check section state
            Switch _GUIExtender_Section_State($iEdit_Section)
                ; If retracted
                Case 0
                    ; Disable other buttons
                    GUICtrlSetState($hButton_2, $GUI_DISABLE)
                    GUICtrlSetState($hButton_3, $GUI_DISABLE)
                    ; Extend section
                    _GUIExtender_Section_Extend($iEdit_Section)
                Case Else
                    ; Re-enable other buttons
                    GUICtrlSetState($hButton_2, $GUI_ENABLE)
                    GUICtrlSetState($hButton_3, $GUI_ENABLE)
                    ; Retract section
                    _GUIExtender_Section_Extend($iEdit_Section, False)
            EndSwitch
        Case $hButton_2
            Switch _GUIExtender_Section_State($iCheck_Section)
                Case 0
                    GUICtrlSetState($hButton_1, $GUI_DISABLE)
                    GUICtrlSetState($hButton_3, $GUI_DISABLE)
                    _GUIExtender_Section_Extend($iCheck_Section)
                Case Else
                    GUICtrlSetState($hButton_1, $GUI_ENABLE)
                    GUICtrlSetState($hButton_3, $GUI_ENABLE)
                    _GUIExtender_Section_Extend($iCheck_Section, False)
            EndSwitch
        Case $hButton_3
            Switch _GUIExtender_Section_State($iCombo_Section)
                Case 0
                    GUICtrlSetState($hButton_1, $GUI_DISABLE)
                    GUICtrlSetState($hButton_2, $GUI_DISABLE)
                    _GUIExtender_Section_Extend($iCombo_Section)
                Case Else
                    GUICtrlSetState($hButton_1, $GUI_ENABLE)
                    GUICtrlSetState($hButton_2, $GUI_ENABLE)
                    _GUIExtender_Section_Extend($iCombo_Section, False)
            EndSwitch
    EndSwitch

WEnd

An example showing how to use the UDF with embedded objects and HotKeys to action the section:

#include <guiconstantsex.au3>
#include <ie.au3>

#include "GUIExtender.au3"

HotKeySet("^{F1}","_Action_Section_1")
HotKeySet("^{F2}","_Action_Section_2")

$hGUI = GUICreate("", 750, 770)
GUISetBkColor(0xC0C0C0)

_GUIExtender_Init($hGUI)

GUICtrlCreateLabel("Press Ctrl - F1 or Ctrl - F2 to toggle embedded objects", 10, 10, 730, 30)
GUICtrlSetFont(-1, 15)

_GUIExtender_Section_Start(40, 370)
_GUIExtender_Section_Action(1)

Global $oIE_1 = _IECreateEmbedded()
Global $hIE_1 = GUICtrlCreateObj($oIE_1, 10, 50, 730, 350)
_IENavigate ($oIE_1, "http://www.autoitscript.com")
_GUIExtender_Obj_Data($hIE_1, $oIE_1) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< New function

_GUIExtender_Section_End()

_GUIExtender_Section_Start(410, 170)

$tab = GUICtrlCreateTab(10, 410, 730, 150)
ConsoleWrite("Main = " & GUICtrlGetHandle($tab) & @CRLF)

$tab0 = GUICtrlCreateTabItem("tab 0")

$tab1 = GUICtrlCreateTabItem("tab 1")

GUICtrlCreateTabItem("")

_GUIExtender_Section_End()

_GUIExtender_Section_Start(580, 200)

Global $oIE_2 = ObjCreate("Shell.Explorer.2")
Global $hIE_2 = GUICtrlCreateObj($oIE_2, 10, 570, 730, 180)
$oIE_2.navigate(@MyDocumentsDir)
_GUIExtender_Obj_Data($hIE_2, $oIE_2) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< New function

_GUIExtender_Section_End()

_GUIExtender_Section_Extend(1, False)
_GUIExtender_Section_Extend(3, False)

GUISetState()

While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    _GUIExtender_Action($iMsg)
WEnd

Func _Action_Section_1()
    _GUIExtender_Section_Extend(1, Not(_GUIExtender_Section_State(1)))
EndFunc

Func _Action_Section_2()
    _GUIExtender_Section_Extend(3, Not(_GUIExtender_Section_State(3)))
EndFunc

An example to show how to code for child GUIs which use the UDF:

#include <guiconstantsex.au3>

#include "GUIExtender.au3"

$hGUI = GUICreate("Test", 300, 390)

$Button = GUICtrlCreateButton("Test", 10, 20, 70, 22)

GUISetState()

While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $Button
            _Child()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _Child()
    $hGUI_Child = GUICreate("Child", 250, 170)

    _GUIExtender_Init($hGUI_Child)

    _GUIExtender_Section_Start(0, 70)
    GUICtrlCreateGroup(" 1 - Static ", 10, 10, 230, 50)
    _GUIExtender_Section_Action(2, "", "", 220, 40, 15, 15) ; Normal button
    _GUIExtender_Section_End()

    _GUIExtender_Section_Start(70, 100)
    GUICtrlCreateGroup(" 2 - Extendable ", 10, 70, 230, 90)
    _GUIExtender_Section_End()

    GUICtrlCreateGroup("", -99, -99, 1, 1)

    GUISetState()

    While 1
        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                GUIDelete($hGUI_Child)
                _GUIExtender_Clear() ; If this is omitted, the script will crash when the child is created a second time
                Return
        EndSwitch
        _GUIExtender_Action($iMsg) ; Check for click on Action control
    WEnd
EndFunc

An example showing how to use the _GUIExtender_ActionCheck and _GUIExtender_UDFCtrlCheck functions in MessageLoop mode:

#include <guiconstantsex.au3>
#include <windowsconstants.au3>

#include <guibutton.au3>
#include <guicombobox.au3>

#include "GUIExtender.au3"

$hGUI = GUICreate("Test", 300, 440)

_GUIExtender_Init($hGUI)

_GUIExtender_Section_Start(50, 60)
GUICtrlCreateGroup(" 1 - Static ", 10, 50, 280, 50)
_GUIExtender_Section_Action(2, "", "", 270, 80, 15, 15) ; Normal button
_GUIExtender_Section_End()

_GUIExtender_Section_Start(110, 110)
GUICtrlCreateGroup(" 2 - Extendable ", 10, 120, 280, 100)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(220, 60)
GUICtrlCreateGroup(" 3 - Static", 10, 230, 280, 50)
_GUIExtender_Section_Action(4, "Close 4", "Open 4", 225, 245, 60, 20, 1) ; Push button
_GUIExtender_Section_End()

_GUIExtender_Section_Start(280, 60)
GUICtrlCreateGroup(" 4 - Extendable ", 10, 290, 280, 50)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(340, 90)
GUICtrlCreateGroup(" 5 - Static", 10, 350, 280, 80)
_GUIExtender_Section_Action(0, "Close All", "Open All", 20, 390, 60, 20) ; Normal button
_GUIExtender_Section_End()

GUICtrlCreateGroup("", -99, -99, 1, 1)

; Create the combo
$hCombo = _GUICtrlComboBox_Create($hGUI, "", 120, 310, 60, 20, $CBS_DROPDOWN); BitOR($CBS_DROPDOWN, $WS_VSCROLL, $WS_TABSTOP, $CBS_UPPERCASE))
_GUICtrlComboBox_BeginUpdate($hCombo)
_GUICtrlComboBox_AddString($hCombo, "ONE")
_GUICtrlComboBox_AddString($hCombo, "TWO")
_GUICtrlComboBox_AddString($hCombo, "THREE")
_GUICtrlComboBox_EndUpdate($hCombo)

; Create a button
$hButton = _GUICtrlButton_Create($hGUI, "Button", 120, 150, 60, 40)

_GUIExtender_Section_Extend(4, False)
_GUIExtender_UDFCtrlCheck($hButton, 2, 120, 40)
_GUIExtender_UDFCtrlCheck($hCombo, 4, 120, 30)

GUISetState()

While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch

    _GUIExtender_Action($iMsg) ; Check for click on Action control

    ; Check UDF control visibility if an Action control was pressed
    If _GUIExtender_ActionCheck() Then
        ; Parameters: (Handle, Section, X-coord, Y-coord) - note coords are relative to the section, not the main GUI
        _GUIExtender_UDFCtrlCheck($hButton, 2, 120, 40)
        _GUIExtender_UDFCtrlCheck($hCombo, 4, 120, 30)
    EndIf
WEnd

And another example showing how to use the _GUIExtender_ActionCheck and _GUIExtender_UDFCtrlCheck functions in OnEvent mode:

#include <guiconstantsex.au3>

#include <guibutton.au3>
#include <guicombobox.au3>

#include "GUIExtender.au3"

Opt("GUIOnEventMode", 1)

$hGUI = GUICreate("Test", 300, 390)
GUISetOnEvent($GUI_EVENT_CLOSE, "On_Exit")

_GUIExtender_Init($hGUI)

_GUIExtender_Section_Start(0, 70)
GUICtrlCreateGroup(" 1 - Static ", 10, 10, 280, 50)
_GUIExtender_Section_Action(2, "", "", 270, 40, 15, 15, 0, 1) ; Normal button
_GUIExtender_Section_End()

_GUIExtender_Section_Start(70, 110)
GUICtrlCreateGroup("2 - Extendable ", 10, 70, 280, 100)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(180, 60)
GUICtrlCreateGroup(" 3 - Static ", 10, 180, 280, 50)
$iRet = _GUIExtender_Section_Action(4, "Close 4", "Open 4", 225, 205, 60, 20, 1, 1) ; Push button
ConsoleWrite($iRet & @CRLF)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(240, 60)
GUICtrlCreateGroup("4 - Extendable ", 10, 240, 280, 50)
_GUIExtender_Section_End()

_GUIExtender_Section_Start(300, 90)
GUICtrlCreateGroup(" 5 - Static ", 10, 300, 280, 80)
_GUIExtender_Section_Action(0, "Close All", "Open All", 20, 340, 60, 20, 0, 1) ; Normal button
_GUIExtender_Section_End()

GUICtrlCreateGroup("", -99, -99, 1, 1)

; Create the combo
$hCombo = _GUICtrlComboBox_Create($hGUI, "", 120, 260, 60, 20, $CBS_DROPDOWN); BitOR($CBS_DROPDOWN, $WS_VSCROLL, $WS_TABSTOP, $CBS_UPPERCASE))
_GUICtrlComboBox_BeginUpdate($hCombo)
_GUICtrlComboBox_AddString($hCombo, "ONE")
_GUICtrlComboBox_AddString($hCombo, "TWO")
_GUICtrlComboBox_AddString($hCombo, "THREE")
_GUICtrlComboBox_EndUpdate($hCombo)

; Create a button
$hButton = _GUICtrlButton_Create($hGUI, "Button", 120, 100, 60, 40)

_GUIExtender_Section_Extend(4, False)
_GUIExtender_UDFCtrlCheck($hButton, 2, 120, 40)
_GUIExtender_UDFCtrlCheck($hCombo, 4, 120, 20)

GUISetState()

While 1
    Sleep(10)
    ; Check UDF control visibility if an Action control was pressed
    If _GUIExtender_ActionCheck() Then
        ; Parameters: (Handle, Section, X-coord, Y-coord) - note coords are relative to the section, not the main GUI
        _GUIExtender_UDFCtrlCheck($hButton, 2, 120, 40)
        _GUIExtender_UDFCtrlCheck($hCombo, 4, 120, 20)
    EndIf
WEnd

Func On_Exit()
    Exit
EndFunc

New An example showing all possible extension and retraction modes using the $iFixed parameter:

#include <GUIConstantsEx.au3>

#include "GUIExtender.au3"

$hGUI = GUICreate("Move Example", 250, 230)

GUICtrlCreateGroup(" Choose Orientation ", 10, 10, 230, 80)

$cRadio_Horz = GUICtrlCreateRadio(" Horizontal ", 20, 30, 100, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$cRadio_Vert = GUICtrlCreateRadio(" Vertical ", 20, 60, 100, 20)

GUICtrlCreateGroup(" Choose Move Style ", 10, 100, 230, 110)

$cRadio_0 = GUICtrlCreateRadio(" Fix Left ", 20, 120, 100, 20)
$cRadio_1 = GUICtrlCreateRadio(" Fix Centre ", 20, 150, 100, 20)
$cRadio_2 = GUICtrlCreateRadio(" Fix Right ", 20, 180, 100, 20)

GUICtrlCreateGroup("", -99, -99, 1, 1)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cRadio_Horz
            GUICtrlSetData($cRadio_0, " Fix Left ")
            GUICtrlSetState($cRadio_0, $GUI_UNCHECKED)
            GUICtrlSetState($cRadio_1, $GUI_UNCHECKED)
            GUICtrlSetData($cRadio_2, " Fix Right ")
            GUICtrlSetState($cRadio_2, $GUI_UNCHECKED)
        Case $cRadio_Vert
            GUICtrlSetData($cRadio_0, " Fix Top ")
            GUICtrlSetState($cRadio_0, $GUI_UNCHECKED)
            GUICtrlSetState($cRadio_1, $GUI_UNCHECKED)
            GUICtrlSetData($cRadio_2, " Fix Bottom ")
            GUICtrlSetState($cRadio_2, $GUI_UNCHECKED)
        Case $cRadio_0
            _Create_GUI(0)
        Case $cRadio_1
            _Create_GUI(1)
        Case $cRadio_2
            _Create_GUI(2)
    EndSwitch

WEnd

Func _Create_GUI($iMove)

    Local $sTitle

    Switch $iMove
        Case 0
            If GUICtrlRead($cRadio_Horz) = 1 Then
                $sTitle = "Fixed Left"
            Else
                $sTitle = "Fixed Top"
            EndIf
        Case 1
            $sTitle = "Fixed Centre"
        Case 2
            If GUICtrlRead($cRadio_Horz) = 1 Then
                $sTitle = "Fixed Right"
            Else
                $sTitle = "Fixed Bottom"
            EndIf
    EndSwitch

    GUISetState(@SW_HIDE, $hGUI)

    $hGUI_Ex = GUICreate($sTitle, 500, 500)

    If GUICtrlRead($cRadio_Horz) = 1 Then

        _GUIExtender_Init($hGUI_Ex, 1, $iMove)
        _GUIExtender_Section_Start(0, 250)
        _GUIExtender_Section_Action(2, "", "", 220, 10, 20, 20)
        _GUIExtender_Section_End()
        _GUIExtender_Section_Start(250, 250)
        GUICtrlCreateLabel("", 250, 0, 250, 500)
        GUICtrlSetBkColor(-1, 0xFFCCCC)
        _GUIExtender_Section_End()

    Else

        _GUIExtender_Init($hGUI_Ex, 0, $iMove)
        _GUIExtender_Section_Start(250, 0)
        _GUIExtender_Section_Action(2, "", "", 470, 220, 20, 20)
        _GUIExtender_Section_End()
        _GUIExtender_Section_Start(250, 250)
        GUICtrlCreateLabel("", 0, 250, 500, 250)
        GUICtrlSetBkColor(-1, 0xFFCCCC)
        _GUIExtender_Section_End()

    EndIf

    _GUIExtender_Section_Extend(2, False)

    GUISetState()

    While 1

        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                GUISetState(@SW_SHOW, $hGUI)
                GUIDelete($hGUI_Ex)
                _GUIExtender_Clear()
                ExitLoop
        EndSwitch

        _GUIExtender_Action($iMsg) ; Check for click on Action control

    WEnd

EndFunc

New An example showing how to override the default $iFixed setting for a section:

#include <GUIConstantsEx.au3>

#include "GUIExtender.au3"

$hGUI = GUICreate("Test", 400, 300)

_GUIExtender_Init($hGUI, 1)
_GUIExtender_Section_Start(0, 100)
_GUIExtender_Section_Action(1)
GUICtrlCreateLabel("", 0, 0, 100, 300)
GUICtrlSetBkColor(-1, 0xFFCCCC)
_GUIExtender_Section_End()
_GUIExtender_Section_Start(100, 200)
$cButton_1 = GUICtrlCreateButton(">>", 110, 10, 20, 30)
$cButton_2 = GUICtrlCreateButton("<<", 260, 10, 20, 30)
_GUIExtender_Section_End()
_GUIExtender_Section_Start(300, 100)
_GUIExtender_Section_Action(3)
GUICtrlCreateLabel("", 300, 0, 100, 300)
GUICtrlSetBkColor(-1, 0xCCFFCC)
_GUIExtender_Section_End()

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cButton_1
            Switch _GUIExtender_Section_State(1)
                Case 0
                    ; Extend to the left - override default
                    _GUIExtender_Section_Extend(1, True, 2)
                    GUICtrlSetData($cButton_1, ">>")
                Case 1
                    ; Retract from the left - override default
                    _GUIExtender_Section_Extend(1, False, 2)
                    GUICtrlSetData($cButton_1, "<<")
            EndSwitch
        Case  $cButton_2
            Switch _GUIExtender_Section_State(3)
                Case 0
                    ; Extend to the right (default)
                    _GUIExtender_Section_Extend(3)
                    GUICtrlSetData($cButton_2, "<<")
                Case 1
                    ; Retract from the right (default
                    _GUIExtender_Section_Extend(3, False)
                    GUICtrlSetData($cButton_2, ">>")
            EndSwitch
    EndSwitch

WEnd

Some details for the curious among you who might want to know a bit more about how GUIExtender works:

The UDF stores coordinates and details of the various sections and their controls in a Global array which it accesses as required.

When a section is started, the UDF creates a small anchor label which it uses to keep track of where the section is currently located. If a section is retracted, the controls within it are moved to the right of the visible GUI and the subsequent sections moved up to fill the gap. The reverse happens when a section is extended - the section controls are moved back into the correct place in the GUI and subsequent sections moved down. In both cases the GUI is resized to fit the visible sections and the section controls are all moved relative to the section anchor. As the hidden controls are off the visible GUI, there is no overlap problem with the controls on the GUI.

Sections are static unless you set an action control. The UDF can create a button on the GUI automatically, but you can also action a section programatically. However, although the UDF button is automatically synchronised with the section state, if you use your own control you have to take care of that yourself - but there is a function which returns the current state to help you and the examples show how to do it :) . You can choose normal or push-style buttons as action controls, as well as the text to display. You can set invisible action controls if only progammatic action required for a section (see examples).

In OnEvent mode, the UDF automatically links these action controls to an internal function which activates the sections without user intervention - in MessageLoop mode, the GUIGetMsg return is passed to the UDF for checking and actioning if necessary.

You can have controls at the top of the GUI which do not need to be in a section (see the MultiRole example) but once you have started declaring sections, all subsequent controls must be within one or the UDF will not know that they exist and so will not be able to rearrange them when needed.

When dealing with UDF_created controls the UDF determines if the section containing the control is extended or retracted. If retracted the control is hidden - if extended the UDF calculates where the control should be depending on the state of the earlier sections and moves it to that point.

New - And finally, the GUIExtender UDF itself - just put it in the same folder as the examples:

#include-once

; #INDEX# ============================================================================================================
; Title .........: GUIExtender
; AutoIt Version : v3.3 or higher
; Language ......: English
; Description ...: Extends and retracts user-defined sections of a GUI either vertically or horizontally
; Remarks .......:
; Note ..........:
; Author(s) .....: Melba23
; ====================================================================================================================

;#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

; #GLOBAL VARIABLES# =================================================================================================
; Declare array to hold section data
Global $aGUIExt_Section_Data[1][9] = [[0, 0, 1, 0, "", 9999]]
; [0][0] = Section count                                            [n][0] = Initial section X/Y-coord
; [0][1] = Orientation - 0 = Vertical, 1 = Horizontal               [n][1] = Section height/width (inc border)
; [0][2] = All state - 0 = all retracted, 1 = at least 1 extended   [n][2] = Section state - 0 = Retracted, 1 = extended, 2 = static
; [0][3] = GUI handle                                               [n][3] = Section anchor ControlID (invisible disabled label)
; [0][4] = Fixed point - 0 = Left/Top, 1 = Centre, 2 = Right/Bottom [n][4] = Section final ControlID
; [0][5] = Action all button ControlID                              [n][5] = Section action button ControlID
; [0][6] = Action all button extended text                          [n][6] = Section action button extended text
; [0][7] = Action all button retracted text                         [n][7] = Section action button retracted text
; [0][8] = Action all button type                                   [n][8] = Section action button type

; Declare array to hold data about embedded objects
Global $aGUIExt_Obj_Data[1][2] = [[0]]
; [0][0] = Object count
; [n][0] = Embedded object ControlID
; [n][1] = Original object handle

; Declare flag for section action
Global $fGUIExt_SectionAction = False

; #CURRENT# ==========================================================================================================
; _GUIExtender_Init:           Initialises the GUI containing the sections and sets orientation and fixed point
; _GUIExtender_Section_Start:  Marks the start point of GUI section
; _GUIExtender_Section_End:    Marks the end of a GUI section
; _GUIExtender_Section_Action: Creates normal or push buttons to action extension or retraction of GUI sections
; _GUIExtender_Action:         Used in GUIGetMsg loops to detect clicks on section action buttons
; _GUIExtender_Restore:        Used reset GUI after a MINIMIZE and RESTORE
; _GUIExtender_Section_Extend: Actions section extension or retraction programatically or via section action buttons
; _GUIExtender_Section_State:  Returns state of section
; _GUIExtender_UDFCtrlCheck:   Hides/Shows and moves UDF-created controls when sections are extended/retracted
; _GUIExtender_ActionCheck:    Indicates when sections are extended/retracted so that _GUIExtender_UDFCtrlCheck can be called
; _GUIExtender_Obj_Data:       Store additional info on embedded objects
; _GUIExtender_Clear:          Called on GUI deletion to clear the data array ready for a new GUI to be initialised
; ====================================================================================================================

; #INTERNAL_USE_ONLY#=================================================================================================
; _GUIExtender_Section_All_Extend:   Actions all moveable sections
; _GUIExtender_Section_Action_Event: Used to detect clicks on section action buttons in OnEvent mode
; ====================================================================================================================

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Init
; Description ...: Initialises the GUI containing the sections and sets orientation and fixed point
; Syntax.........: _GUIExtender_Init($hWnd[, $iOrient = 0[, $iFixed = 0]])
; Parameters ....: $hWnd - Handle of GUI containing the sections
;                  $iOrient - 0 = Vert - GUI extends and retracts in vertical sense
;                             1 = Horz - GUI extends and retracts in horizontal sense
;                  $iFixed  - 0 = GUI Left/Top fixed (Default)
;                             1 = GUI centre fixed
;                             2 = GUI Right/Bottom fixed
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns 1
;                  Failure:  Returns 0 and sets @error as follows:
;                  1 = Invalid handle
;                  2 = Existing initialisation
;                  3 = Invalid parameter with @extended set: 1 = $iOrient, 2 $iFixed
; Author ........: Melba23
; Remarks .......: This function should be called before any controls are created within the GUI
;                  Only one GUI can be initialised at any one time.  _GUIExtender_Clear must be called before a second
;                  GUI can be initialised.  The previous GUI loses all extension/retraction ability
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Init($hWnd, $iOrient = 0, $iFixed = 0)

    ; Check valid handle
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0)

    ; Check for existing initialisation
    If $aGUIExt_Section_Data[0][3] Then Return SetError(2, 0, 0)

    ; Check for valid parameters
    Switch $iOrient
        Case 0, 1
            ; Valid
        Case Else
            Return SetError(3, 1, 0)
    EndSwitch
    Switch $iFixed
        Case 0, 1, 2
            ; Valid
        Case Else
            Return SetError(3, 2, 0)
    EndSwitch

    ; Store GUI handle
    $aGUIExt_Section_Data[0][3] = $hWnd
    ; Store orientation
    $aGUIExt_Section_Data[0][1] = $iOrient
    ; Store fixed point
    $aGUIExt_Section_Data[0][4] = $iFixed
    ; Set resizing mode to prevent resizing of controls
    Opt("GUIResizeMode", 0x0322) ; $GUI_DOCKALL
    ; Set automatic restore function for OnEvent mode scripts
    GUISetOnEvent(-5, "_GUIExtender_Restore") ; $GUI_EVENT_RESTORE

    Return 1

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Section_Start
; Description ...: Marks the start point of GUI section
; Syntax.........: _GUIExtender_Section_Start($iSection_Coord, $iSection_Size)
; Parameters ....: $iSection_Coord - Coordinates of left/top edge of section depending on orientation
;                  $iSection_Size  - Width/Height of section
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns section ID
;                  Failure:  Returns 0 and sets @error as follows:
;                  1 = Section overlaps with previous section
; Author ........: Melba23
; Remarks .......: The function creates a disabled label to act as an anchor for the section position
;                  The function must be called BEFORE any controls in the section have been cretaed
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Section_Start($iSection_Coord, $iSection_Size)

    If $aGUIExt_Section_Data[0][0] > 1 Then
        ; Check section start is after previous section end
        If $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0] - 1][0] + $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0] - 1][1] > $iSection_Coord Then Return SetError(1, 0, 0)
    EndIf
    ; Add new section
    $aGUIExt_Section_Data[0][0] += 1
    ; ReDim array if required
    If UBound($aGUIExt_Section_Data) < $aGUIExt_Section_Data[0][0] + 1 Then
        ReDim $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0] + 1][9]
    EndIf
    ; Store passed position and size parameters
    $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][0] = $iSection_Coord
    $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][1] = $iSection_Size
    ; Set state to static if not already set
    If $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][2] = "" Then $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][2] = 2
    ; Create a zero size disabled label to act as an anchor for the section
    If $aGUIExt_Section_Data[0][1] Then ; Depending on orientation
        $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][3] = GUICtrlCreateLabel("", $iSection_Coord, 0, 1, 1)
    Else
        $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][3] = GUICtrlCreateLabel("", 0, $iSection_Coord, 1, 1)
    EndIf
    GUICtrlSetBkColor(-1, -2) ; $GUI_BKCOLOR_TRANSPARENT
    GUICtrlSetState(-1, 128) ; $GUI_DISABLE
    ; Set dummy action ControlID if needed
    If $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][5] = "" Then $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][5] = 9999

    ; Return section ID
    Return $aGUIExt_Section_Data[0][0]

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Section_End
; Description ...: Marks the end point of GUI section
; Syntax.........: _GUIExtender_Section_End()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Remarks .......: The function must be called AFTER all the controls in the section have been created
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Section_End()

    ; Determine End ControlID for the section
    $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][4] = GUICtrlCreateDummy() - 1

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Section_Action
; Description ...: Creates controls to action extension or retraction of GUI sections
; Syntax.........: _GUIExtender_Section_Action($iSection[, $sText_Extended = ""[, $sText_Retracted = ""[, $iX = 0[, $iY = 0[, $iW = 0[, $iH = 0[, $iType = 0[, $iEventMode = 0]]]]]]]]])
; Parameters ....: $iSection      - Section to action - 0 = all extendable sections
;                  $sText_Extended - Text on button when section is extended - default: small up/left arrow
;                  $sText_Retracted - Text on button when section is retracted - default: small down/right arrow
;                  $iX - Left side of the button
;                  $iY - Top of the button
;                  $iW - Width of the button
;                  $iH - Height of the button
;                  $iType - Type of button:
;                           0 = pushbutton (default)
;                           1 = normal button
;                  $iEventMode - Set to 1 if using OnEvent mode
;                           In this case, the control is automatically linked to the _GUIExtender_Section_Action_Event function
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns 1
;                  Failure:  Returns 0 and sets @error as follows:
;                  1 = Control not created
; Author ........: Melba23
; Remarks .......: Sections are static unless an action control has been set
;                  Omitting all optional parameters creates a section which can be actioned programmatically
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Section_Action($iSection, $sText_Extended = "", $sText_Retracted = "", $iX = 0, $iY = 0, $iW = 1, $iH = 1, $iType = 0, $iEventMode = 0)

    ; ReDim array if required
    If $iSection > 1 And UBound($aGUIExt_Section_Data) < $iSection + 1 Then
        ReDim $aGUIExt_Section_Data[$iSection + 1][9]
    EndIf
    ; Set state to extended indicating a extendable section
    $aGUIExt_Section_Data[$iSection][2] = 1
    ; If default arrows required
    Local $iDef_Arrows = 0
    If $sText_Extended = "" And $sText_Retracted = "" Then
        $iDef_Arrows = 1
        If $aGUIExt_Section_Data[0][1] Then ; Dependiing on orientation
            $sText_Extended = 3
            $sText_Retracted = 4
        Else
            $sText_Extended = 5
            $sText_Retracted = 6
        EndIf
    EndIf
    ; What type of button?
    Switch $iType
        ; Pushbutton
        Case 0
            ; Create normal button
            $aGUIExt_Section_Data[$iSection][5] = GUICtrlCreateButton($sText_Extended, $iX, $iY, $iW, $iH)
        Case Else
            ; Create pushbutton
            $aGUIExt_Section_Data[$iSection][5] = GUICtrlCreateCheckBox($sText_Extended, $iX, $iY, $iW, $iH, 0x1000) ; $BS_PUSHLIKE
            ; Set button state
            GUICtrlSetState(-1, 1) ; $GUI_CHECKED
    EndSwitch
    ; Check for error
    If $aGUIExt_Section_Data[$iSection][5] = 0 Then Return SetError(2, 0, 0)
    ; Change font if default arrows required
    If $iDef_Arrows Then GUICtrlSetFont($aGUIExt_Section_Data[$iSection][5], 10, 400, 0, "Webdings")
    ; Set event function if required
    If $iEventMode Then GUICtrlSetOnEvent($aGUIExt_Section_Data[$iSection][5], "_GUIExtender_Section_Action_Event")
    ; Store required text
    $aGUIExt_Section_Data[$iSection][6] = $sText_Extended
    $aGUIExt_Section_Data[$iSection][7] = $sText_Retracted
    ; Store button type
    $aGUIExt_Section_Data[$iSection][8] = $iType

    Return 1

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Action
; Description ...: Used in GUIGetMsg loops to detect clicks on section action buttons and $GUI_EVENT_RESTORE events
; Syntax.........: _GUIExtender_Action($iMsg)
; Parameters ....: $iMsg - Return from GUIGetMsg
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Remarks .......: The return from GUIGetMsg is passed to this function to determine if a section action control was clicked
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Action($iMsg)

    ; If GUI is restored, run the restore function
    If $iMsg = -5 Then _GUIExtender_Restore() ; $GUI_EVENT_RESTORE
    ; Check if an action control has been clicked
    For $i = 0 To $aGUIExt_Section_Data[0][0]
        ; If action button clicked
        If $iMsg = $aGUIExt_Section_Data[$i][5] Then
            ; Check current state
            Switch $aGUIExt_Section_Data[$i][2]
                Case 0
                    _GUIExtender_Section_Extend($i, True)
                Case Else
                    _GUIExtender_Section_Extend($i, False)
            EndSwitch
            ; Set flag for section action occurring
            $fGUIExt_SectionAction = True
        EndIf
    Next

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Restore
; Description ...: Used to reset GUI after a MINIMIZE and RESTORE
; Syntax.........: _GUIExtender_Restore()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: None
; Author ........: Melba23
; Remarks .......: The GUI is not correctly restored after a MINIMIZE if a section is retracted.  This function cycles
;                  the highest extendable section to reset the correct position of the controls
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Restore()

    ; Hide the GUI to prevent excess flicker
    GUISetState(@SW_HIDE, $aGUIExt_Section_Data[0][3])
    ; Look for the highest extendable function
    For $i = UBound($aGUIExt_Section_Data) - 1 To 1 Step -1
        If $aGUIExt_Section_Data[$i][2] <> 2 Then
            ; Depending on current state, cycle extendable section
            Switch $aGUIExt_Section_Data[$i][2]
                Case 0
                    _GUIExtender_Section_Extend($i)
                    _GUIExtender_Section_Extend($i, False)
                Case 1
                    _GUIExtender_Section_Extend($i, False)
                    _GUIExtender_Section_Extend($i)
            EndSwitch
            ExitLoop
        EndIf
    Next
    ; Show GUI again
    GUISetState(@SW_SHOW, $aGUIExt_Section_Data[0][3])

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Section_Extend
; Description ...: Actions section extension or retraction programatically or via section action buttons
; Syntax.........: _GUIExtender_Section_Extend($iSection[, $fExtend = True[, $iFixed]])
; Parameters ....: $iSection - Section to action - 0 = all moveable sections
;                  $fExtend  - True = extend; False = retract
;                  $iFixed    - 0 = Left/Top fixed
;                               1 = Expand/contract centred
;                               2 = Right/bottom fixed
;                               Any other value = Default as set by _GUIExtender_Init (default)
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns 1
;                  Failure:  Returns 0 and sets @error as follows:
;                  1 = Invalid section ID (@extended: 1 = not in array, 2 = no _Start function used)
;                  2 = Section already in required state
;                  3 = GUI minimized
; Author ........: Melba23
; Remarks .......: This function is called by the UDF when the section action buttons are clicked,
;                  but can also be called programatically
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Section_Extend($iSection, $fExtend = True, $iFixed = 9)

    Local $aPos, $iCID, $iDelta_GUI

    ; Check GUI is not minimized
    If BitAND(WinGetState($aGUIExt_Section_Data[0][3]), 16) Then Return SetError(3, 0, 0)

    ; Check if all sections to be actioned
    If $iSection = 0 Then
        _GUIExtender_Section_All_Extend($fExtend)
        Return 1
    EndIf

    ; Check for invalid section (either outside array or no _Start function called)
    If $iSection > UBound($aGUIExt_Section_Data) - 1 Then Return SetError(1, 1, 0)
    If $aGUIExt_Section_Data[$iSection][1] = "" Then Return SetError(1, 2, 0)

    ; Check if state already matches demand
    If ($aGUIExt_Section_Data[$iSection][2] = 1 And $fExtend = True) Or ($aGUIExt_Section_Data[$iSection][2] = 0 And $fExtend = False) Then Return SetError(2, 0, 0)

    ; Check Move state
    Switch $iFixed
        Case 0, 1, 2
            ; Do nothing
        Case Else
            ; Set default value
            $iFixed = $aGUIExt_Section_Data[0][4]
    EndSwitch

    ; Get current GUI size and set function calculation values
    Local $aGUIPos = WinGetPos($aGUIExt_Section_Data[0][3])
    Local $iGUI_Fixed = $aGUIPos[2]
    Local $iGUI_Adjust = $aGUIPos[3]
    If $aGUIExt_Section_Data[0][1] Then ; If Horz orientation
        $iGUI_Fixed = $aGUIPos[3]
        $iGUI_Adjust = $aGUIPos[2]
    EndIf

    ; Determine action required
    If $fExtend Then
        ; Change button text
        GUICtrlSetData($aGUIExt_Section_Data[$iSection][5], $aGUIExt_Section_Data[$iSection][6])
        ; Force action control state if needed
        If $aGUIExt_Section_Data[$iSection][8] = 1 Then GUICtrlSetState($aGUIExt_Section_Data[$iSection][5], 1) ; $GUI_CHECKED
        ; Set section state
        $aGUIExt_Section_Data[$iSection][2] = 1
        ; Add size of section being extended
        $iGUI_Adjust += $aGUIExt_Section_Data[$iSection][1]
    Else
        ; Change button text
        GUICtrlSetData($aGUIExt_Section_Data[$iSection][5], $aGUIExt_Section_Data[$iSection][7])
        ; Force action control state if needed
        If $aGUIExt_Section_Data[$iSection][8] = 1 Then GUICtrlSetState($aGUIExt_Section_Data[$iSection][5], 4) ; $GUI_UNCHECKED
        ; Set section state
        $aGUIExt_Section_Data[$iSection][2] = 0
        ; Subtract size of section being hidden
        $iGUI_Adjust -= $aGUIExt_Section_Data[$iSection][1]
    EndIf

    ; Hide all sections to prevent ghosting when changing GUI size
    For $i = $aGUIExt_Section_Data[1][3] To $aGUIExt_Section_Data[$aGUIExt_Section_Data[0][0]][4]
        GUICtrlSetState($i, 32) ; $GUI_HIDE
    Next

    ; Resize and possibly move GUI
    If $aGUIExt_Section_Data[0][1] Then ; Depending on orientation
        ; Calculate change in GUI size
        $iDelta_GUI = $aGUIPos[2] - $iGUI_Adjust
        ; Check GUI fixed point
        Switch $iFixed
            Case 0
                WinMove($aGUIExt_Section_Data[0][3], "", Default, Default, $iGUI_Adjust, $iGUI_Fixed)
            Case 1
                WinMove($aGUIExt_Section_Data[0][3], "", $aGUIPos[0] + Int($iDelta_GUI / 2), Default, $iGUI_Adjust, $iGUI_Fixed)
            Case 2
                WinMove($aGUIExt_Section_Data[0][3], "", $aGUIPos[0] + $iDelta_GUI, Default, $iGUI_Adjust, $iGUI_Fixed)
        EndSwitch
    Else
        $iDelta_GUI = $aGUIPos[3] - $iGUI_Adjust
        Switch $iFixed
            Case 0
                WinMove($aGUIExt_Section_Data[0][3], "", Default, Default, $iGUI_Fixed, $iGUI_Adjust)
            Case 1
                WinMove($aGUIExt_Section_Data[0][3], "", Default, $aGUIPos[1] + Int($iDelta_GUI / 2), $iGUI_Fixed, $iGUI_Adjust)
            Case 2
                WinMove($aGUIExt_Section_Data[0][3], "", Default, $aGUIPos[1] + $iDelta_GUI, $iGUI_Fixed, $iGUI_Adjust)
        EndSwitch
    EndIf

    ; Initial section position = section 1 start
    Local $iNext_Coord = $aGUIExt_Section_Data[1][0]
    ; Move sections to required position
    Local $iAdjust_X = 0, $iAdjust_Y = 0
    For $i = 1 To $aGUIExt_Section_Data[0][0]
        ; Is this section visible?
        If $aGUIExt_Section_Data[$i][2] > 0 Then
            ; Get current position of section anchor
            $aPos = ControlGetPos($aGUIExt_Section_Data[0][3], "", $aGUIExt_Section_Data[$i][3])
            If $aGUIExt_Section_Data[0][1] Then ; Depending on orientation
                ; Determine required change in X position for section controls
                $iAdjust_X = $aPos[0] - $iNext_Coord
                ; Determine if controls need to be moved back into the GUI
                If $aPos[1] > $iGUI_Fixed Then $iAdjust_Y = $iGUI_Fixed
            Else
                ; Determine required change in Y position for section controls
                $iAdjust_Y = $aPos[1] - $iNext_Coord
                ; Determine if controls need to be moved back into the GUI
                If $aPos[0] > $iGUI_Fixed Then $iAdjust_X = $iGUI_Fixed
            EndIf
            ; For all controls in this section
            For $j = $aGUIExt_Section_Data[$i][3] To $aGUIExt_Section_Data[$i][4]
                $iCID = $j
                ; Adjust the position
                $aPos = ControlGetPos($aGUIExt_Section_Data[0][3], "", $iCID)
                If @error Then
                    For $k = 1 To $aGUIExt_Obj_Data[0][0]
                        If $aGUIExt_Obj_Data[$k][0] = $j Then
                            $aPos = ControlGetPos($aGUIExt_Section_Data[0][3], "", $aGUIExt_Obj_Data[$k][1])
                            $iCID = $aGUIExt_Obj_Data[$k][1]
                            ExitLoop
                        EndIf
                    Next
                    ; If not an object  see if the ControlID returns a handle (an internal tab will not)
                    If $iCID = $j And GUICtrlGetHandle($j) = 0 Then $iCID = "Ignore"
                EndIf
                If $iCID = "Ignore" Then ContinueLoop
                ; Move control
                ControlMove($aGUIExt_Section_Data[0][3], "", $iCID, $aPos[0] - $iAdjust_X, $aPos[1] - $iAdjust_Y)
                ; And show the control
                GUICtrlSetState($j, 16) ; $GUI_SHOW
            Next
            ; Determine start position for next visible section
            $iNext_Coord += $aGUIExt_Section_Data[$i][1]
        Else
            ; Get current position of hidden section anchor
            $aPos = ControlGetPos($aGUIExt_Section_Data[0][3], "", $aGUIExt_Section_Data[$i][3])
            ; Determine if controls in this section need to be moved outside GUI to prevent possible overlap
            If $aGUIExt_Section_Data[0][1] Then ; Depending on orientation
                If $aPos[1] < $iGUI_Fixed Then
                    For $j = $aGUIExt_Section_Data[$i][3] To $aGUIExt_Section_Data[$i][4]
                        $iCID = $j
                        ; Adjust the position
                        $aPos = ControlGetPos($aGUIExt_Section_Data[0][3], "", $j)
                        If @error Then
                            For $k = 1 To $aGUIExt_Obj_Data[0][0]
                                If $aGUIExt_Obj_Data[$k][0] = $j Then
                                    $aPos = ControlGetPos($aGUIExt_Section_Data[0][3], "", $aGUIExt_Obj_Data[$k][1])
                                    $iCID = $aGUIExt_Obj_Data[$k][1]
                                    ExitLoop
                                EndIf
                            Next
                            ; If not an object  see if the ControlID returns a handle (an internal tab will not)
                            If $iCID = $j And GUICtrlGetHandle($j) = 0 Then $iCID = "Ignore"
                        EndIf
                        If $iCID = "Ignore" Then ContinueLoop
                        ; Move control
                        ControlMove($aGUIExt_Section_Data[0][3], "", $iCID, $aPos[0], $aPos[1] + $iGUI_Fixed)
                    Next
                EndIf
            Else
                If $aPos[0] < $iGUI_Fixed Then
                    For $j = $aGUIExt_Section_Data[$i][3] To $aGUIExt_Section_Data[$i][4]
                        $iCID = $j
                        ; Adjust the position
                        $aPos = ControlGetPos($aGUIExt_Section_Data[0][3], "", $j)
                        If @error Then
                            For $k = 1 To $aGUIExt_Obj_Data[0][0]
                                If $aGUIExt_Obj_Data[$k][0] = $j Then
                                    $aPos = ControlGetPos($aGUIExt_Section_Data[0][3], "", $aGUIExt_Obj_Data[$k][1])
                                    $iCID = $aGUIExt_Obj_Data[$k][1]
                                    ExitLoop
                                EndIf
                            Next
                            ; If not an object  see if the ControlID returns a handle (an internal tab will not)
                            If $iCID = $j And GUICtrlGetHandle($j) = 0 Then $iCID = "Ignore"
                        EndIf
                        If $iCID = "Ignore" Then ContinueLoop
                        ; Move control
                        ControlMove($aGUIExt_Section_Data[0][3], "", $iCID, $aPos[0] + $iGUI_Fixed, $aPos[1])
                    Next
                EndIf
            EndIf
        EndIf
    Next

    ; Set correct "all" state if there is a "all" control
    If $aGUIExt_Section_Data[0][5] <> 9999 Then
        Local $iAll_State = 0
        ; Check if any sections extended
        For $i = 1 To $aGUIExt_Section_Data[0][0]
            If $aGUIExt_Section_Data[$i][2] = 1 Then
                $iAll_State = 1
                ExitLoop
            EndIf
        Next
        ; Sync "all" sections control
        Switch $iAll_State
            ; None extended
            Case 0
                ; Clear flag
                $aGUIExt_Section_Data[0][2] = 0
                ; Set text
                GUICtrlSetData($aGUIExt_Section_Data[0][5], $aGUIExt_Section_Data[0][7])
                ; Set state if required
                If $aGUIExt_Section_Data[0][8] = 1 Then GUICtrlSetState($aGUIExt_Section_Data[0][5], 4) ; $GUI_UNCHECKED
            ; Some extended
            Case Else
                ; Set flag
                $aGUIExt_Section_Data[0][2] = 1
                ; Set text
                GUICtrlSetData($aGUIExt_Section_Data[0][5], $aGUIExt_Section_Data[0][6])
                ; Set state if required
                If $aGUIExt_Section_Data[0][8] = 1 Then GUICtrlSetState($aGUIExt_Section_Data[0][5], 1) ; $GUI_CHECKED
        EndSwitch
    EndIf

    Return 1

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Section_State
; Description ...: Returns current state of section
; Syntax.........: _GUIExtender_Section_State($iSection)
; Parameters ....: $iSection - Section to check
; Requirement(s).: v3.3 +
; Return values .: Success: State of section: 0 = Retracted, 1 = Extended, 2 = Static
;                  Failure: Invalid section returns -1 and sets @error to 1
; Author ........: Melba23
; Remarks .......: This allows additional GUI controls to reflect the section state
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Section_State($iSection)

    If $iSection > UBound($aGUIExt_Section_Data) - 1 Then Return SetError(1, 0, -1)
    Return $aGUIExt_Section_Data[$iSection][2]

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_UDFCtrlCheck
; Description ...: Hides/Shows and moves UDF-created controls when sections are extended/retracted
; Syntax.........: _GUIExtender_UDFCtrlCheck($hControl_Handle, $iSection, $iX, $iY)
; Parameters ....: $hControl_Handle - Handle of UDF-created control
;                  $iSection        - Section within which control is situated
;                  $iX, $iY         - Coords of control - relative to section not to GUI
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns 1
;                  Failure:  Returns 0 and sets @error as follows:
;                  1 = Invalid handle
;                  2 = Invalid section
;                  3 = Invalid coordinate value
; Author ........: Melba23
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_UDFCtrlCheck($hCtrl_Handle, $iSection, $iX, $iY)

    Local $iCtrl_Coord

    ; Check parameters
    If Not IsHWnd($hCtrl_Handle) Or Not WinExists($hCtrl_Handle) Then Return SetError(1, 0, 0)
    If $iSection > UBound($aGUIExt_Section_Data) - 1 Then Return SetError(2, 0, 0)
    If Not IsInt($iX) Or Not IsInt($iY) Then Return SetError(3, 0, 0)

    ; Is the section visible
    Switch _GUIExtender_Section_State($iSection)
        Case 1
            ; If section extended then show the control
            ControlShow($aGUIExt_Section_Data[0][3], "", $hCtrl_Handle)
            ; Now check required position within the GUI - set intial value depending on orientation
            If $aGUIExt_Section_Data[0][1] = 0 Then
                $iCtrl_Coord = $iY + $aGUIExt_Section_Data[1][0] ; Set to offset withint section
            Else
                $iCtrl_Coord = $iX + $aGUIExt_Section_Data[1][0]
            EndIf
            ; Check which earlier sections are extended
            For $i = 1 To $iSection - 1
                If _GUIExtender_Section_State($i) Then
                    ; Add add their size if extended
                    $iCtrl_Coord += $aGUIExt_Section_Data[$i][1]
                EndIf
            Next
            ; Now move control depending on orientation
            If $aGUIExt_Section_Data[0][1] = 0 Then
                WinMove($hCtrl_Handle, "", $iX, $iCtrl_Coord)
            Else
                WinMove($hCtrl_Handle, "", $iCtrl_Coord, $iY)
            EndIf
        Case 0
            ; If section retracted hide the control
            ControlHide($aGUIExt_Section_Data[0][3], "", $hCtrl_Handle)
    EndSwitch

    ; Clear flag for section action
    $fGUIExt_SectionAction = False

    Return 1

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_ActionCheck
; Description ...: Indicates when sections are extended/retracted so that _GUIExtender_UDFCtrlCheck can be called
; Syntax.........: _GUIExtender_ActionCheck()
; Parameters ....: None
; Requirement(s).: v3.3 +
; Return values .: Returns True if sections have been actioned
;                  Returns False after _GUIExtender_UDFCtrlCheck has been used to adjust UDF-created controls
; Author ........: Melba23
; Remarks .......:
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_ActionCheck()

    Return $fGUIExt_SectionAction

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Obj_Data
; Description ...: Store additional info on embedded objects
; Syntax.........: _GUIExtender_Obj_Data($iCID, $oObj)
; Parameters ....: $iCID - Returned ControlID from GUICtrlCreateObj
;                  $iObj - Object reference number from initial object creation
; Requirement(s).: v3.3 +
; Return values .: Success:  Returns 1
;                  Failure:  Returns 0 and sets @error to 1
; Author ........: Melba23, DllCall from trancexx
; Remarks .......: This allows embedded objects to be used in the UDF
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Obj_Data($iCID, $iObj)

    ; Increase array size
    $aGUIExt_Obj_Data[0][0] += 1
    ReDim $aGUIExt_Obj_Data[$aGUIExt_Obj_Data[0][0] + 1][2]
    ; Store ControlID
    $aGUIExt_Obj_Data[$aGUIExt_Obj_Data[0][0]][0] = $iCID
    ; Determine and store object handle
    Local $aRet = DllCall("oleacc.dll", "int", "WindowFromAccessibleObject", "idispatch", $iObj, "hwnd*", 0)
    If @error Or $aRet[0] Then Return SetError(1, 0, 0)
    $aGUIExt_Obj_Data[$aGUIExt_Obj_Data[0][0]][1] = $aRet[2]

    Return 1

EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: _GUIExtender_Clear
; Description ...: Called on GUI deletion to clear the data array ready for a new GUI to be initialised
; Syntax.........: _GUIExtender_Clear()
; Requirement(s).: v3.3 +
; Author ........: Melba23
; Remarks .......: If the data array is not cleared the array is corrupted during initialisation and the UDF crashes
; Example........: Yes
;=====================================================================================================================
Func _GUIExtender_Clear()

    ; Reset data array
    Global $aGUIExt_Section_Data[1][9] = [[0, 0, 1, 0, "", 9999]]

EndFunc

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIExtender_Section_All_Extend
; Description ...: Actions all moveable sections
; Author ........: Melba23
; Modified.......:
; Remarks .......: This function is used internally by _GUIExtender_Section_Extend when all sections are to be moved
; ===============================================================================================================================
Func _GUIExtender_Section_All_Extend($fExtend = True)

    ; Set required state for extendable sections
    Local $iState = 0
    If $fExtend Then $iState = 1

    For $i = 1 To $aGUIExt_Section_Data[0][0]
        ; Check if section requires change of state
        If $aGUIExt_Section_Data[$i][2] <> 2 And $aGUIExt_Section_Data[$i][2] = Not($iState) Then
            ; Extend/Shrink as required
            _GUIExtender_Section_Extend($i, $fExtend)
            ; Set section state to match
            $aGUIExt_Section_Data[$i][2] = $iState
            ; Set section action control state
            Switch $fExtend
                Case True
                    GUICtrlSetData($aGUIExt_Section_Data[$i][5], $aGUIExt_Section_Data[$i][6])
                    If $aGUIExt_Section_Data[$i][8] = 1 Then GUICtrlSetState($aGUIExt_Section_Data[$i][5], 1) ; $GUI_CHECKED
                Case False
                    GUICtrlSetData($aGUIExt_Section_Data[$i][5], $aGUIExt_Section_Data[$i][7])
                    If $aGUIExt_Section_Data[$i][8] = 1 Then GUICtrlSetState($aGUIExt_Section_Data[$i][5], 4) ; $GUI_UNCHECKED
            EndSwitch
        EndIf
    Next

EndFunc

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _GUIExtender_Section_Action_Event
; Description ...: Used to detect clicks on section action buttons in OnEvent mode
; Author ........: Melba23
; Modified.......:
; Remarks .......: This function is called when section action button are clicked in OnEvent mode
; ===============================================================================================================================
Func _GUIExtender_Section_Action_Event()

    _GUIExtender_Action(@GUI_CTRLID)

EndFunc

New - For ease of downloading, here are all the above files in zip format:GUIExtender.zip

As always, I welcome constructive comments and effusive compliments! :P

M23

Edited by Melba23
4 people like this

Share this post


Link to post
Share on other sites



Posted

Useful stuff, especially for avoiding multiple GUI's at once (moving them together is a pain in the a.. :blink: )! Thank you for sharing!

M.I.

Share this post


Link to post
Share on other sites

Posted

Awesome Stuff.Thank you very much M23.

Share this post


Link to post
Share on other sites

Posted

Superb M23.

I will definately use this, I have only looked at the examples so far and they are absolutely top of the pops.

Thanks.

Share this post


Link to post
Share on other sites

Posted

Very-very nice.

That's an awesome job done there. Thanks for sharing it :blink:

Share this post


Link to post
Share on other sites

Posted

good! thank you for shared it.

Share this post


Link to post
Share on other sites

Posted

Awesome Melba23, Posted Image

you always amaze me with your UDFs. 5 stars from me

Share this post


Link to post
Share on other sites

Posted

New version - 5/08/10

GUIExtender can now extend and retract sections horizontally or vertically. You set the required orientation when initialising the UDF and all sections in the GUI then use that orientation when extending or retracting.

New UDF and new example in the first post.

Enjoy! :blink:

M23

1 person likes this

Share this post


Link to post
Share on other sites

Posted

Wow, thats really cool. Thanks. :blink:

Share this post


Link to post
Share on other sites

Posted (edited)

Usefull and nice ! Posted Image

It give me some ideas...

Edited by wakillon

Share this post


Link to post
Share on other sites

Posted

Hy Melba23, Hy all,

I like your GUIExtender UDF.

I have an idea for an application.

I trie to adapt your udf to my needs, but now i am in a dead point.

I need a hint how to use "Func _GUIExtender_Section_Action".

I want to activate the hidden section using to radio button, and i dont need the "MORE" button, with the arrow.

My programing skills are not sow good... maybe a hint...

In attachament i put the modification and a screen shoot

THANKS!!!!!

post-58816-12817325159669_thumb.jpg

Copy of GUIExtender_Example_Working.au3

Share this post


Link to post
Share on other sites

Posted

Good work Melba

Share this post


Link to post
Share on other sites

Posted

BlueLord,

Sorry for the delay in replying - I was away for a few weeks. ;)

All you need to do is to use the _GUIExtender_Section_Action function with only the $iSection parameter, as explained in the function header and shown in the final example. This creates an extendable section without a UDF-created button.

In your example script, just change this line:

_GUIExtender_Section_Action($iThis_Section + 1, "", "", 270, 60, 15, 15) ; Note easy way to denote next section

to read:

_GUIExtender_Section_Action($iThis_Section + 1)

You now have no automatically created button and your radio button will still work as you wish.

All clear? :)

M23

Share this post


Link to post
Share on other sites

Posted

OK!

Thanks!

Share this post


Link to post
Share on other sites

Posted

Hy,

Me again...

I have a "minor" bug in my GUI.

When i first start the script the element's from "$iSettingMenu_Section" not appear.

But after i activare a hide section "$iMMenu_Section" elements appear and after hide again the "$iMMenu_Section" are not hidden.

I whant that the elements of "$iSettingMenu_Section" to appear when i first start the script.

I have attachen the script and a picture...

GuiCLG_20100901_forum.au3

post-58816-12833583891237_thumb.png

Share this post


Link to post
Share on other sites

Posted (edited)

BlueLord,

You were seriously overcomplicating the script - if you let the UDF create the Action controls, you do not need to deal with the state of the extendable sections. ;)

You also need to make sure you have the sections following on directly one from the other. That is to say that the start coordinate of a section should equal the sum of the start position and size of the section before it - take a look at the values now. :P

I think this is what you want - I have commented where necessary: ;)

#include <GUIConstantsEx.au3>
#include "GUIExtender.au3"
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <ButtonConstants.au3>
#include <WindowsConstants.au3>

;; Create GUI window
$win_1 = GUICreate("Check List Generator = powered by BlueLord", 365, 440)

; Initialise UDF
_GUIExtender_Init($win_1)

$iQuickMenu_Section = _GUIExtender_Section_Start(0, 100)

$print_selc_group = GUICtrlCreateGroup("Print Mode . . .", 10, 20, 140, 65);*
GUIStartGroup("Print Mode . . .")
$prt_full = GUICtrlCreateRadio("Complete Print", 20, 35, 100, 20)
GUICtrlSetTip(-1, "Print Complet '", "Full Print Mode", 1)
$prt_indv = GUICtrlCreateRadio("Individual Print", 20, 60, 100, 20)
GUICtrlSetTip(-1, "Print Individual", "Individual Print Mode", 1)
GUICtrlSetState($prt_full, $GUI_CHECKED)

$print_selc_group = GUICtrlCreateGroup("Print", 210, 20, 140, 65);*
GUIStartGroup("Print . . .")
$Print_Button = GUICtrlCreateButton("Print", 250, 35, 70, 40, $BS_ICON)
GUICtrlSetImage(-1, "shell32.dll", 252)
GUICtrlSetTip($Print_Button, "Print Your Selection", "Print!", 1)

; This sets an action ControlID but you need to do all the work!
_GUIExtender_Section_Action($iQuickMenu_Section + 1)

_GUIExtender_Section_End()

$iMMenu_Section = _GUIExtender_Section_Start(100, 30)
; These are UDF generated Action controls - you need not worry about them!
$g_section_but = _GUIExtender_Section_Action($iMMenu_Section + 1, "g", "g", 20, 100, 95, 20, 1)
$u_section_but = _GUIExtender_Section_Action($iMMenu_Section + 2, "u", "u", 120, 100, 95, 20, 1)
$a_section_but = _GUIExtender_Section_Action($iMMenu_Section + 3, "a", "a", 220, 100, 95, 20, 1)
_GUIExtender_Section_End()

$iGMenu_Section = _GUIExtender_Section_Start(130, 80)
$m_g_group = GUICtrlCreateGroup("G", 10, 130, 340, 70)
_GUIExtender_Section_End()

$iUMenu_Section = _GUIExtender_Section_Start(210, 80)
$m_u_group = GUICtrlCreateGroup("U", 10, 210, 340, 70)
_GUIExtender_Section_End()

$iAMenu_Section = _GUIExtender_Section_Start(290, 80)
$m_a_group = GUICtrlCreateGroup("A", 10, 290, 340, 70)
_GUIExtender_Section_End()

$iSettingMenu_Section = _GUIExtender_Section_Start(370, 70)

$setting2 = GUICtrlCreateGroup("Settings", 10, 370, 140, 60);*
$helpgroup = GUICtrlCreateGroup("_?_", 210, 370, 140, 60);*

GUIStartGroup("Settings")
$prt_set = GUICtrlCreateButton("", 20, 385, 40, 40, $BS_ICON)
GUICtrlSetImage(-1, "shell32.dll", 1007)
GUICtrlSetTip(-1, "Change Printer Settings", "Printer Settings", 1)
$full_set = GUICtrlCreateButton("", 60, 385, 40, 40, $BS_ICON)
GUICtrlSetImage(-1, "shell32.dll", -145)
GUICtrlSetTip(-1, "Settings", "Settings", 1)
$ini_set = GUICtrlCreateButton("", 100, 385, 40, 40, $BS_ICON)
GUICtrlSetImage(-1, "shell32.dll", -132);-132
GUICtrlSetTip(-1, "Delete", "Delete", 1)

GUIStartGroup("_?_")
$about_prg = GUICtrlCreateButton("", 220, 385, 40, 40, $BS_ICON)
GUICtrlSetImage(-1, "shell32.dll", -278) ;-28
GUICtrlSetTip(-1, "Info", "About", 1)
$help_prg = GUICtrlCreateButton("", 260, 385, 40, 40, $BS_ICON)
GUICtrlSetImage(-1, "shell32.dll", -155) ;-155
GUICtrlSetTip(-1, "Help", "Help", 1)
$exit_prg = GUICtrlCreateButton("", 300, 385, 40, 40, $BS_ICON)
GUICtrlSetImage(-1, "shell32.dll", -28);-278
GUICtrlSetTip(-1, "Close program", "Exit", 1)

_GUIExtender_Section_End()

GUICtrlCreateGroup("", -99, -99, 1, 1)

; Now collapse the section you do not want to show - not all of them as before!
_GUIExtender_Section_Extend($iMMenu_Section, False)
_GUIExtender_Section_Extend($iGMenu_Section, False)
_GUIExtender_Section_Extend($iUMenu_Section, False)
_GUIExtender_Section_Extend($iAMenu_Section, False)

GUISetState()

While 1

    $iMsg = GUIGetMsg()

    ; Check for normal AutoIt controls
    Switch $iMsg
        Case $GUI_EVENT_CLOSE, $exit_prg
            Exit
        Case $Print_Button
            _DublePrintButton_Action($iMsg)
        ; We need to deal with the radio buttons because they control the user created action control
        ; As the 2 radios are in a group, only one of them can be active at a time
        ; so it is really easy to decide what to do!
        Case $prt_full
            _GUIExtender_Section_Extend($iAMenu_Section, False)
            _GUIExtender_Section_Extend($iUMenu_Section, False)
            _GUIExtender_Section_Extend($iGMenu_Section, False)
            _GUIExtender_Section_Extend($iMMenu_Section, False)
        Case $prt_indv
            _GUIExtender_Section_Extend($iMMenu_Section)
    EndSwitch

    ; Check for UDF-generated GUIExtender controls
    ; The UDF will deal with them - we need not wory about them!
    _GUIExtender_Action($iMsg)

WEnd

Func _DublePrintButton_Action($iMsg)

    If GUICtrlRead($prt_indv) = 1 Then
        MsgBox(0, "Individual Print Mode", "OK - Individual Print")
    Else
        MsgBox(0, "Complete Print Mode", "OK - Complete Print")
    EndIf

EndFunc   ;==>_DublePrintButton_Action

All clear? :)

M23

Edit: Typnig!

Edited by Melba23

Share this post


Link to post
Share on other sites

Posted

Thank's

I'm new in autoit and programing. I like autoit and i trie to lern.

I don't have good programming skills and i make slow progress.

Maybe sometimes i complcate the script.

Thanks again

Share this post


Link to post
Share on other sites

Posted

Hello... me again ;)

I test my modificated script from you, it's ok but when i minimize and then maximize back the window the element's of last section are hidden.

Second point:

I'm asking if it's a method to "hide" minimize and "close" button.

In my script i used "-1,-1,$WS_BORDER)" to hide this buttons.

Thanks

post-58816-1283451933528_thumb.jpg

Share this post


Link to post
Share on other sites

Posted (edited)

BlueLord,

Interesting..... ;)

As a workaround, make these changes: :)

$iSettingMenu_Section = _GUIExtender_Section_Start(370, 70)
_GUIExtender_Section_Action($iSettingMenu_Section)



Switch $iMsg
    Case $GUI_EVENT_CLOSE, $exit_prg
        Exit
    Case $GUI_EVENT_RESTORE
        _GUIExtender_Section_Extend($iSettingMenu_Section, False)
        _GUIExtender_Section_Extend($iSettingMenu_Section)

I will investigate further. Thanks for bringing it to my attention. ;)

M23

Edit: New version of the UDF in the first post - just use that and the problem goes away! :P

Thanks for bringing the problem to my attention. o:)

M23

Edited by Melba23

Share this post


Link to post
Share on other sites

Posted (edited)

NEW VERSION

GUIExtender now restores the GUI correctly after a MINIMIZE/RESTORE cycle. Windows replaces GUI sections in their original rather then their current positions which led to some sections not being displayed incorrectly or not at all when earlier sections are retracted. ;)

I have added a function to the UDF to reset the GUI to the desired state, which it does by cycling the highest numbered extendable section and so resetting the positions of all the sections and their controls.

If you are in OnEvent mode or if you already call _GUIExtender_Action then you need to take no action as this function is called automatically. :)

If you are in GetMessage mode and are NOT using any UDF-created action controls, you need to add the following to your GUIGetMsg loop:

Case $GUI_EVENT_RESTORE
    _GUIExtender_Restore()

If only the final section of your GUI is extendable, you can get away with not doing this as the earlier sections will always be in the correct position. However, I would still recommend adding the $GUI_EVENT_RESTORE line so you get into the habit and do not forget in other scripts! :P

New UDF and a modified example to show how to amend the GUIGetMsg loop as described above now in the first post. New Zip file also uploaded.

Thanks to BlueLord for pointing out the problem. ;)

M23

Edit: Clarity (I hope!)

Edited by Melba23

Share this post


Link to post
Share on other sites
This topic is now closed to further replies.
Sign in to follow this  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.