GUI am Bildschirmrand + Taskleiste "andocken"

  • Hallo,

    ich habe mal ein Programm hochgeladen, dass dies verdeutlichen soll. Ich habe vor, ein Programm zu erstellen, dessen GUI man ganz leicht am Bildschirmrand bzw Taskleiste andocken lässt. Ich habe das zwar schonmal versucht doch ich habs nicht hinbekommen, wie dieses Programm es macht. Zieht man es am Bildschirmrand, wird es sozusagen "magnetisch" angezogen.

    • Offizieller Beitrag

    Hatte da mal was archiviert:

    Spoiler anzeigen
    [autoit]


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

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

    Global Const $WM_EXITSIZEMOVE = 0x0232
    Global $nRange = 20
    Global $IsSideWinStick = False

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

    $hGUI = GUICreate("GUI Stickable!", 280, 150)
    GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")
    GUIRegisterMsg($WM_EXITSIZEMOVE, "WM_EXITSIZEMOVE")
    GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")

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

    $Stickable_CB = GUICtrlCreateCheckbox("Stickable", 20, 20)
    GUICtrlSetState(-1, $GUI_CHECKED)

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

    $StickableToAll_CB = GUICtrlCreateCheckbox("Stickable to all windows (High CPU usage)", 20, 40)

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

    $Range_Input = GUICtrlCreateInput($nRange, 20, 70, 40, 20, $ES_READONLY)
    $UpDown = GUICtrlCreateUpdown(-1)
    GUICtrlSetLimit(-1, 80, 5)

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

    GUISetState()

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

    GUICreate("Some extra window", 320, 180, 0, 0)
    GUISetState()

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

    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    ExitLoop
    Case $Stickable_CB
    If GUICtrlRead($Stickable_CB) = $GUI_CHECKED Then
    GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")
    GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")
    GUIRegisterMsg($WM_EXITSIZEMOVE, "WM_EXITSIZEMOVE")
    Else
    GUIRegisterMsg($WM_WINDOWPOSCHANGING, "")
    GUIRegisterMsg($WM_SYSCOMMAND, "")
    GUIRegisterMsg($WM_EXITSIZEMOVE, "")
    EndIf
    Case $StickableToAll_CB
    If GUICtrlRead($StickableToAll_CB) = $GUI_CHECKED Then
    $IsSideWinStick = True
    Else
    $IsSideWinStick = False
    EndIf
    Case $UpDown
    $nRange = GUICtrlRead($Range_Input)
    EndSwitch
    WEnd

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

    Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)
    Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam)
    Local $nLeft = DllStructGetData($stWinPos, 3)
    Local $nTop = DllStructGetData($stWinPos, 4)

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

    Local $aCurWinPos = WinGetPos($hWnd)
    Local $aWorkArea = _GetWorkingArea()

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

    ;Left
    If Abs($aWorkArea[0] - $nLeft) <= $nRange Then DllStructSetData($stWinPos, 3, $aWorkArea[0])
    ;Right
    If Abs($nLeft + $aCurWinPos[2] - $aWorkArea[2]) <= $nRange Then DllStructSetData($stWinPos, 3, $aWorkArea[2] - $aCurWinPos[2])
    ;Top
    If Abs($aWorkArea[1] - $nTop) <= $nRange Then DllStructSetData($stWinPos, 4, $aWorkArea[1])
    ;Bottom
    If Abs($nTop + $aCurWinPos[3] - $aWorkArea[3]) <= $nRange Then DllStructSetData($stWinPos, 4, $aWorkArea[3] - $aCurWinPos[3])

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

    If Not $IsSideWinStick Then Return 0

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

    Local $ahWnd = WinList()

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

    For $i = 1 To UBound($ahWnd) - 1
    If $ahWnd[$i][1] = $hWnd Or Not BitAND(WinGetState($ahWnd[$i][1]), 2) Then ContinueLoop

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

    $aSideWinPos = WinGetPos($ahWnd[$i][1])
    If UBound($aSideWinPos) < 3 Then ContinueLoop

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

    Local $XPoint = $aSideWinPos[0] + 15
    Local $YPoint = $aSideWinPos[1] + 15

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

    If $XPoint < 0 Then $XPoint = 5
    If $YPoint < 0 Then $YPoint = 5

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

    If $aCurWinPos[1] + $aCurWinPos[3] >= $aSideWinPos[1] And $aCurWinPos[1] <= $aSideWinPos[1] + $aSideWinPos[3] Then
    ;Left
    If Abs(($aSideWinPos[0] + $aSideWinPos[2]) - $nLeft) <= $nRange And _
    WindowFromPoint($XPoint, $YPoint) = $ahWnd[$i][1] Then _
    DllStructSetData($stWinPos, 3, $aSideWinPos[0] + $aSideWinPos[2])

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

    ;Right
    If Abs($nLeft + $aCurWinPos[2] - $aSideWinPos[0]) <= $nRange And _
    WindowFromPoint($XPoint, $YPoint) = $ahWnd[$i][1] Then _
    DllStructSetData($stWinPos, 3, $aSideWinPos[0] - $aCurWinPos[2])
    EndIf

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

    If $aCurWinPos[0] + $aCurWinPos[2] >= $aSideWinPos[0] And $aCurWinPos[0] <= $aSideWinPos[0] + $aSideWinPos[2] Then
    ;Top
    If Abs(($aSideWinPos[1] + $aSideWinPos[3]) - $nTop) <= $nRange And _
    WindowFromPoint($XPoint, $YPoint) = $ahWnd[$i][1] Then _
    DllStructSetData($stWinPos, 4, $aSideWinPos[1] + $aSideWinPos[3])

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

    ;Bottom
    If Abs($nTop + $aCurWinPos[3] - $aSideWinPos[1]) <= $nRange And _
    WindowFromPoint($XPoint, $YPoint) = $ahWnd[$i][1] Then _
    DllStructSetData($stWinPos, 4, $aSideWinPos[1] - $aCurWinPos[3])
    EndIf
    Next

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

    Return 0
    EndFunc ;==>WM_WINDOWPOSCHANGING

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

    Func WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)
    Switch BitAND($wParam, 0xFFF0)
    Case $SC_SIZE, $SC_MOVE
    DllCall("user32.dll", "int", "SystemParametersInfo", "int", 37, "int", 1, "ptr", 0, "int", 2)
    EndSwitch
    EndFunc ;==>WM_SYSCOMMAND

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

    Func WM_EXITSIZEMOVE($hWnd, $Msg, $wParam, $lParam)
    Local $Old_Show_Content_Param = RegRead("HKEY_CURRENT_USER\Control Panel\Desktop", "DragFullWindows")
    DllCall("user32.dll", "int", "SystemParametersInfo", "int", 37, "int", $Old_Show_Content_Param, "ptr", 0, "int", 2)
    EndFunc ;==>WM_EXITSIZEMOVE

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

    Func WindowFromPoint($XPoint, $YPoint)
    Local $aResult = DllCall("User32.dll", "hwnd", "WindowFromPoint", "int", $XPoint, "int", $YPoint)
    Return $aResult[0]
    EndFunc ;==>WindowFromPoint

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

    ;===============================================================================
    ;
    ; Function Name: _GetWorkingArea()
    ; Description: Returns the coordinates of desktop working area rectangle
    ; Parameter(s): None
    ; Return Value(s): On Success - Array containing coordinates:
    ; $a[0] = left
    ; $a[1] = top
    ; $a[2] = right
    ; $a[3] = bottom
    ; On Failure - 0
    ;
    ;BOOL WINAPI SystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);
    ;uiAction SPI_GETWORKAREA = 48
    ;===============================================================================
    Func _GetWorkingArea()
    Local Const $SPI_GETWORKAREA = 48
    Local $stRECT = DllStructCreate("long; long; long; long")
    Local $SPIRet = DllCall("User32.dll", "int", "SystemParametersInfo", _
    "uint", $SPI_GETWORKAREA, "uint", 0, "ptr", DllStructGetPtr($stRECT), "uint", 0)
    If @error Then Return 0
    If $SPIRet[0] = 0 Then Return 0

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

    Local $sLeftArea = DllStructGetData($stRECT, 1)
    Local $sTopArea = DllStructGetData($stRECT, 2)
    Local $sRightArea = DllStructGetData($stRECT, 3)
    Local $sBottomArea = DllStructGetData($stRECT, 4)

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

    Local $aRet[4] = [$sLeftArea, $sTopArea, $sRightArea, $sBottomArea]
    Return $aRet
    EndFunc ;==>_GetWorkingArea

    [/autoit]


    Angepasst an die neue AutoIt-Version.

  • Ich hab ein kleines Problem dabei. Wenn die GUI unten rechts angedockt wird, sieht man einen Abstand von einem Pixel. Wie kann man das denn so machen, dass die GUI 1 Pixel mehr nach rechts und nach oben angedockt werden kann?

    Spoiler anzeigen
    [autoit]

    Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)
    Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam)
    Local $nLeft = DllStructGetData($stWinPos, 3)
    Local $nTop = DllStructGetData($stWinPos, 4)
    Global $PlayerGUI_Handle

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

    If $hWnd = $PlayerGUI_Handle Then

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

    Local $aCurWinPos = WinGetPos($hWnd)
    Local $aWorkArea = _GetWorkingArea()

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

    ;Left
    If Abs($aWorkArea[0] - $nLeft) <= $nRange Then DllStructSetData($stWinPos, 3, $aWorkArea[0])
    ;Right
    If Abs($nLeft + $aCurWinPos[2] - $aWorkArea[2]) <= $nRange Then DllStructSetData($stWinPos, 3, $aWorkArea[2] - $aCurWinPos[2])
    ;Top
    If Abs($aWorkArea[1] - $nTop) <= $nRange Then DllStructSetData($stWinPos, 4, $aWorkArea[1])
    ;Bottom
    If Abs($nTop + $aCurWinPos[3] - $aWorkArea[3]) <= $nRange Then DllStructSetData($stWinPos, 4, $aWorkArea[3] - $aCurWinPos[3])

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

    If Not $IsSideWinStick Then Return 0

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

    Local $ahWnd = WinList()

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

    For $i = 1 To UBound($ahWnd) - 1
    If $ahWnd[$i][1] = $hWnd Or Not BitAND(WinGetState($ahWnd[$i][1]), 2) Then ContinueLoop

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

    $aSideWinPos = WinGetPos($ahWnd[$i][1])
    If UBound($aSideWinPos) < 3 Then ContinueLoop

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

    Local $XPoint = $aSideWinPos[0] + 15
    Local $YPoint = $aSideWinPos[1] + 15

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

    If $XPoint < 0 Then $XPoint = 5
    If $YPoint < 0 Then $YPoint = 5

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

    If $aCurWinPos[1] + $aCurWinPos[3] >= $aSideWinPos[1] And $aCurWinPos[1] <= $aSideWinPos[1] + $aSideWinPos[3] Then
    ;Left
    If Abs(($aSideWinPos[0] + $aSideWinPos[2]) - $nLeft) <= $nRange And _
    WindowFromPoint($XPoint, $YPoint) = $ahWnd[$i][1] Then _
    DllStructSetData($stWinPos, 3, $aSideWinPos[0] + $aSideWinPos[2])

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

    ;Right
    If Abs($nLeft + $aCurWinPos[2] - $aSideWinPos[0]) <= $nRange And _
    WindowFromPoint($XPoint, $YPoint) = $ahWnd[$i][1] Then _
    DllStructSetData($stWinPos, 3, $aSideWinPos[0] - $aCurWinPos[2])
    EndIf

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

    If $aCurWinPos[0] + $aCurWinPos[2] >= $aSideWinPos[0] And $aCurWinPos[0] <= $aSideWinPos[0] + $aSideWinPos[2] Then
    ;Top
    If Abs(($aSideWinPos[1] + $aSideWinPos[3]) - $nTop) <= $nRange And _
    WindowFromPoint($XPoint, $YPoint) = $ahWnd[$i][1] Then _
    DllStructSetData($stWinPos, 4, $aSideWinPos[1] + $aSideWinPos[3])

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

    ;Bottom
    If Abs($nTop + $aCurWinPos[3] - $aSideWinPos[1]) <= $nRange And _
    WindowFromPoint($XPoint, $YPoint) = $ahWnd[$i][1] Then _
    DllStructSetData($stWinPos, 4, $aSideWinPos[1] - $aCurWinPos[3])
    EndIf
    Next
    EndIf
    Return 0
    EndFunc ;==>WM_WINDOWPOSCHANGING

    [/autoit]