GUI am Bildschirmrand Taskbar unter Win64 andocken geht nicht

  • Hallo liebe AutoIt.de Gemeinde!

    Ich versuche vergeblich, dieses Script unter Windows 7 x64 zum laufen zu bringen. Mit Autoit32 funktioniert das, aber leider nicht unter Autoit64.
    Das Problem liegt an Local $nLeft = DllStructGetData($stWinPos, 3) und Local $nTop = DllStructGetData($stWinPos, 4), da diese in Zeile 76 und 77 unter Autoit64 nur 0 zurückgeben, was bei Autoit32 nicht der Fall ist. Ich wüsste auch keine Möglichkeit, dies zu umgehen. Wie kann ich das auch unter Autoit64 zum laufen bringen?

    Das Script:

    Spoiler anzeigen
    [autoit]

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_UseUpx=n
    #AutoIt3Wrapper_UseX64=y
    #AutoIt3Wrapper_Run_AU3Check=n
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #cs ----------------------------------------------------------------------------

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

    AutoIt Version: 3.3.6.1
    Author: Burak Keskin

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

    Script Function:
    None.

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

    #ce ----------------------------------------------------------------------------

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

    ; Script Start - Add your code below here

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

    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <EditConstants.au3>

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

    Global Const $WM_EXITSIZEMOVE = 0x0232
    Global Const $SC_MOVE = 0xF010
    Global Const $SC_SIZE = 0xF000

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

    Global $nRange = 20
    Global $IsSideWinStick = False ;True for sticking to all visible windows ( it's hangs up CPU).

    [/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]
  • tausche Zeile75 gegen : Local $stWinPos = DllStructCreate("uint64;uint64;int;int;int;int;uint", $lParam)
    PS. Damit wird Dein Script aber in der Form ein 64-bit Script.
    Eventuell vorher OSArch prüfen und dementsprechen auswählen ...

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

  • Woah vielen Dank Schnuffel. Mein Fehler war, dass ich dort überall 64 angehängt habe.

    Hier das fertige Script, dass unter Autoit 32 und 64 lauffähig ist:

    Spoiler anzeigen
    [autoit]

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_UseUpx=n
    #AutoIt3Wrapper_UseX64=y
    #AutoIt3Wrapper_Run_AU3Check=n
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #cs ----------------------------------------------------------------------------

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

    AutoIt Version: 3.3.6.1
    Author: Burak Keskin

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

    Script Function:
    None.

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

    #ce ----------------------------------------------------------------------------

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

    ; Script Start - Add your code below here

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

    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <EditConstants.au3>

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

    Global Const $WM_EXITSIZEMOVE = 0x0232
    Global Const $SC_MOVE = 0xF010
    Global Const $SC_SIZE = 0xF000

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

    Global $nRange = 20
    Global $IsSideWinStick = False ;True for sticking to all visible windows ( it's hangs up CPU).

    [/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 $sAdd = ''
    If @AutoItX64 Then $sAdd = '64'
    Local $stWinPos = DllStructCreate("uint" & $sAdd & ";uint" & $sAdd & ";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][/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]