DockIt GUI abdocken

  • Hi,
    ich bin durch ein Zufall auf ein beeindruckendes Script gestoßen.
    Hier mal der Link: https://autoit.de/index.php?page…79275#post79275
    Nun hab ich die Frage, ob man die 2te GUI durch verschieben ab und wieder andocken kann.
    Meine das so:
    Wenn man die erste GUI verschiebt, soll sich die 2te GUI auch verschieben, aber
    wenn man die 2te GUI vercshiebt soll sie sich ab- oder andocken

    • Offizieller Beitrag

    Dazu muß WM_MOVE nur für das erste GUI aktiviert werden. Der Einfachheit halber hab ich in meinem Bsp. die Schleife zum Durchlaufen des Array auskommentiert und fix auf das erste Element (GUI1) verwiesen. Für diesen Fall kann natürlich ein 1D-Array verwendet werden. Kannst du ja dann anpassen.
    Um GUI2 wieder anzudocken mußt du kurz GUI1 bewegen, oder du definierst einen "Fangbereich" um die GUI1 und checkst, ob GUI2 in diesen eintritt. Wie das geht, kannst du dem anderen Bsp. (Andocken am Desktoprand) aus demselben Thread entnehmen.

    Spoiler anzeigen
    [autoit]

    #include <WindowsConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <Winapi.au3>
    $gui1 = GUICreate("Nummer 1", 300, 300)
    GUICtrlCreateGroup('Dockposition', 40, 40, 220, 220)
    $r1 = GUICtrlCreateRadio('1', 240, 140, 15, 17)
    GUICtrlSetState(-1, $GUI_CHECKED)
    $r2 = GUICtrlCreateRadio('2', 140, 240, 15, 17)
    $r3 = GUICtrlCreateRadio('3', 45, 140, 15, 17)
    $r4 = GUICtrlCreateRadio('4', 140, 50, 15, 17)
    GUICtrlCreateGroup('', -99, -99, 1, 1)
    $gui2 = GUICreate("Ich bin gedockt", 200, 200, -1, -1, -1, $WS_EX_TOOLWINDOW)

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

    Global $aDocks[2][4] = [[$gui1,$gui2,1,-1],[$gui2,$gui1,3,-1]]
    ; ['GUI-master','GUI-slave',dockPos,Abstand]
    ; dockPos: 1=rechts, 2=unten, 3=links, 4=oben
    ; Abstand: -1=SysMetrics Fensterrand, alle anderen Werte Pixelabstand zw. Fenstern
    ;=======================================================================================================
    ; Damit zwei Fenster wechselseitig reagieren, müssen beide im Array aufgeführt werden, einmal als Master
    ; und einmal als Slave.
    ; Dabei müssen die entgegengesetzten Flags für die Dockposition vergeben werden (1 u. 3 bzw. 2 u. 4)
    ;=======================================================================================================

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

    GUISetState(@SW_SHOW, $gui2)
    GUISetState(@SW_SHOW, $gui1)

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

    ; WM_MOVE registrieren:
    GUIRegisterMsg($WM_MOVE, "WM_MOVE")
    GUIRegisterMsg($WM_ACTIVATE, "WM_ACTIVATE")

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

    ; Ereignis WM_MOVE auslösen zum erstmaligen Positionieren der Fenster
    _moved()

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

    While True
    $msg = GUIGetMsg()
    Switch $msg
    Case -3
    Exit
    Case $r1
    $aDocks[0][2] = 1
    $aDocks[1][2] = 3
    _moved()
    Case $r2
    $aDocks[0][2] = 2
    $aDocks[1][2] = 4
    _moved()
    Case $r3
    $aDocks[0][2] = 3
    $aDocks[1][2] = 1
    _moved()
    Case $r4
    $aDocks[0][2] = 4
    $aDocks[1][2] = 2
    _moved()
    EndSwitch
    WEnd

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

    Func _moved()
    DllCall("User32.dll", "int", "PostMessageA", "hwnd", WinGetHandle($aDocks[0][0]), "int", $WM_MOVE, "int", 0, "int", 0)
    EndFunc

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

    Func WM_MOVE($hWndGUI)
    ;~ For $i = 0 To UBound($aDocks) -1
    Local $i = 0
    If WinGetHandle($aDocks[$i][0]) = $hWndGUI Then
    Local $aPos1 = WinGetPos($aDocks[$i][0])
    Local $aPos2 = WinGetPos($aDocks[$i][1]), $iDiff = 0
    If $aDocks[$i][3] = -1 Then
    Local $ret = DllCall("user32.dll", "int", "GetSystemMetrics", "int", 32)
    If IsArray($ret) Then $iDiff = $ret[0]
    Else
    $iDiff = $aDocks[$i][3]
    EndIf
    Switch $aDocks[$i][2]
    Case 1
    WinMove($aDocks[$i][1], '', $aPos1[0]+$aPos1[2]+$iDiff, $aPos1[1])
    Case 2
    WinMove($aDocks[$i][1], '', $aPos1[0], $aPos1[1]+$aPos1[3]+$iDiff)
    Case 3
    WinMove($aDocks[$i][1], '', $aPos1[0]-$iDiff-$aPos2[2], $aPos1[1])
    Case 4
    WinMove($aDocks[$i][1], '', $aPos1[0], $aPos1[1]-$iDiff-$aPos2[3])
    EndSwitch
    EndIf
    ;~ Next
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func WM_ACTIVATE($hWndGUI)
    If WinGetHandle($aDocks[0][0]) = $hWndGUI Then _
    DllCall("User32.dll", "hwnd", "SetFocus", "hwnd", WinGetHandle($aDocks[0][1]))
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit]
  • Danke für deine Hilfe
    Ich hab auch schon probiert den Fangbereich zu bestimmen (aus deinem anderen Script), kriege es aber nicht hin ?(
    Könntest du mir bitte helfen?
    Schon mal danke

  • Ich hab das Script mit dem Fangbereich mal ein bisschen umgeschrieben

    Spoiler anzeigen
    [autoit]

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

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

    Global $CatchWidth = 10 ; Pixelbereich indem das Fenster gefangen wird
    Global $BorderDiff = 2 ; Pixelabstand zum Rand

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

    Global $gui = GUICreate("Dock on Border", 150, 150)
    GUISetBkColor(0x000000)
    WinSetOnTop($gui, "", 1)
    GUISetState(@SW_SHOW)

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

    Global $gui2 = GUICreate("Border", 800, 600, 0, 0)
    GUISetBkColor(0xFFFFFF)
    GUISetState(@SW_SHOW)

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

    ; WM_MOVE registrieren:
    GUIRegisterMsg($WM_MOVE, "WM_MOVE")

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

    $W = WinGetClientSize("Hauptfenster")

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

    While True
    $msg = GUIGetMsg()
    Switch $msg
    Case -3
    Exit
    EndSwitch
    WEnd

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

    Func WM_MOVE($hWndGUI)
    If Not(WinGetHandle($gui) = $hWndGUI) Then Return $GUI_RUNDEFMSG
    Local $aPos = WinGetPos($gui)
    Local $Catch_Left = $CatchWidth, $Catch_Right = $W[0] - $CatchWidth
    Local $Catch_Top = $CatchWidth, $Catch_Bottom = $W[1] - $CatchWidth
    Select
    Case $aPos[0] <= $Catch_Left
    If $aPos[1] <= $Catch_Top Then
    WinMove($gui, '', $BorderDiff, $BorderDiff)
    ElseIf $aPos[1] + $aPos[3] >= $Catch_Bottom Then
    WinMove($gui, '', $BorderDiff, $W[1] - $BorderDiff - $aPos[3])
    Else
    WinMove($gui, '', $BorderDiff, $aPos[1])
    EndIf
    Case $aPos[0] + $aPos[2] >= $Catch_Right
    If $aPos[1] <= $Catch_Top Then
    WinMove($gui, '', $W[0] - $BorderDiff - $aPos[2], $BorderDiff)
    ElseIf $aPos[1] + $aPos[3] >= $Catch_Bottom Then
    WinMove($gui, '', $W[0] - $BorderDiff - $aPos[2], $W[1] - $BorderDiff - $aPos[3])
    Else
    WinMove($gui, '', $W[0] - $BorderDiff - $aPos[2], $aPos[1])
    EndIf
    Case $aPos[1] <= $Catch_Top
    If $aPos[0] <= $Catch_Left Then
    WinMove($gui, '', $BorderDiff, $BorderDiff)
    ElseIf $aPos[0] + $aPos[2] >= $Catch_Right Then
    WinMove($gui, '', $W[0] - $BorderDiff - $aPos[2], $BorderDiff)
    Else
    WinMove($gui, '', $aPos[0], $BorderDiff)
    EndIf
    Case $aPos[1] + $aPos[3] >= $Catch_Bottom
    If $aPos[0] <= $Catch_Left Then
    WinMove($gui, '', $BorderDiff, $W[1] - $BorderDiff - $aPos[3])
    ElseIf $aPos[0] + $aPos[2] >= $Catch_Right Then
    WinMove($gui, '', $W[0] - $BorderDiff - $aPos[2], $W[1] - $BorderDiff - $aPos[3])
    Else
    WinMove($gui, '', $aPos[0], $W[1] - $BorderDiff - $aPos[3])
    EndIf
    EndSelect
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_MOVE

    [/autoit]


    Das funktioniert leider nicht so, wie es soll
    Ich bin für jede Hilfe dankbar