wraithdu Posted April 22, 2008 Share Posted April 22, 2008 I have a two GUI app. It opens with the parent GUI active and showing, then when the child GUI with $WS_EX_TOOLWINDOW style is opened via a button, the parent GUI is disabled (not hidden) and the child GUI is shown. How can I keep this child GUI always on top of the parent, but not necessarily on top of all windows (ie $WS_EX_TOPMOST)? What can happen otherwise is that if another window is activated over top this app, then when activating it via the parent GUI's taskbar button (remember the child is a TOOLWINDOW and does not have a taskbar button and no ALT-TAB), the parent GUI is shown but not the child GUI. There's no way to get to the child without minimizing everything else. Thanks! Link to comment Share on other sites More sharing options...
martin Posted April 22, 2008 Share Posted April 22, 2008 I have a two GUI app. It opens with the parent GUI active and showing, then when the child GUI with $WS_EX_TOOLWINDOW style is opened via a button, the parent GUI is disabled (not hidden) and the child GUI is shown. How can I keep this child GUI always on top of the parent, but not necessarily on top of all windows (ie $WS_EX_TOPMOST)? What can happen otherwise is that if another window is activated over top this app, then when activating it via the parent GUI's taskbar button (remember the child is a TOOLWINDOW and does not have a taskbar button and no ALT-TAB), the parent GUI is shown but not the child GUI. There's no way to get to the child without minimizing everything else. Thanks!If it's a child window then it will stay on top of the parent if it's made like this example #include <guiconstants.au3> #include <constants.au3> $hGui1 = GUICreate('Parent',800,600,100,100, BitOr($WS_POPUP,$WS_SIZEBOX,$GUI_SS_DEFAULT_GUI,$WS_CLIPCHILDREN)) $iBtn1 = GUICtrlCreateButton("fit",560,10,100,21,$WS_CLIPSIBLINGS) $hLV1 = GUICtrlCreateListView("lvexample",410,50,300,300) GUISetState() $child = GUICreate("child",100,100,100,100,-1,$WS_EX_TOOLWINDOW) WinMove("child","",0,0,395,600);put it in the top left DllCall("user32.dll", "int", "SetParent", "hwnd", $child, "hwnd", $hGui1) GUISetState() While 1 $msg = GUIGetMsg() If $msg = -3 Then Exit If $msg = $iBtn1 Then GUISetState(@SW_RESTORE, $child) WinMove($child,"",0,0,295,470) EndIf WEnd 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. Link to comment Share on other sites More sharing options...
wraithdu Posted April 22, 2008 Author Share Posted April 22, 2008 Thanks for the example, but I guess my 2nd GUI isn't truly a "child" window by your script. It's just a 2nd GUI window with the TOOLWINDOW style. It's exactly like your script without the DllCall command. Any way to do what I want under those circumstances? Link to comment Share on other sites More sharing options...
Squirrely1 Posted April 22, 2008 Share Posted April 22, 2008 (edited) Try this: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Constants.au3> Global $enabled = 0 Global $child = 0 Global $close_button = 78219 $hGui1 = GUICreate('Parent',500,500) $iBtn1 = GUICtrlCreateButton("Open Child", 400, 11, 80, 27) GUISetState() While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE Exit Case Not $enabled And Not WinExists($child) $enabled = 1 GUISetState(@SW_ENABLE, $hGui1) Case $msg = $iBtn1 $child = GUICreate("child",200,200,-1,-1,$WS_EX_TOOLWINDOW,-1,$hGui1) $close_button = GUICtrlCreateButton("Close", 11, 11, 68, 27) GUISetState() $enabled = 0 WinSetOnTop($child, "", 1) GUISetState(@SW_DISABLE, $hGui1) Case $msg = $close_button GUIDelete($child) $enabled = 1 GUISetState(@SW_ENABLE, $hGui1) EndSelect If WinExists($child) Then If Not WinActive($child) Then WinSetOnTop($child, "", 0) Else WinSetOnTop($child, "", 1) EndIf EndIf Sleep(40) WEnd I think this is what you want, but it doesn't work perfectly Edited April 22, 2008 by Squirrely1 Das Häschen benutzt Radar Link to comment Share on other sites More sharing options...
wraithdu Posted April 22, 2008 Author Share Posted April 22, 2008 Thanks! The WinSetOnTop loop is the ticket I think. I'm a little wary of CPU usage though, the app could be running in the backgroup as a tray icon for the duration of a user session. Oh, and for reference, I'm using OnEventMode, so it would be something like While 1 If Not WinActive($child) Then WinSetOnTop($child, "", 0) Else WinSetOnTop($child, "", 1) EndIf Sleep(250) WEnd Maybe I could dial down the loop, I really only need the child brought to the top when the parent's taskbar button is pressed. Link to comment Share on other sites More sharing options...
wraithdu Posted April 22, 2008 Author Share Posted April 22, 2008 (edited) Ahhh, this works MUCH better If Not WinActive($hGui1) Then WinSetOnTop($child, "", 0) Else WinSetOnTop($child, "", 1) EndIf Sleep(30) Much smoother transitions with the test on the parent GUI. Thanks for the pointer in the right direction. Edited April 22, 2008 by wraithdu Link to comment Share on other sites More sharing options...
martin Posted April 22, 2008 Share Posted April 22, 2008 (edited) Thanks for the example, but I guess my 2nd GUI isn't truly a "child" window by your script. It's just a 2nd GUI window with the TOOLWINDOW style. It's exactly like your script without the DllCall command. Any way to do what I want under those circumstances?Easiest way is to have something in your idle loop that checks to see if the parent becomes active when you want the focus on the child. If the child is forced to be active then you might need something on the child to allow you to get back to the parent. expandcollapse popup#include <guiconstants.au3> #include <constants.au3> $hGui1 = GUICreate('Parent', 800, 600, 100, 100, BitOR($WS_POPUP, $WS_SIZEBOX, $GUI_SS_DEFAULT_GUI, $WS_CLIPCHILDREN)) $iBtn1 = GUICtrlCreateCheckbox("keep child on top", 560, 10, 100, 21) $hLV1 = GUICtrlCreateListView("lvexample", 410, 50, 300, 300, $WS_CLIPSIBLINGS) GUISetState() $child = GUICreate("child", 150, 100, 150, 150, -1, $WS_EX_TOOLWINDOW) $chk2 = GUICtrlCreateCheckbox("allow parent on top",20,20,160,20) GUISetState() $keepchildontop = False While 1 $msg = GUIGetMsg() Switch $msg Case - 3 Exit Case $iBtn1 If BitAND(GUICtrlRead($iBtn1), $GUI_CHECKED) = $GUI_CHECKED Then $keepchildontop = True GUICtrlSetState($chk2,$GUI_UNCHECKED) Else $keepchildontop = False GUICtrlSetState($chk2,$GUI_CHECKED) EndIf Case $chk2 $keepchildontop = BitAND(GUICtrlRead($chk2),$GUI_CHECKED) = $GUI_UNCHECKED GUICtrlSetState( $iBtn1,$GUI_CHECKED + $GUI_UNCHECKED - GUICtrlRead($chk2)) EndSwitch If $keepchildontop Then If WinActive($hGui1) Then WinActivate($child) EndIf WEnd EDIT: I was a bit slow there. Squirrely1's example works well. Edited April 22, 2008 by martin 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. Link to comment Share on other sites More sharing options...
Squirrely1 Posted April 22, 2008 Share Posted April 22, 2008 (edited) In the past I have tried for some hours to make the Parent and Child thing work, and wraithdu's upgrade finally makes this script work great now: CODE#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ;#include <Constants.au3> Global $enabled = 0 Global $child = 0 Global $close_button = 78 $hGui1 = GUICreate('Parent',500,500) $iBtn1 = GUICtrlCreateButton("Open Child", 400, 11, 80, 27) GUISetState() While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE Exit Case Not $enabled And Not WinExists($child) $enabled = 1 GUISetState(@SW_ENABLE, $hGui1) Case $msg = $iBtn1 $child = GUICreate("child",200,200,-1,-1,-1,$WS_EX_TOOLWINDOW,$hGui1) $close_button = GUICtrlCreateButton("Close", 11, 11, 68, 27) GUISetState() $enabled = 0 WinSetOnTop($child, "", 1) GUISetState(@SW_DISABLE, $hGui1) Case $msg = $close_button GUIDelete($child) $enabled = 1 GUISetState(@SW_ENABLE, $hGui1) EndSelect If Not WinActive($hGui1) Then WinSetOnTop($child, "", 0) Else If WinExists($child) Then WinSetOnTop($child, "", 1) EndIf EndIf Sleep(40) WEnd But you are a real programmer, martin, not just mostly cute like me. How would you improve this code? It looks like it does too much checking to see if windows are active and if they exist, and that maybe it uses too much memory. Edited May 2, 2008 by Squirrely1 Das Häschen benutzt Radar Link to comment Share on other sites More sharing options...
wraithdu Posted April 22, 2008 Author Share Posted April 22, 2008 Again, I use OnEventMode, but here's what I went with for my While loop ; GUI loop While 1 If BitAND(2, WinGetState($eGUI)) Then ; edit is visible If WinActive($nGUI) Then WinActivate($eGUI) EndIf Sleep(30) Else Sleep(1000) EndIf WEnd Thanks guys! Link to comment Share on other sites More sharing options...
-Ultima- Posted April 23, 2008 Share Posted April 23, 2008 (edited) If you're not going to allow the parent dialog to be selected while the child dialog is visible, then you might as well not have the parent dialog enabled to begin with once you set the child to be visible... expandcollapse popup#Include <GUIConstantsEx.au3> #Include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) ; Parent -------------- Global $hParent = GUICreate("Parent", 320, 240) GUICtrlSetOnEvent(GUICtrlCreateButton("Show Child", 5, 5), "showChild") ; Child -------------- Global $hChild = GUICreate("Child", 210, 160, Default, Default, Default, $WS_EX_TOOLWINDOW, $hParent) GUICtrlSetOnEvent(GUICtrlCreateButton("Hide Child", 5, 5), "hideChild") ; Miscellaneous --------- GUISetOnEvent($GUI_EVENT_CLOSE, "appExit", $hParent) GUISetOnEvent($GUI_EVENT_CLOSE, "hideChild", $hChild) GUISetState(@SW_SHOW, $hParent) While 1 Sleep(1000) WEnd ; Functions --------- Func showChild() GUISetState(@SW_DISABLE, $hParent) GUISetState(@SW_SHOW, $hChild) WinActivate($hChild) EndFunc Func hideChild() GUISetState(@SW_ENABLE, $hParent) GUISetState(@SW_HIDE, $hChild) WinActivate($hParent) EndFunc Func appExit() Exit EndFunc (I'm not sure if this is what wraithdu is looking for, but it works like how Squirrely1's script does without the overhead) Edited April 23, 2008 by -Ultima- [ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ] Link to comment Share on other sites More sharing options...
wraithdu Posted April 23, 2008 Author Share Posted April 23, 2008 OMG, how did I miss the [parent] declaration in GUICreate?!?!? Son of a.... Link to comment Share on other sites More sharing options...
martin Posted April 23, 2008 Share Posted April 23, 2008 But you are a real programmer, martin, not just mostly cute like me. How would you improve this code? It looks like it does too much checking to see if windows are active and if they exist, and that maybe it uses too much memory.If I am a real programmer then so are we all. I haven't got any better solutions than anyone else in this thread. I don't think your script would use up too much memory though. 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. Link to comment Share on other sites More sharing options...
Squirrely1 Posted May 2, 2008 Share Posted May 2, 2008 Sorry for some resurrecting activity, but I wasn't happy that the issue raised by the OP had been satisfied in this thread, and especially, I wasn't satisfied with my code, when I found this thread in a search. So, here is a new, working version for use with MessageLoop mode, Opt("GUIOnEventMode", 0) - expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ;#include <ButtonConstants.au3>; needed if any button styles are used. Opt("MustDeclareVars", 1) ;The following line replaces $GUI_SS_DEFAULT_GUI because it doesn't appear in AutoIt v3.2.10.0 - Global Const $DEFAULT_GUISTYLES = BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU) Global $parentIsEnabled, $parent_gui, $btn_open, $child_gui, $btn_close, $msg $parent_gui = GUICreate("Parent GUI", 500, 500, -1, -1, _ BitOR($DEFAULT_GUISTYLES, $WS_CLIPCHILDREN, $WS_SIZEBOX)) $btn_open = GUICtrlCreateButton("Open Child", 400, 11, 80, 27) $parentIsEnabled = True $child_gui = GUICreate("Child GUI", 200, 200, -1, -1, _ BitOR($DEFAULT_GUISTYLES, $WS_CLIPSIBLINGS), $WS_EX_TOOLWINDOW, $parent_gui) GUISetState(@SW_SHOW, $parent_gui) GUISwitch($parent_gui) While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE If $parentIsEnabled Then ExitLoop Else GUISetState(@SW_HIDE, $child_gui) GUISetState(@SW_ENABLE, $parent_gui) $parentIsEnabled = True GUISwitch($parent_gui) ; the following line seems to be needed when running AutoIt v3.2.11.10 - WinActivate($parent_gui) EndIf Case $msg = $btn_open GUISetState(@SW_DISABLE, $parent_gui) $parentIsEnabled = False GUISetState(@SW_SHOW, $child_gui) GUISwitch($child_gui) EndSelect Sleep(40) WEnd And here is a new version for use with the OnEvent mode, Opt("GUIOnEventMode", 1) - expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ;#include <ButtonConstants.au3>; needed if any $BS_ button styles are used. Opt("GUIOnEventMode", 1) Opt("MustDeclareVars", 1) Global $parentIsEnabled, $parent_gui, $btn_open, $child_gui, $btn_close, $msg ;The following line replaces $GUI_SS_DEFAULT_GUI because it doesn't appear in AutoIt v3.2.10.0 - Global Const $DEFAULT_GUISTYLES = BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU) $parent_gui = GUICreate("Parent GUI", 500, 500, -1, -1, _ BitOR($DEFAULT_GUISTYLES, $WS_CLIPCHILDREN, $WS_SIZEBOX)) $btn_open = GUICtrlCreateButton("Open Child", 400, 11, 80, 27) $parentIsEnabled = True $child_gui = GUICreate("Child GUI", 200, 200, -1, -1, _ BitOR($DEFAULT_GUISTYLES, $WS_CLIPSIBLINGS), $WS_EX_TOOLWINDOW, $parent_gui) GUISwitch($parent_gui) GUICtrlSetOnEvent($btn_open, "showChild") GUISetOnEvent($GUI_EVENT_CLOSE, "appExit", $parent_gui) GUISetOnEvent($GUI_EVENT_CLOSE, "hideChild", $child_gui) GUISetState(@SW_SHOW, $parent_gui) While 1 Sleep(40) WEnd Func appExit() Exit EndFunc ;==>appExit Func hideChild() GUISetState(@SW_HIDE, $child_gui) GUISetState(@SW_ENABLE, $parent_gui) GUISwitch($parent_gui) $parentIsEnabled = True ; the following line seems to be needed when running AutoIt v3.2.11.10 - WinActivate($parent_gui) EndFunc ;==>hideChild Func showChild() GUISetState(@SW_DISABLE, $parent_gui) $parentIsEnabled = False GUISetState(@SW_SHOW, $child_gui) GUISwitch($child_gui) EndFunc ;==>showChild I found out two things doing this: 1. Using the beta 3.2.11.10, this was strangely required in both snippets: WinActivate($parent_gui) 2. A definition for $GUI_SS_DEFAULT_GUI was missing from the WindowsConstants.au3 in AutoIt v3.2.10.0 that was not missing from the beta version v3.2.11.10 Das Häschen benutzt Radar Link to comment Share on other sites More sharing options...
Dolemite50 Posted April 24, 2009 Share Posted April 24, 2009 Squirrly, I'm not sure if this is old news or not but it looks like the solution for having to activate the window is to show/enable the other before doing any hiding or disabling to the first. Select Case $msg = $GUI_EVENT_CLOSE If $parentIsEnabled Then ExitLoop Else GUISetState(@SW_ENABLE, $parent_gui) GUISetState(@SW_HIDE, $child_gui) $parentIsEnabled = True GUISwitch($parent_gui) EndIf Case $msg = $btn_open GUISetState(@SW_SHOW, $child_gui) GUISetState(@SW_DISABLE, $parent_gui) $parentIsEnabled = False GUISetState(@SW_SHOW, $child_gui) GUISwitch($child_gui) EndSelect 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