GUI Control Splitter

  • Hi!

    Da ich gerade etwas am Neuentwerfen einiger Funktionen meines ISN AutoIt Studios bin hab ich mir gedacht die neue Splitterfunktion ist auch für einige von euch sicherlich brauchbar:

    Was macht diese UDF?
    -> Sie lässt euch leicht beliebig viele Controls in eine GUI packen die ihr dann mittels Splitter in der Größe verschieben könnt! So könnt ihr euer Fenster zb. in mehrere Teile unterteilen...so wie es auch im ISN AutoIt Studio gemacht wurde (nur da hab ichs noch viel komplizierter gemacht...)

    Vielleicht kann´s ja mal wer brauchen...


    [autoit]


    #cs ----------------------------------------------------------------------------
    Splitting Techdemo for ISN AutoIt Studio 1.0
    Zeigt wie diverse Controls in eine GUI eingefügt werden können und mittels Splitter in der Größe verändert werden können (horizontal & Vertikale Splitter sind möglich)
    #ce ----------------------------------------------------------------------------

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

    Opt("GUIOnEventMode", 1) ;0=disabled, 1=OnEvent mode enabled
    Opt("GUICloseOnESC", 1) ;1=ESC closes, 0=ESC won't close
    Opt("GUIResizeMode", 802) ;0=no resizing, <1024 special resizing

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

    Global $Splitter_Rand = 3 ;Rand zwischen einem Control und dem Controlsplitter
    Global $Splitter_Minimale_Groesse = 100 ;Minimale Groesse die ein Control im Splittersystem haben kann
    Global $User32_dll_handle = DllOpen("user32.dll") ;Handle der user32.dll für zb. _IsPressed

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

    ;Kleine TestGUI
    #include <GuiComboBox.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <Constants.au3>
    #include <Misc.au3>

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

    $Form1 = GUICreate("Form1", 683, 614, -1, -1, bitor($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_SIZEBOX, $WS_MAXIMIZEBOX))
    GUISetOnEvent($GUI_EVENT_CLOSE, "_exit", $Form1)
    GUISetOnEvent($GUI_EVENT_RESIZED, "_Aktualisiere_Splittercontrols", $Form1)
    GUISetOnEvent($GUI_EVENT_RESTORE, "_Aktualisiere_Splittercontrols", $Form1)
    GUISetOnEvent($GUI_EVENT_MAXIMIZE, "_Aktualisiere_Splittercontrols", $Form1)
    $Links = GUICtrlCreateEdit("", 24, 56, 153, 273)
    GUICtrlSetData(-1, "Links")
    $Label1 = GUICtrlCreateLabel("", 200, 48, 5, 308, -1, $SS_BLACKFRAME)
    GUICtrlSetState(-1, $GUI_ONTOP)
    GUICtrlSetCursor(-1, 13)
    GUICtrlSetOnEvent(-1, "_move_Splitter")
    $Mitte = GUICtrlCreateEdit("", 249, 58, 153, 273)
    GUICtrlSetData(-1, "Edit1")
    $Rechts = GUICtrlCreateEdit("", 438, 25, 153, 273)
    GUICtrlSetData(-1, "Edit1")
    $Label2 = GUICtrlCreateLabel("", 406, 34, 5, 308, -1, $SS_BLACKFRAME)
    GUICtrlSetState(-1, $GUI_ONTOP)
    GUICtrlSetCursor(-1, 13)
    GUICtrlSetOnEvent(-1, "_move_Splitter")
    $Unten = GUICtrlCreateEdit("", 71, 419, 497, 113)
    GUICtrlSetData(-1, "Edit1")
    $Label3 = GUICtrlCreateLabel("", 17, 366, 652, 5, -1, $SS_BLACKFRAME)
    GUICtrlSetState(-1, $GUI_ONTOP)
    GUICtrlSetCursor(-1, 11)
    GUICtrlSetOnEvent(-1, "_move_Splitter")
    $testinput = guictrlcreateinput("lalal", 10, 10, 200, 20)
    GUISetState(@SW_SHOW)

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

    _Aktualisiere_Splittercontrols()

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

    While 1
    sleep(100)
    WEnd

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

    ; #FUNCTION# ;===============================================================================
    ;
    ; Name...........: _Aktualisiere_Splittercontrols
    ; Description ...: Wird verwendet um die Position der Controls und die Splitter zu aktualisieren
    ; Syntax.........: _Aktualisiere_Splittercontrols()
    ; Parameters ....: Keine
    ; Return values .: Keine
    ; Author ........: ISI360
    ; Modified.......:
    ; Remarks .......: Wird zb. auch in der Funktion _move_Splitter() aufgerufen
    ; Alle Controls die im Splittersystem verwendet werden sollen MÜSSEN hier aufgeführt sein!
    ; Related .......:
    ; Link ..........; http://www.isnetwork.at.pn
    ; Example .......;
    ;
    ; ;==========================================================================================
    func _Aktualisiere_Splittercontrols()
    ;Weise zuerst (!!) die Controls den Splittern zu...
    _Add_control_to_Splitter($Form1, $Links, -1, $Label1, -1, $Label3)
    _Add_control_to_Splitter($Form1, $Mitte, $Label1, $Label2, -1, $Label3)
    _Add_control_to_Splitter($Form1, $testinput, $Label2, -1, -1, $Rechts)
    _Add_control_to_Splitter($Form1, $Rechts, $Label2, -1, $testinput, $Label3)
    _Add_control_to_Splitter($Form1, $Unten, -1, -1, $Label3, -1)
    ;...und lasse danach die Splitter selbst Teil des Systems sein (Wichtig!)
    _Add_control_to_Splitter($Form1, $Label1, $Links, $Mitte, -1, $Label3)
    _Add_control_to_Splitter($Form1, $Label2, $Mitte, $rechts, -1, $Label3)
    _Add_control_to_Splitter($Form1, $Label3, -1, -1, $Mitte, $unten)
    endfunc

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

    ; #FUNCTION# ;===============================================================================
    ;
    ; Name...........: _Add_control_to_Splitter
    ; Description ...: Fügt ein beliebiges Control in ein Splittersystem ein. Dabei müssen jeweils die Handles der Splitter angegeben werden
    ; Syntax.........: _Add_control_to_Splitter($control, $splitter_left, $splitter_right, $splitter_top, $splitter_down)
    ; Parameters ....: $hgui - Handle zum GUI Fenster in dem sich die Controls und Splitter befinden
    ; $control - Handle zum Control welches in das Splittersystem eingefügt werden soll
    ; $splitter_left - Handle zum nächstgelegenen linken Splitter (Bei -1 wird der linke GUI-Rand verwendet)
    ; $splitter_right - Handle zum nächstgelegenen rechten Splitter (Bei -1 wird der rechte GUI-Rand verwendet)
    ; $splitter_top - Handle zum nächstgelegenen Splitter über dem Control (Bei -1 wird der obere GUI-Rand verwendet)
    ; $splitter_down - Handle zum nächstgelegenen Splitter unter dem Control (Bei -1 wird der untere GUI-Rand verwendet)
    ; Return values .: 1 - Erfolg
    ; 0 - Control konnte nicht in das Splittersystem integriert werden
    ; Author ........: ISI360
    ; Modified.......:
    ; Remarks .......: Kann auch zum Aktualisieren der Positionen eines Controls genutzt werden (zb. durch _move_Splitter())
    ; Related .......:
    ; Link ..........: http://www.isnetwork.at.pn
    ; Example .......:
    ;
    ; ;==========================================================================================
    func _Add_control_to_Splitter($hgui = "", $control = "", $splitter_left = -1, $splitter_right = -1, $splitter_top = -1, $splitter_down = -1)
    if $hgui = "" then return 0 ;error
    if $control = "" then return 0 ;error

    ;Definiere verwendete Variablen
    Local $position_splitter_links
    Local $position_splitter_rechts
    Local $position_splitter_unten
    Local $position_splitter_oben
    Local $x
    Local $y
    Local $breite
    Local $hoehe

    ;Hole Positionen von den angegebenen Splittern und der GUI
    ;splitter/guirand links
    if $splitter_left <> -1 Then
    $position_splitter_links = ControlGetPos($hgui, "", $splitter_left)
    Else
    $position_splitter_links = WinGetClientSize($hgui, "")
    endif

    ;splitter/guirand rechts
    if $splitter_right <> -1 Then
    $position_splitter_rechts = ControlGetPos($hgui, "", $splitter_right)
    Else
    $position_splitter_rechts = WinGetClientSize($hgui, "")
    endif

    ;splitter/guirand oben
    if $splitter_top <> -1 Then
    $position_splitter_oben = ControlGetPos($hgui, "", $splitter_top)
    Else
    $position_splitter_oben = WinGetClientSize($hgui, "")
    endif

    ;splitter/guirand unten
    if $splitter_down <> -1 Then
    $position_splitter_unten = ControlGetPos($hgui, "", $splitter_down)
    Else
    $position_splitter_unten = WinGetClientSize($hgui, "")
    endif

    ;Berechene Positionen
    ;x
    if $splitter_left <> -1 Then
    $x = $position_splitter_links[0] + $position_splitter_links[2] + $Splitter_Rand
    Else
    $x = $Splitter_Rand
    endif

    ;y
    if $splitter_top <> -1 Then
    $y = $position_splitter_oben[1] + $position_splitter_oben[3] + $Splitter_Rand
    Else
    $y = $Splitter_Rand
    endif

    ;breite
    $breite = ($position_splitter_rechts[0] - $x) - $Splitter_Rand

    ;höhe
    $hoehe = ($position_splitter_unten[1] - $y) - $Splitter_Rand

    ;Setze neue Positionen für das Control
    guictrlsetpos($control, $x, $y, $breite, $hoehe)

    ;Fertig ;)
    return 1
    EndFunc

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

    ; #FUNCTION# ;===============================================================================
    ;
    ; Name...........: _move_Splitter
    ; Description ...: Verschiebt durch gedrückthalten der linken Maustaste einen Splitter
    ; Syntax.........: _move_Splitter()
    ; Parameters ....: Keine
    ; Return values .: 1 - Erfolg
    ; 0 - Fehler
    ; Author ........: ISI360
    ; Modified.......:
    ; Remarks .......: Muss durch eine GUICtrlSetOnEvent funktion aufgerufen werden
    ; Erkennt automatisch ob es sich bei dem Splitter um einen Horizontalen oder Vertikalen Splitter handelt
    ; Erkennt automatisch die Controls (dank dllcall) die den Splitter betreffen und achtet auf die Minimalgröße ($Splitter_Minimale_Groesse)
    ; Related .......:
    ; Link ..........: http://www.isnetwork.at.pn
    ; Example .......:
    ;
    ; ;==========================================================================================
    func _move_Splitter()
    if @GUI_CtrlId = "" then Return 0
    if @GUI_WinHandle = "" then Return 0

    ;Definiere verwendete Variablen
    Local $position_splitter
    Local $Position_Maus1
    Local $Position_Maus2
    Local $x_Differenz
    Local $y_Differenz
    Local $x
    Local $y
    Local $breite
    Local $hoehe
    Local $handle_element_oben
    Local $position_element_oben
    Local $handle_element_unten
    Local $position_element_unten
    Local $handle_element_rechts
    Local $position_element_rechts
    Local $handle_element_links
    Local $position_element_links

    $position_fenster = WinGetPos(@GUI_WinHandle) ;aktuelle Position des Fensters
    $position_fenster_clientsize = WinGetClientSize(@GUI_WinHandle) ;Clientsize des aktuellen fensters
    $position_splitter = ControlGetPos(@GUI_WinHandle, "", @GUI_CtrlId) ;aktuelle Position des Splitters
    $Position_Maus1 = MouseGetPos() ;hole mausposition
    $x_Differenz = $Position_Maus1[0] - $position_splitter[0] ;x differenz vom control zur mausposition
    $y_Differenz = $Position_Maus1[1] - $position_splitter[1] ;y differenz vom control zur mausposition

    While _IsPressed('01', $User32_dll_handle)
    $Position_Maus1 = MouseGetPos() ;hole mausposition
    sleep(10) ;warte ganz kurz...
    $Position_Maus2 = MouseGetPos() ;hole 2. mausposition
    if $Position_Maus1 <> $Position_Maus2 Then ;falls sich mauszeiger bewegt hat...

    if $position_splitter[3] > $position_splitter[2] then ;prüfe ob es sich um einen horizontalen oder vertikalen splitter handelt
    $x = $Position_Maus1[0] - $x_Differenz
    $y = $position_splitter[1]
    if $x < $Splitter_Rand then $x = $Splitter_Rand ;falls splitter aus der GUI wandert
    if $x > $position_fenster_clientsize[0] then $x = $position_fenster_clientsize[0] - $Splitter_Rand ;falls splitter aus der GUI wandert

    ;Prüfe welches Control sich links und rechts neben dem Splitter befindet und prüfe desen größe...
    $position_splitter = ControlGetPos(@GUI_WinHandle, "", @GUI_CtrlId) ;aktuelle Position des Splitters
    $handle_element_links = DllCall("user32.dll", "hwnd", "WindowFromPoint", "int", ($position_fenster[0] + $position_splitter[0]) - ($Splitter_Rand + 50), "int", $position_fenster[1] + $position_splitter[1] + $Splitter_Rand + 50) ;suche control nach x und y koordinaten
    $position_element_links = ControlGetPos(@GUI_WinHandle, "", $handle_element_links[0]) ;aktuelle Position des linken Elements des Splitters
    $handle_element_rechts = DllCall("user32.dll", "hwnd", "WindowFromPoint", "int", ($position_fenster[0] + $position_splitter[0]) - ($Splitter_Rand - 50), "int", $position_fenster[1] + $position_splitter[1] + $Splitter_Rand + 50) ;suche control nach x und y koordinaten
    $position_element_rechts = ControlGetPos(@GUI_WinHandle, "", $handle_element_rechts[0]) ;aktuelle Position des rechteb Elements des Splitters
    if IsArray($position_element_links) Then
    if $x - ($position_element_links[0]) < $Splitter_Minimale_Groesse then $x = $position_splitter[0]
    endif
    if IsArray($position_element_rechts) Then
    if ($position_element_rechts[0] + $position_element_rechts[2]) - $x < $Splitter_Minimale_Groesse then $x = $position_splitter[0]
    endif

    GUICtrlSetPos(@GUI_CtrlId, $x, $y) ;setze Splitterposition für vertikalen Splitter
    Else
    $x = $position_splitter[0]
    $y = $Position_Maus1[1] - $y_Differenz
    if $y < $Splitter_Rand then $y = $Splitter_Rand ;falls splitter aus der GUI wandert
    if $y > $position_fenster_clientsize[1] then $y = $position_fenster_clientsize[1] - $Splitter_Rand ;falls splitter aus der GUI wandert

    ;Prüfe welches Control sich ober und unterhalb dem Splitter befindet und prüfe desen größe...
    $position_splitter = ControlGetPos(@GUI_WinHandle, "", @GUI_CtrlId) ;aktuelle Position des Splitters
    $handle_element_oben = DllCall("user32.dll", "hwnd", "WindowFromPoint", "int", $position_fenster[0] + $position_splitter[0] + 50, "int", ($position_fenster[1] + $position_splitter[1]) - 50) ;suche control nach x und y koordinaten
    $position_element_oben = ControlGetPos(@GUI_WinHandle, "", $handle_element_oben[0]) ;aktuelle Position des oberen Elements des Splitters
    $handle_element_unten = DllCall("user32.dll", "hwnd", "WindowFromPoint", "int", $position_fenster[0] + $position_splitter[0] + 50, "int", ($position_fenster[1] + $position_splitter[1]) + 50) ;suche control nach x und y koordinaten
    $position_element_unten = ControlGetPos(@GUI_WinHandle, "", $handle_element_unten[0]) ;aktuelle Position des unteren Elements des Splitters
    if IsArray($position_element_oben) Then
    if $y - $position_element_oben[1] < $Splitter_Minimale_Groesse then $y = $position_splitter[1]
    endif
    if IsArray($position_element_unten) Then
    if ($position_element_unten[1] + $position_element_unten[3]) - $y < $Splitter_Minimale_Groesse then $y = $position_splitter[1]
    endif

    GUICtrlSetPos(@GUI_CtrlId, $x, $y) ;setze Splitterposition für horizontalen Splitter
    endif
    _Aktualisiere_Splittercontrols() ;aktualisiere die Controls und andere Splitter beim bewegen des Splitters
    EndIf
    WEnd
    _Aktualisiere_Splittercontrols() ;Finale aktualisierung
    Return 1 ;Fertig
    EndFunc

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

    func _exit()
    Exit
    endfunc

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