GezJohnJones Posted July 12, 2015 Posted July 12, 2015 Hello, I have a problem needing a solution. I need a bit of script that will switch between active applications every 30 seconds or so. Being an absolute beginner I looked around and came up with this. While 1 ;loop indefinitely WinActivate("notepad","") ;give focus to notepad Sleep(30000) ;sleep 30 seconds WinActivate("wordpad","") ;give focus to wordpad Sleep(30000) ;sleep 30 seconds WEndThis works for my purposes as a basic switcher. But I'd like to take it a step further and be able to set parameters. I'd like the user to be able to see a list of active applications in a GUI, be able to select multiple applications to switch between, and select the switch frequency. I'm finding out how to do each part of the puzzle including creating the GUI, populating the list with data, having a textbox set the frequency etc., but I don't know how to bring it all together. Thank you for any help you can provide. GezJohnJones
JohnOne Posted July 12, 2015 Posted July 12, 2015 If you post your pieces, it will aid in the help of bringing it all together.Quite blind without it. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
Moderators Melba23 Posted July 12, 2015 Moderators Posted July 12, 2015 GezJohnJones,Welcome to the AutoIt forums.I suggest you post the code you have already cobbled together (see here how to do it) so that we have some idea of how you want to proceed - otherwise any code we might suggest could well not fit into your base idea.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
GezJohnJones Posted July 12, 2015 Author Posted July 12, 2015 Hi John & Melba. Apologies for the ignorance!! Apart from messing around in VBA, this is the first bit of coding I've got involved in and only really being doing since yesterday! If this isn't the appropriate forum for this kind of thing, or if my skill level is too low to be thinking about this just yet, please let me know. But I will do my best to show you what I got and where I want to get to. So I set out what my GUI will look like. I've used a treeview box with checkboxes because visually that seemed to do what I want. However, after some research Im thinking a multi-selectable list my be more appropriate? Here's the GUI expandcollapse popup#Region INCLUDES #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <TreeViewConstants.au3> #include <WindowsConstants.au3> #EndRegion INCLUDES #Region ### START Koda GUI section ### Form=c:\users\geraint\documents\autoit\appswitcherconfig.kxf #Region GUI $AppSwitcherConfig = GUICreate("AppSwitcher!", 265, 357, 192, 124) $lbl_AppSwitcher = GUICtrlCreateLabel("AppSwitcher!", 88, 16, 93, 23) GUICtrlSetFont(-1, 12, 800, 0, "Times New Roman") #EndRegion GUI #Region BUTTONS $Btn_Start = GUICtrlCreateButton("Start", 8, 320, 75, 25) $btn_Stop = GUICtrlCreateButton("Stop", 96, 320, 75, 25) $btn_close = GUICtrlCreateButton("Close", 184, 320, 75, 25) #EndRegion BUTTONS #Region FREQUENCY $lbl_freq = GUICtrlCreateLabel("Cycle Time (secs)", 56, 288, 87, 17) $txt_freq = GUICtrlCreateInput("30", 152, 286, 33, 21) #EndRegion FREQUENCY #Region Applications Local $TVS_Applications = GUICtrlCreateTreeView(8, 40, 249, 241, BitOR($GUI_SS_DEFAULT_TREEVIEW,$TVS_CHECKBOXES)) GUICtrlCreateTreeViewItem("NotePad", $TVS_Applications) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateTreeViewItem("Chrome", $TVS_Applications) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateTreeViewItem("Steam", $TVS_Applications) GUICtrlSetState(-1, $GUI_CHECKED) #EndRegion Applications GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $btn_close Exit EndSwitch WEndI want the createtreeviewitems to be populated by a function that retrieves the active windows. The examples I have seen bring through everything that's happening in the backgroud. I don't have anything to show in terms of code for this part, but I know I should be looking at something around WinList and arrays(?). The frequency or cycle time is set by the user. Lastly, given the settings selected in the GUI (i.e. the applications and the cycle time, I want the Start button to run this as a function, stop to stop the function but keep the GUI up, and close to close the GUI and stop any running scripts. While 1 ;loop indefinitely WinActivate("notepad","") ;give focus to notepad Sleep(30000) ;sleep 30 seconds WinActivate("wordpad","") ;give focus to wordpad Sleep(30000) ;sleep 30 seconds WEndPutting it down like this makes it evident that what was so simple in my head is actually quite complex :/GezJohnJones
JohnOne Posted July 12, 2015 Posted July 12, 2015 Winlist would be an apt place to start like you mentionPerhaps you should create a function that employs it. The function should also loop through the windows returned by WinList testing them with WinGetState to ensure they are at least visible.I would start by creating a new array in your function the same size as the array WinList returns, adding only those handles of visible windows, and maybe some other criteria, then redim (Adjust the size) of your array before returning it from the function.Keep your tasks in the project modular and focus on one task at a time. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
GezJohnJones Posted July 12, 2015 Author Posted July 12, 2015 Thanks John,So I've updated the script to get the active running windows in. Here's the updated code. Before I get on to the next step and send results to the switcher code, I have a problem with the close button and the exit button. I have to click the exit button 3 times to close, and the close button isn't working at all. expandcollapse popup#include <array.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <GUIListBox.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $AppSwitcherConfig = GUICreate("AppSwitcher!", 265, 357, 311, 154) $ApplicationList = GUICtrlCreateList("", 8, 48, 249, 227, BitOR($GUI_SS_DEFAULT_LIST, $LBS_MULTIPLESEL)) GUISetState() $lbl_AppSwitcher = GUICtrlCreateLabel("AppSwitcher!", 88, 16, 93, 23) GUICtrlSetFont(-1, 12, 800, 0, "Times New Roman") $Btn_Start = GUICtrlCreateButton("Start", 8, 320, 75, 25) $btn_Stop = GUICtrlCreateButton("Stop", 96, 320, 75, 25) $btn_close = GUICtrlCreateButton("Close", 184, 320, 75, 25) $lbl_freq = GUICtrlCreateLabel("Cycle Time (secs)", 56, 288, 87, 17) $txt_freq = GUICtrlCreateInput("30", 152, 286, 33, 21) PopulateList() While GUIGetMsg() <> -3 Sleep(50) WEnd Func PopulateList() $WinArray = WinList() For $i = 1 To $WinArray[0][0] If _isVisible($WinArray[$i][1]) And $WinArray[$i][0] <> "" Then GUICtrlSetData($ApplicationList, $WinArray[$i][0]) EndIf Next EndFunc ;==>PopulateList Func _isVisible($hWin) $state = WinGetState($hWin) If BitAND($state, 2) Then Return True Else Return False EndIf EndFunc ;==>_isVisible While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $btn_close Exit Case $Btn_Start EndSwitch WEnd
JohnOne Posted July 12, 2015 Posted July 12, 2015 Remove...While GUIGetMsg() <> -3 Sleep(50) WEnd AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
GezJohnJones Posted July 12, 2015 Author Posted July 12, 2015 Perfect! Right, on to sending the results to the switcher script. Using the help files best I can so I'm assuming I'm looking at a GUIctrlread. Thanks for the help.
GezJohnJones Posted July 12, 2015 Author Posted July 12, 2015 (edited) OK I'm stuck again. How do you return multiple values chosen from the list and put them into an array? I can only get it to return the last application I clicked. Edited July 12, 2015 by GezJohnJones spelling
Moderators Melba23 Posted July 12, 2015 Moderators Posted July 12, 2015 GezJohnJones,Time for you to discover the UDFs which offer a wider range of functionality then the native functions:expandcollapse popup#include <GUIConstantsEx.au3> #include <Array.au3> #include <GUIListBox.au3> $hGUI = GUICreate("Test", 500, 500) $ApplicationList = GUICtrlCreateList("", 10, 10, 400, 400, BitOR($GUI_SS_DEFAULT_LIST, $LBS_MULTIPLESEL)) $cButton = GUICtrlCreateButton("Read", 10, 450, 80, 30) GUISetState() PopulateList() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $cButton $aSelections = _GUICtrlListBox_GetSelItems($ApplicationList) ; UDF function to get all selections _ArrayDisplay($aSelections, "", Default, 8) EndSwitch WEnd Func PopulateList() $WinArray = WinList() For $i = 1 To $WinArray[0][0] If _isVisible($WinArray[$i][1]) And $WinArray[$i][0] <> "" Then GUICtrlSetData($ApplicationList, $WinArray[$i][0]) EndIf Next EndFunc ;==>PopulateList Func _isVisible($hWin) $state = WinGetState($hWin) If BitAND($state, 2) Then Return True Else Return False EndIf EndFunc ;==>_isVisiblePlease ask if you have any questions.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
GezJohnJones Posted July 13, 2015 Author Posted July 13, 2015 Thanks Melba, This is a steep learning curve for me but I think I get it. The UDF gets the selected item in the listbox and puts them in an array, the _ArrayDisplay shows me the results. The results shows as the following. [0] being how many selections, [1] the first selected, [2] the second selected. The selected items come through as the place on the list, not the application name. Row|Col 0[0]|2[1]|1[2]|4So how do I then get on to the next step of placing the applications names in a loop to activate the selected windows? So I need something like this, or similar. While 1 WinActivate(selection1, "") Sleep($frequency) WinActivate(selection2,"") Sleep($frequency)WEnd
Moderators Melba23 Posted July 13, 2015 Moderators Posted July 13, 2015 GezJohnJones,Look at the list of _GUICtrlListBox_* functions in the Help file - you will find another function _GUICtrlListBox_GetSelItemsText which looks as if it might be what you need. Looking through similar functions in the Help file should always be the first thing you do - it is often faster then asking here.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
GezJohnJones Posted July 13, 2015 Author Posted July 13, 2015 OK thanks for the help, it's much appreciated. I'll see if I can finish it off without pestering now haha. Cheers
Moderators Melba23 Posted July 13, 2015 Moderators Posted July 13, 2015 GezJohnJones,You are not "pestering" at all - my comment was aimed much more generally. Do not hesitate to ask in the future if you need help - after having done some "due diligence" in the Help file, of course.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
GezJohnJones Posted July 14, 2015 Author Posted July 14, 2015 Hello again! So I made some progress and the script is doing what I need.....kind of. So I have a GUI that pops up with a listbox showing me active applications. I can select multiple applications, set how long before they cycle. I press start, and the applications cycle. Good stuff. However, as you see in the code, the only way I've found to do it is to name each array index individually and make the window active in an infinite while loop. So my problems are as follows- I can only select the amount of indices I specify in the loop, i.e. if I put in array[1], [2] and [3], I must select 3 applications otherwise the loop breaks and the script closes. I've tried doing this with a "For In" but I can't specify the sleep delay. Is there another way of doing this? Note [0] returns the number of selected applications, don't know if anything can be done with this. - Once the loop starts, I can't stop it. The close button doesn't stop the script and it keeps looping. I'd like to stop it when $btn_stop, $btn_close or the exit button is pressed. I tried incorporating an exit loop but can't get it to work. Can someone take a look, please? expandcollapse popup#include <array.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <GUIListBox.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $AppSwitcherConfig = GUICreate("AppSwitcher!", 265, 357) $ApplicationList = GUICtrlCreateList("", 8, 48, 249, 227, BitOR($GUI_SS_DEFAULT_LIST, $LBS_MULTIPLESEL)) GUISetState() $lbl_AppSwitcher = GUICtrlCreateLabel("AppSwitcher!", 88, 16, 93, 23) GUICtrlSetFont(-1, 12, 800, 0, "Times New Roman") $Btn_Start = GUICtrlCreateButton("Start", 8, 320, 75, 25) $btn_Stop = GUICtrlCreateButton("Stop", 96, 320, 75, 25) $btn_close = GUICtrlCreateButton("Close", 184, 320, 75, 25) $lbl_freq = GUICtrlCreateLabel("Cycle Time (secs)", 56, 288, 87, 17) $txt_freq = GUICtrlCreateInput("30", 152, 286, 33, 21) PopulateList() While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $btn_close Exit Case $Btn_Start $aSelections = _GUICtrlListBox_GetSelItemsText($ApplicationList) Start() Case $btn_Stop EndSwitch WEnd Func PopulateList() $WinArray = WinList() For $i = 1 To $WinArray[0][0] If _isVisible($WinArray[$i][1]) And $WinArray[$i][0] <> "" Then GUICtrlSetData($ApplicationList, $WinArray[$i][0]) EndIf Next EndFunc ;==>PopulateList Func _isVisible($hWin) $state = WinGetState($hWin) If BitAND($state, 2) Then Return True Else Return False EndIf EndFunc ;==>_isVisible Func Start() $a = $aSelections[0] $freq = GUICtrlRead($txt_freq) * 1000 While 1 WinActivate($aSelections[1], "") Sleep($freq) WinActivate($aSelections[2], "") Sleep($freq) WinActivate($aSelections[3], "") Sleep($freq) WEnd EndFunc ;==>Start
Moderators Melba23 Posted July 14, 2015 Moderators Posted July 14, 2015 GezJohnJones,I have made a few changes:expandcollapse popup; Only need these includes #include <GUIConstantsEx.au3> #include <GUIListBox.au3> $AppSwitcherConfig = GUICreate("AppSwitcher!", 265, 357) $ApplicationList = GUICtrlCreateList("", 8, 48, 249, 227, BitOR($GUI_SS_DEFAULT_LIST, $LBS_MULTIPLESEL)) GUICtrlCreateLabel("AppSwitcher!", 88, 16, 93, 23) ; No need to store ControlID if you never use it GUICtrlSetFont(-1, 12, 800, 0, "Times New Roman") $Btn_Start = GUICtrlCreateButton("Start", 8, 320, 75, 25) $btn_Stop = GUICtrlCreateButton("Stop", 96, 320, 75, 25) $btn_close = GUICtrlCreateButton("Close", 184, 320, 75, 25) GUICtrlCreateLabel("Cycle Time (secs)", 56, 288, 87, 17) $txt_freq = GUICtrlCreateInput("30", 152, 286, 33, 21) GUISetState() PopulateList() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $btn_close ; Can use multiple events Exit Case $Btn_Start Start() EndSwitch WEnd Func PopulateList() $WinArray = WinList() For $i = 1 To $WinArray[0][0] If _isVisible($WinArray[$i][1]) And $WinArray[$i][0] <> "" Then GUICtrlSetData($ApplicationList, $WinArray[$i][0]) EndIf Next EndFunc ;==>PopulateList Func _isVisible($hWin) $state = WinGetState($hWin) If BitAND($state, 2) Then Return True Else Return False EndIf EndFunc ;==>_isVisible Func Start() ; Read selections $aSelections = _GUICtrlListBox_GetSelItemsText($ApplicationList) ; Check there is at least 1 If $aSelections[0] = 0 then Return $freq = Number(GUICtrlRead($txt_freq)) * 1000 ; Perhaps a check for a minimum time? While 1 ; Loop through each selection in turn For $i = 1 To $aSelections[0] ConsoleWrite("Activating: " & $aSelections[$i] & @CRLF) ;WinActivate($aSelections[$i]) ; Now wait If _Wait($freq) Then ; If we get True returned then stop ConsoleWrite("Rotation stopped" & @CRLF) Return EndIf Next WEnd EndFunc ;==>Start Func _Wait($freq) ; Get a timestamp $nTimeStamp = TimerInit() While 1 ; Check if any buttons pressed Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $btn_close ; Exit the whole script Exit Case $btn_Stop ; Return true - that will stop the rotation Return True EndSwitch ; See if the delay is passed If TimerDiff($nTimeStamp) > $freq Then ; return Flase - the rotation will continue Return False EndIf WEnd EndFuncI hope the comments are clear enough, but please do ask if you have any questions.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
GezJohnJones Posted July 14, 2015 Author Posted July 14, 2015 That's perfect. I was way out with what I was thinking I needed to do. Still, I've learnt a lot from that and that's what counts. Really, really appreciate it. Thanks again, Geraint
Moderators Melba23 Posted July 14, 2015 Moderators Posted July 14, 2015 GezJohnJones,Delighted I could help.And to anyone else reading, this thread is an excellent example of how to get focused advice. Post some code which shows you have made an effort to solve the problem yourself and explain exactly why it does not work as expected - that way we have something with which to work and more importantly the knowledge that the OP is not just expecting us to do all the work.M23 tweakster2010 1 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
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