Jump to content

Clip GUIs together and move simultanioulsy


Leo1906
 Share

Recommended Posts

Hey guys, I could need your help aggain ..

Is there a way to clip GUIs together (child GUIs - in one script). So if I use WinMove with speed set to one of those GUIs, the others follow at the same speed like they where one block?
I can't think of an option to do this in pure Autoit. Creating an adlib for each GUI won't help I'm afraid, because adlibs are paused on GUI-move?

And using this type of function didn't help either: 

I can't imagine any other way of achieving multiple GUI moves at once using Autoit, because Autoit waits for the WinMove command to finish ..

Any thoughts? Maybe a build in windows function for clipping GUIs together?

 

Thanks for your help :)

Edited by Leo1906
Link to comment
Share on other sites

  • Moderators

@Leo1906 I use something like this in one of my larger scripts for pop out messages, to ensure they keep pace with the main GUI. May translate to what you are trying to accomplish:

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

Local $hGUI_Child
$hGUI_Main = GUICreate("Test", 300, 300)
    _Create_Child($hGUI_Main)
    GUIRegisterMsg($WM_MOVE, "_Position_Child")
    GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")
    GUISetState(@SW_SHOW, $hGUI_Main)
    $btnGo = GUICtrlCreateButton("Show Child", 220, 250, 70, 40)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
            Case $btnGo
                _SH_Child($hGUI_Main, "Secondary Pop Up That Follows Main", 10000)
        EndSwitch
    WEnd


Func _Create_Child($hGUI_Main)
    Local $lnCount = 100
    $hGUI_Child = GUICreate("Follower", 400, $lnCount, -1, -1, BitOR($WS_POPUP, $WS_BORDER), 0, $hGUI_Main)
    GUISetBkColor(0xCCFFCC)
    GUISetFont(11, 400, Default, "Arial")
    Global $text = GUICtrlCreateLabel("", 10, 10, 380, ($lnCount * 20) - 20)
    _Position_Child($hGUI_Main, 0, 0, 0)
    GUISetState(@SW_HIDE, $hGUI_Child)
EndFunc   ;==>_Create_Child

Func _Position_Child($hGUI_Main, $iMsg, $wParam, $lParam)
    Local $aGUI_Main_Pos = WinGetPos($hGUI_Main)
    WinMove($hGUI_Child, "", $aGUI_Main_Pos[0] + $aGUI_Main_Pos[2], $aGUI_Main_Pos[1])
EndFunc   ;==>_Position_Child

Func _SH_Child($hGUI_Main, $sText, $sLength)
    GUISetState(@SW_SHOW, $hGUI_Child)
    GUICtrlSetData($text, $sText)
    WinActivate($hGUI_Main)
    Sleep($sLength)
    GUISetState(@SW_HIDE, $hGUI_Child)
    GUICtrlSetData($text, "")
EndFunc   ;==>_SH_Child

Func _WM_NOTIFY($nWnd, $iMsg = "", $wParam = "", $lParam = "")
    Local $tStruct = DllStructCreate("hwnd;uint_ptr;int_ptr;int;int", $lParam)
    If BitAND(DllStructGetData($tStruct, 3), 0xFFFFFFFF) = $NM_CLICK Then ; Code
        $hCurrListView = DllStructGetData($tStruct, 1) ; ListView handle
    EndIf
EndFunc   ;==>_WM_NOTIFY

 

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

Unfortunately this doesn't help. I came up with another idea.
I want to create my child guis inside the parent gui and make the parent gui transparent. Then I can move the parent GUI and the child GUIs move with it at the same time. So far my thougts.
Here an example code:

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

HotKeySet("^w", "_test") ; ctrl + w

Const $SC_MOVE = 0xF010
Global $hChild, $bChildMax = False

$hMain = GUICreate("Parent", 500, 500, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED,$WS_EX_TOOLWINDOW,$WS_EX_TOPMOST,$WS_EX_LAYERED))
_WinAPI_SetLayeredWindowAttributes($hMain, 0xABCDEF, 255)
GUISetBkColor(0xABCDEF)
GUISetState(@SW_SHOW)

$hChild = GUICreate("Child", 300, 300, 10, 0, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX))
$button1 = GUICtrlCreateButton("Test", 50, 50, 50, 40)
_WinAPI_SetParent($hChild, $hMain)
GUISetState()

GUIRegisterMsg($WM_SYSCOMMAND, "On_WM_SYSCOMMAND")

While 1
    $aMsg = GUIGetMsg(1)
    Switch $aMsg[1]
        Case $hMain
            Switch $aMsg[0]
                Case $GUI_EVENT_CLOSE
                    Exit
            EndSwitch

        Case Else
            Switch $aMsg[0]
                Case $button1
                    WinMove($hMain, "", 1000, 500, 500, 500, 10)
                Case $GUI_EVENT_CLOSE
                    ; Activate menu
                    GUICtrlSetState($mChild, $GUI_ENABLE)
                    ; Clear the Maximised flag
                    $bChildMax = False
                    ; Delete child
                    GUIDelete($hChild)
                Case $GUI_EVENT_MAXIMIZE
                    ; Set the Maximised flag
                    $bChildMax = True
                Case $GUI_EVENT_MINIMIZE
                    ; Clear the Maximised flag
                    $bChildMax = False
                Case $GUI_EVENT_RESTORE
                    ; Clear the Maximised flag
                    $bChildMax = False
            EndSwitch
    EndSwitch
WEnd

Func _test()
    WinMove($hMain, "", 100, 100, 500, 500, 10)
EndFunc

Func On_WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)

    If $hWnd = $hChild Then
        ; Is the child maximised?
        If $bChildMax Then
            ;Is it a MOVE mesage?
            If BitAND($wParam, 0xFFF0) = $SC_MOVE Then Return False
        EndIf
    EndIf

    Return $GUI_RUNDEFMSG
EndFunc   ;==>On_WM_SYSCOMMAND

Works good so far. And having the invisible borders when moving the child GUIs is exactly what I want.
I think I can get this to work just fine, but there is one last thing ..

Why can't I proceed to drag the child GUI after a WinMove was made? I need to get this to work and then all will be fine :D
Any ideas?

Link to comment
Share on other sites

Ok, solved the problem with dragging the child GUIs after WinMove. The new problem is that it seems like you can't move a child GUI when some transparency is set to it. Is there a way to get around this problem?
Only thing I can imagine is to track the mouse position and when it's over the child GUI, the transparency is removed .. But that's not a very elegant way ...

Try here and press ctrl+w to see what I mean ..

 

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

HotKeySet("^w", "_test") ; ctrl + w

Global $GUIFADE_MAXTRANS = 255
Const $SC_MOVE = 0xF010
Global $hChild, $bChildMax = False
Global $numberCores = 7
Global $WorkAera = _GetWorkArea()
Global Const $SC_DRAGMOVE = 0xF012

$hMain = GUICreate("Parent", 500, 500, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED,$WS_EX_TOOLWINDOW,$WS_EX_TOPMOST,$WS_EX_LAYERED))
_WinAPI_SetLayeredWindowAttributes($hMain, 0xABCDEF, 255)
GUISetBkColor(0xABCDEF)
GUISetState(@SW_SHOW)

$hChild = GUICreate("Child", 300, 300, 10, 0, $WS_POPUP, BitOR($WS_EX_LAYERED,$WS_EX_TOOLWINDOW,$WS_EX_TOPMOST,$WS_EX_LAYERED))
GUISetBkColor(0x919191)
$button1 = GUICtrlCreateButton("Test", 50, 50, 50, 40)
_GuiRoundCorners($hChild, 0, 0, 20, 20)

_WinAPI_SetParent($hChild, $hMain)
WinSetTrans($hChild, "", 240)
GUISetState()

;~ _FadeInGUI($hChild)

;~ GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
;~ GUIRegisterMsg($WM_SYSCOMMAND, "On_WM_SYSCOMMAND")



While 1
    $aMsg = GUIGetMsg(1)
    Switch $aMsg[1]
        Case $hMain
            Switch $aMsg[0]
                Case $GUI_EVENT_CLOSE
                    Exit
            EndSwitch

        Case Else
            Switch $aMsg[0]
                Case $GUI_EVENT_PRIMARYDOWN

                    _SendMessage($hChild, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
                Case $button1
                    WinMove($hMain, "", 1000, 500, 500, 500, 10)
                Case $GUI_EVENT_CLOSE
                    ; Activate menu
                    GUICtrlSetState($mChild, $GUI_ENABLE)
                    ; Clear the Maximised flag
                    $bChildMax = False
                    ; Delete child
                    GUIDelete($hChild)
                Case $GUI_EVENT_MAXIMIZE
                    ; Set the Maximised flag
                    $bChildMax = True
                Case $GUI_EVENT_MINIMIZE
                    ; Clear the Maximised flag
                    $bChildMax = False
                Case $GUI_EVENT_RESTORE
                    ; Clear the Maximised flag
                    $bChildMax = False
            EndSwitch
    EndSwitch
WEnd

Func _GetWorkArea()
    Local $Area[6]
    Local $StartRect = DllStructCreate("int[4]")
    Local $PStartRect = DllStructGetPtr($StartRect)
    DllCall("user32.dll", "int", "SystemParametersInfo", "int", 48, "int", 0, "ptr", $PStartRect, "int", 0)
    $Area[0] = DllStructGetData($StartRect,1,1)
    $Area[1] = DllStructGetData($StartRect,1,2)
    $Area[2] = DllStructGetData($StartRect,1,3)
    $Area[3] = DllStructGetData($StartRect,1,4)
    $Area[4] = $Area[2] - $Area[0]
    $Area[5] = $Area[3] - $Area[1]
    Return $Area
EndFunc

Func _GuiRoundCorners($h_win, $i_x1, $i_y1, $i_x3, $i_y3)
    Dim $pos, $ret, $ret2
    $pos = WinGetPos($h_win)
    $ret = DllCall("gdi32.dll", "long", "CreateRoundRectRgn", "long", $i_x1, "long", $i_y1, "long", $pos[2], "long", $pos[3], "long", $i_x3, "long", $i_y3)
    If $ret[0] Then
        $ret2 = DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $h_win, "long", $ret[0], "int", 1)
        If $ret2[0] Then
            Return 1
        Else
            Return 0
        EndIf
    Else
        Return 0
    EndIf
EndFunc

Func _test()
;~  WinMove($hMain, "", 100, 100, 500, 500, 10)
WinSetTrans($hChild, "", 255)
EndFunc

Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    If ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc

Func On_WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)

    If $hWnd = $hChild Then
        ; Is the child maximised?
        If $bChildMax Then
            ;Is it a MOVE mesage?
            If BitAND($wParam, 0xFFF0) = $SC_MOVE Then Return False
        EndIf
    EndIf

    Return $GUI_RUNDEFMSG
EndFunc   ;==>On_WM_SYSCOMMAN



Func _FadeInGUI($hWnd)
    WinSetTrans($hWnd, "", 0)
    GUISetState(@SW_SHOW, $hWnd)
    For $i = 1 To $GUIFADE_MAXTRANS Step 0.05
        WinSetTrans($hWnd, "", $i)
    Next
EndFunc

Func _FadeOutGUI($hWnd)
    For $i = $GUIFADE_MAXTRANS To 0 Step -0.05
        WinSetTrans($hWnd, "", $i)
    Next
    GUISetState(@SW_HIDE, $hWnd)
EndFunc

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...