Sign in to follow this  
Followers 0
spudw2k

Need help with draggable child gui

4 posts in this topic

#1 ·  Posted (edited)

Can someone help me with this? I want to be able to drag my children guis within a parent gui, but my code does not quite work right. it works the first drag, but then moves the parent gui each subsequent drag. run the code below to see what i mean.

edit: updated code a bit. Added resize method for child guis and prevented main gui from moving using _sendmessage.

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <TreeViewConstants.au3>
#include <WindowsConstants.au3>
#include <ScrollBarConstants.au3>
#include <sendmessage.au3>
#include <WinAPI.au3>
#include <Misc.au3>

$gui = GUICreate("SpeeD Burner", 732, 556, 385, 307, $WS_SIZEBOX, BitOR($WS_EX_ACCEPTFILES,$WS_EX_WINDOWEDGE))
$src = _FileBrowser("Source")
$dest = _FileBrowser("Destination",$gui,0,254)

$mnuFile = GUICtrlCreateMenu("&File")
    $mnuFile_New = GUICtrlCreateMenuItem("&New Disc", $mnuFile)
    $mnuFile_Save = GUICtrlCreateMenuItem("&Save Disc", $mnuFile)
        GUICtrlSetState(-1, $GUI_DISABLE)
    $mnuFile_Burn = GUICtrlCreateMenuItem("&Burn Disc", $mnuFile)
        GUICtrlSetState(-1, $GUI_DISABLE)
    $mnuFile_Spacer = GUICtrlCreateMenuItem("", $mnuFile)
    $mnuFile_Exit = GUICtrlCreateMenuItem("E&xit", $mnuFile)
$mnuTools = GUICtrlCreateMenu("&Tools")
    $MenuItem1 = GUICtrlCreateMenuItem("&Burn ISO", $mnuTools)
    $MenuItem2 = GUICtrlCreateMenuItem("&Options", $mnuTools)

GUISetState(@SW_SHOW)
Dim $SpeeD_AccelTable[3][2] = [["^n", $mnuFile_New],["^s", $mnuFile_Save],["^!x", $mnuFile_Exit]]
GUISetAccelerators($SpeeD_AccelTable)

While 1
    $nMsg = GUIGetMsg(1)
    Switch $nMsg[0]
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_PRIMARYDOWN
            ;If $nMsg[1] <> $gui Then msgbox(0,"",$nMsg[1])
            If $nMsg[1] <>$gui Then $hWnd = _SendMessage($nMsg[1], $WM_SYSCOMMAND, 0xF012, 2,1)
            GUISwitch($nMsg[1])
        Case $GUI_EVENT_RESIZED
            _ResizeChild()

    EndSwitch
WEnd

Func _FileBrowser($title="",$parent=$gui,$x=0,$y=0)
    $h_cGUI = GUICreate($title, 720, 244, $x, $y, $WS_CHILD+$WS_SIZEBOX, BitOR($WS_EX_ACCEPTFILES,$WS_EX_CLIENTEDGE), $parent)
        $groupSource = GUICtrlCreateGroup($title, 8, 0, 705, 242, $WS_CLIPSIBLINGS)
            GUICtrlSetFont(-1, 12, 800, 0, "Monotype Corsiva")
            GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKBOTTOM)
        $treeviewSource = GUICtrlCreateTreeView(16, 20, 169, 213, BitOR($TVS_HASBUTTONS,$TVS_HASLINES,$TVS_LINESATROOT,$TVS_DISABLEDRAGDROP,$TVS_SHOWSELALWAYS,$WS_GROUP,$WS_TABSTOP,$WS_BORDER))
            GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKBOTTOM+$GUI_DOCKWIDTH)
        $listviewSource = GUICtrlCreateListView("", 192, 20, 513, 213, BitOR($LVS_REPORT,$LVS_SINGLESEL,$LVS_SHOWSELALWAYS,$WS_BORDER))
            GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKBOTTOM)
    GUISetState()
    GUISwitch($gui)
    Return $h_cGUI
EndFunc

Func _ResizeChild()
    $winpos = WinGetPos($nMsg[1])
    $parent = WinGetPos("SpeeD Burner")
    If $nMsg[1] <> $gui Then
        If $winpos[2] < 500 Then
            _WinAPI_SetWindowPos($nMsg[1],$HWND_TOP,$winpos[0]-$parent[0]-4,$winpos[1]-$parent[1]-50,500,$winpos[3],$SWP_SHOWWINDOW )
            $winpos = WinGetPos($nMsg[1])
            $parent = WinGetPos("SpeeD Burner")
        EndIf
        If $winpos[3] < 150 Then 
            _WinAPI_SetWindowPos($nMsg[1],$HWND_TOP,$winpos[0]-$parent[0]-4,$winpos[1]-$parent[1]-50,$winpos[2],150,$SWP_SHOWWINDOW )
            $winpos = WinGetPos($nMsg[1])
            $parent = WinGetPos("SpeeD Burner")
        EndIf
    EndIf
EndFunc

edit: It seems to start working again (kinda) if I double click or click around a whole bunch but is very unrealiable. Are there preferred alternative methods to do this task?

Edited by spudw2k

Share this post


Link to post
Share on other sites



Can someone help me with this? I want to be able to drag my children guis within a parent gui, but my code does not quite work right. it works the first drag, but then moves the parent gui each subsequent drag. run the code below to see what i mean.

edit: updated code a bit. Added resize method for child guis and prevented main gui from moving using _sendmessage.

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <TreeViewConstants.au3>
#include <WindowsConstants.au3>
#include <ScrollBarConstants.au3>
#include <sendmessage.au3>
#include <WinAPI.au3>
#include <Misc.au3>

$gui = GUICreate("SpeeD Burner", 732, 556, 385, 307, $WS_SIZEBOX, BitOR($WS_EX_ACCEPTFILES,$WS_EX_WINDOWEDGE))
$src = _FileBrowser("Source")
$dest = _FileBrowser("Destination",$gui,0,254)

$mnuFile = GUICtrlCreateMenu("&File")
    $mnuFile_New = GUICtrlCreateMenuItem("&New Disc", $mnuFile)
    $mnuFile_Save = GUICtrlCreateMenuItem("&Save Disc", $mnuFile)
        GUICtrlSetState(-1, $GUI_DISABLE)
    $mnuFile_Burn = GUICtrlCreateMenuItem("&Burn Disc", $mnuFile)
        GUICtrlSetState(-1, $GUI_DISABLE)
    $mnuFile_Spacer = GUICtrlCreateMenuItem("", $mnuFile)
    $mnuFile_Exit = GUICtrlCreateMenuItem("E&xit", $mnuFile)
$mnuTools = GUICtrlCreateMenu("&Tools")
    $MenuItem1 = GUICtrlCreateMenuItem("&Burn ISO", $mnuTools)
    $MenuItem2 = GUICtrlCreateMenuItem("&Options", $mnuTools)

GUISetState(@SW_SHOW)
Dim $SpeeD_AccelTable[3][2] = [["^n", $mnuFile_New],["^s", $mnuFile_Save],["^!x", $mnuFile_Exit]]
GUISetAccelerators($SpeeD_AccelTable)

While 1
    $nMsg = GUIGetMsg(1)
    Switch $nMsg[0]
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_PRIMARYDOWN
            ;If $nMsg[1] <> $gui Then msgbox(0,"",$nMsg[1])
            If $nMsg[1] <>$gui Then $hWnd = _SendMessage($nMsg[1], $WM_SYSCOMMAND, 0xF012, 2,1)
            GUISwitch($nMsg[1])
        Case $GUI_EVENT_RESIZED
            _ResizeChild()

    EndSwitch
WEnd

Func _FileBrowser($title="",$parent=$gui,$x=0,$y=0)
    $h_cGUI = GUICreate($title, 720, 244, $x, $y, $WS_CHILD+$WS_SIZEBOX, BitOR($WS_EX_ACCEPTFILES,$WS_EX_CLIENTEDGE), $parent)
        $groupSource = GUICtrlCreateGroup($title, 8, 0, 705, 242, $WS_CLIPSIBLINGS)
            GUICtrlSetFont(-1, 12, 800, 0, "Monotype Corsiva")
            GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKBOTTOM)
        $treeviewSource = GUICtrlCreateTreeView(16, 20, 169, 213, BitOR($TVS_HASBUTTONS,$TVS_HASLINES,$TVS_LINESATROOT,$TVS_DISABLEDRAGDROP,$TVS_SHOWSELALWAYS,$WS_GROUP,$WS_TABSTOP,$WS_BORDER))
            GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKBOTTOM+$GUI_DOCKWIDTH)
        $listviewSource = GUICtrlCreateListView("", 192, 20, 513, 213, BitOR($LVS_REPORT,$LVS_SINGLESEL,$LVS_SHOWSELALWAYS,$WS_BORDER))
            GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKTOP+$GUI_DOCKBOTTOM)
    GUISetState()
    GUISwitch($gui)
    Return $h_cGUI
EndFunc

Func _ResizeChild()
    $winpos = WinGetPos($nMsg[1])
    $parent = WinGetPos("SpeeD Burner")
    If $nMsg[1] <> $gui Then
        If $winpos[2] < 500 Then
            _WinAPI_SetWindowPos($nMsg[1],$HWND_TOP,$winpos[0]-$parent[0]-4,$winpos[1]-$parent[1]-50,500,$winpos[3],$SWP_SHOWWINDOW )
            $winpos = WinGetPos($nMsg[1])
            $parent = WinGetPos("SpeeD Burner")
        EndIf
        If $winpos[3] < 150 Then 
            _WinAPI_SetWindowPos($nMsg[1],$HWND_TOP,$winpos[0]-$parent[0]-4,$winpos[1]-$parent[1]-50,$winpos[2],150,$SWP_SHOWWINDOW )
            $winpos = WinGetPos($nMsg[1])
            $parent = WinGetPos("SpeeD Burner")
        EndIf
    EndIf
EndFunc

edit: It seems to start working again (kinda) if I double click or click around a whole bunch but is very unrealiable. Are there preferred alternative methods to do this task?

Unfortunately $nMsg[1] does not give the window clicked on as you would expect. Most of the time it will give the parent window not the child you clicked on.

I suggest you have a little function to decide which child the mouse is over and send your drag message to the correct window. You will need to have global identities for your child windows.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Unfortunately $nMsg[1] does not give the window clicked on as you would expect. Most of the time it will give the parent window not the child you clicked on.

I suggest you have a little function to decide which child the mouse is over and send your drag message to the correct window. You will need to have global identities for your child windows.

Right on. Thanks for the info. I ended up making something work using some WM_NOTIFY magic (trickery). I'm planing on making a simple CD-Burner gui for monoceres CD/DVD UDF using imapi2. Thanks for the assist.

Share this post


Link to post
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
Sign in to follow this  
Followers 0