graydwarf Posted February 22, 2015 Share Posted February 22, 2015 I'm looking for a way that my users can drag a child window (dialog) around while preventing it from leaving (rendering outside) the parent window. Attached is a mockup showing what I mean. - The child window needs to be sizeable. The way I have it now is the user can resize the window via grab handle. - The child window has an input box that resizes with the child window. - The child window is a typical tools dialog that has a title and close button. - The end solution ideally prevents the child window from going outside the parent window border at all. My mockup suggests it could but I'd rather it didn't. Before I start digging into repositioning the child window based on mouse (drag/resize) events, I was hoping there was a simple way to do this using GUI/Control Styles. Any help with this would be much appreciated. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 22, 2015 Moderators Share Posted February 22, 2015 graydwarf,Something like this looks as if it might fit most of the bill: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinApi.au3> Const $SC_MOVE = 0xF010 Global $hChild, $bChildMax = False $hMain = GUICreate("Parent", 500, 500) GUICtrlCreateLabel("", 0, 0, 0, 0) ; You need this $mMain = GUICtrlCreateMenu("New") $mChild = GUICtrlCreateMenuItem("Child", $mMain) GUISetState(@SW_SHOW) ; Prevent maximised child being moved GUIRegisterMsg($WM_SYSCOMMAND, "On_WM_SYSCOMMAND") While 1 ; Use advanced GUIGetMsg to distinguish between windows $aMsg = GUIGetMsg(1) Switch $aMsg[1] ; It is the parent Case $hMain ; Now check the message Switch $aMsg[0] Case $GUI_EVENT_CLOSE Exit Case $mChild ; Deactivate menu GUICtrlSetState($mChild, $GUI_DISABLE) ; Create child $hChild = GUICreate("Child", 300, 300, 10, 0, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX)) ; Set as child _WinAPI_SetParent($hChild, $hMain) GUISetState() EndSwitch ; Must be the child Case Else Switch $aMsg[0] 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 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 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
graydwarf Posted February 22, 2015 Author Share Posted February 22, 2015 graydwarf, Something like this looks as if it might fit most of the bill: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinApi.au3> Const $SC_MOVE = 0xF010 Global $hChild, $bChildMax = False $hMain = GUICreate("Parent", 500, 500) GUICtrlCreateLabel("", 0, 0, 0, 0) ; You need this $mMain = GUICtrlCreateMenu("New") $mChild = GUICtrlCreateMenuItem("Child", $mMain) GUISetState(@SW_SHOW) ; Prevent maximised child being moved GUIRegisterMsg($WM_SYSCOMMAND, "On_WM_SYSCOMMAND") While 1 ; Use advanced GUIGetMsg to distinguish between windows $aMsg = GUIGetMsg(1) Switch $aMsg[1] ; It is the parent Case $hMain ; Now check the message Switch $aMsg[0] Case $GUI_EVENT_CLOSE Exit Case $mChild ; Deactivate menu GUICtrlSetState($mChild, $GUI_DISABLE) ; Create child $hChild = GUICreate("Child", 300, 300, 10, 0, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX)) ; Set as child _WinAPI_SetParent($hChild, $hMain) GUISetState() EndSwitch ; Must be the child Case Else Switch $aMsg[0] 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 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 That gets me real close. Thanks for providing it. I do have a bit of a rendering problem though that I don't see in the example you provided. The child window doesn't paint on initial render and it doesn't repaint on drag. If I click on another window or the parent window, suddenly the child window paints (usually). Any ideas? I'm digging through the help file looking for anything that would help me repaint but no luck so far. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 22, 2015 Moderators Share Posted February 22, 2015 graydwarf,No ideas sorry. I just run a boring no-frills theme and it (re)paints fine for me. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
graydwarf Posted February 22, 2015 Author Share Posted February 22, 2015 The demo paints fine and it's nearly the same code except I've got some other controls on my parent window. I tried changing my window theme to classic and I still get the same behavior. The only code that's needed to create the "embedded" child window is this: _WinAPI_SetParent($g_SpeechBubbleWindow, $g_SnapShotWindow) Couple good things are coming from this. - Learning that I can place all my GUI msg's in a single loop instead of per GUI which will simplify some things for me. - I've been using Aero theme for a long time and dealing with the transparent title bar frustrations without realizing it all this time. Switching to Win7 Classic for the win. Anyway, I'll start ripping stuff out until I figure out what's causing it. Thanks. Link to comment Share on other sites More sharing options...
graydwarf Posted February 22, 2015 Author Share Posted February 22, 2015 Yeah, here we go. All you need to do is add a picture control to the parent page and suddenly the child window won't render properly. Add this to the global declarations of that sample code and point it at a valid image to repro. Global $g_idPictureControl = GUICtrlCreatePic (@WorkingDir & "\Scenarios\BYOND\Images\snapshot_21_02_2015_17_15_50.jpg", 0, 0, 0, 0) Link to comment Share on other sites More sharing options...
graydwarf Posted February 22, 2015 Author Share Posted February 22, 2015 I just changed the image size to 100,100 and now the rendering issue for the child dialog is only where the 100x100 image rendered underneath it. The rest of the child dialog rendered fine. So, windows/autoit is confused about what to repaint in this scenario. It's really weird actually because it seems to be doing a partial repaint which makes it almost seem like a timing issue for that region. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 22, 2015 Moderators Share Posted February 22, 2015 graydwarf,I have been adding controls to the parent and I see the same effect - trying to see if I can find a solution. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
graydwarf Posted February 22, 2015 Author Share Posted February 22, 2015 (edited) Thank I found a solution. Still testing. Just add $WS_CLIPSIBLINGS to the styles. This explicitly calls out the very problem in the help file. *edit* $WS_CLIPSIBLINGS - Help: "Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window." Global $g_idPictureControl = GUICtrlCreatePic (@WorkingDir & "\Scenarios\BYOND\Images\snapshot_21_02_2015_17_15_50.jpg", 0, 0, 100, 100, $WS_CLIPSIBLINGS) Edited February 22, 2015 by graydwarf Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 22, 2015 Moderators Share Posted February 22, 2015 graydwarf,Got there at the same time as you - "great minds", as they say! M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
graydwarf Posted February 22, 2015 Author Share Posted February 22, 2015 (edited) Yeah, thanks for getting me there. *edit* For anyone else coming across this issue, important to note that using 'WS_CLIPSIBLINGS' in the above scenario might interfere with your ability to interact with the picture control. I'm no longer getting GUI event messages when clicking on the image. Still troubleshooting. Edited February 22, 2015 by graydwarf ericbartha 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now