ReeKorl Posted April 16, 2016 Share Posted April 16, 2016 Hi all, I have a script currently working which is used to monitor a piece of software which occasionally pops a messagebox that otherwise would need to be closed off manually. The script works fine for the most part, however I've noticed recently that the program it's monitoring can actually pop one of three different messageboxes I need to close, rather than just the one I was originally looking for. Currently, the script is as follows (cut down to the vitals for brevity): Global $i = 0 Do InterfaceRestart() Until $i = 1 Func InterfaceRestart() Local $hWnd1 = WinWait ("[TITLE:Interface; CLASS:#32770]","Window 1 text") WinActivate ($hWnd1) ControlClick ($hWnd1, "", "[CLASS:Button; INSTANCE:1]", "primary", 1) End Func There's some more stuff in there also, mostly pauses to allow these old systems to do something before the script activates the various sections. Now, I know I need to change the WinWaits to something along the lines of the below to wait for any one of the three windows (sample code is just for two, but can be extended easily enough): Global $i = 0 Do Do ;nothing Until WinExists ("[TITLE:Interface; CLASS:#32770]","Window 1 text") OR WinExists ("[TITLE:Interface; CLASS:#32770]","Window 2 text") ;Collect window handle here??? InterfaceRestart($hWnd1) Until $i = 1 Func InterfaceRestart($hWnd1) WinActivate ($hWnd1) ControlClick ($hWnd1, "", "[CLASS:Button; INSTANCE:1]", "primary", 1) End Func But... I need to know how to do the above AND collect the window handle so it can be passed to the restart function. I blame a lack of sleep, but I've been editing in circles for about an hour now... Any thoughts? One note about the code - I can't just make it listen for a window based on title and class alone (despite all three being of the same), as there's other ones which could pop with different window text that I absolutely cannot have this click through automatically. ~~R Link to comment Share on other sites More sharing options...
AutoBert Posted April 16, 2016 Share Posted April 16, 2016 When you like to react on one of the 3 Windows, WinWaitActive("[TITLE:Interface; CLASS:#32770]","") will do this job as you expect. Link to comment Share on other sites More sharing options...
MichaelHB Posted April 16, 2016 Share Posted April 16, 2016 I do not know if I got it right, but something like this maybe:  Local $hWnd1 While True $hWnd1 = WinGetHandle("[TITLE:Interface; CLASS:#32770]") If Not @error Then InterfaceRestart($hWnd1) Sleep(100) WEnd Func InterfaceRestart($hWnd) WinActivate ($hWnd) ControlClick ($hWnd, "", "[CLASS:Button; INSTANCE:1]", "primary", 1) End Func  Link to comment Share on other sites More sharing options...
ReeKorl Posted April 17, 2016 Author Share Posted April 17, 2016 10 hours ago, AutoBert said: When you like to react on one of the 3 Windows, WinWaitActive("[TITLE:Interface; CLASS:#32770]","") will do this job as you expect. Unless I'm completely misunderstanding the way that WinWait (and WinWaitActive) work, it won't. I was originally using WinWait (can't use Actiive as I can't guarantee the messagebox will pop focused... don't ask me why, this old program I'm monitoring was written well before my time here) which was working when I thought I was only listening for one particular window, but now I know there's three I need to wait for, hence the move to WinExists with an OR between the definitions. As I understand it, WinWait will completely freeze execution until the window specified exists, so if you try a "WinWait(Win1) OR WinWait(Win2) OR WinWait(Win3)" it will freeze at the point of looking for Win1 (or perhaps not even parse correctly at all). Not what I'm looking for - there could be a number of Win2 or Win3 that appear before Win1 does. Also, using a single listener with [TITLE:Interface; CLASS:#32770] isn't sufficient, as there's other ones with the same definition that I don't want to close down automatically. Anyway, that's not the stumbling block I have, what I need is a way to pass the window handle to the restart function, not to detect the window's existence. 10 hours ago, MichaelHB said: I do not know if I got it right, but something like this maybe:  Local $hWnd1 While True $hWnd1 = WinGetHandle("[TITLE:Interface; CLASS:#32770]") If Not @error Then InterfaceRestart($hWnd1) Sleep(100) WEnd Func InterfaceRestart($hWnd) WinActivate ($hWnd) ControlClick ($hWnd, "", "[CLASS:Button; INSTANCE:1]", "primary", 1) End Func  I sort of see what you're getting at, but I don't think I'm going to have any sort of errorlevel to interpret - all messagebox windows are effectively the same, with the only distinction being the text inside them. On the plus side, I do prefer your looping method of "While True" to the one I'm currently using!  Maybe I need to rephrase the question a little... I need to wait for (out of a set of let's say ten possible windows which could appear) one of three specific windows, then pass the handle of which one appeared to another function so it can operate on it. ~~R Link to comment Share on other sites More sharing options...
Juvigy Posted April 17, 2016 Share Posted April 17, 2016 (edited) How do you identify the 3 windows ? Michael's example is what you need - just change it a bit to pass every handle to the restart function and inside check if the window is the right one. Edited April 18, 2016 by Juvigy spell check Link to comment Share on other sites More sharing options...
ReeKorl Posted April 17, 2016 Author Share Posted April 17, 2016 (edited) The script (when it is just listening for just one specific window) is as below: Local $hWnd1 = WinWait ("[TITLE:Interface; CLASS:#32770]","Text displayed in window 1") In simple terms, the list of windows I've found that this pops are as below: WinExists ("[TITLE:Interface; CLASS:#32770]","Text displayed in window 1") OR_ WinExists ("[TITLE:Interface; CLASS:#32770]","Text displayed in window 2") OR_ WinExists ("[TITLE:Interface; CLASS:#32770]","Text displayed in window 3") OR_ ;BUT NOT THESE ONES: ;WinExists ("[TITLE:Interface; CLASS:#32770]","Text displayed in window 4") OR_ ;WinExists ("[TITLE:Interface; CLASS:#32770]","Text displayed in window 5") Line breaks added for legibility. As you can see, they all have the same title and class, but the 'type' of messagebox differs in the text inside them. Technically, the text also differs inside each 'type' but only at the end of the string with UID and timestamp. This is what we need to collect on the ones that need to stay open, and right now it's done manually by an engineer when they check the system. Automating that is something for later though, I need to get this part done so that the 'noise' alerts don't prevent the program itself from running correctly. I really would prefer not to (for example) pass a list of all windows open through to the closing routine and then detect if it needs to be closed every time it loops. I'm trying to keep this as lightweight as possible, the machines this runs on are very old and slow. Plus, potentially there's going to be tens (or even hundreds) of the ones I don't want closed when one of our engineers looks at it - we don't have anyone monitoring this over the weekend, so the ones we need to keep open may build up whilst nobody's looking. Is there really no easy way of coding "When any window which matches one of these three definitions exists, tell me what its handle is?" ~~R Edited April 17, 2016 by ReeKorl tidying code Link to comment Share on other sites More sharing options...
MichaelHB Posted April 17, 2016 Share Posted April 17, 2016 Like @Juvigy said, all you need is to change the example to something like this: Local $hWnd1 While True $hWnd1 = WinGetHandle("[TITLE:Interface; CLASS:#32770]","Text displayed in window 1") If Not @error Then InterfaceRestart($hWnd1) $hWnd1 = WinGetHandle("[TITLE:Interface; CLASS:#32770]","Text displayed in window 2") If Not @error Then InterfaceRestart($hWnd1) $hWnd1 = WinGetHandle("[TITLE:Interface; CLASS:#32770]","Text displayed in window 3") If Not @error Then InterfaceRestart($hWnd1) Sleep(100) WEnd Func InterfaceRestart($hWnd) WinActivate ($hWnd) ControlClick ($hWnd, "", "[CLASS:Button; INSTANCE:1]", "primary", 1) End Func  Link to comment Share on other sites More sharing options...
ReeKorl Posted April 17, 2016 Author Share Posted April 17, 2016 Ack... I completely missed that the sample you provided was using WinGetHandle() rather than WinExists()... must be code blindness from staring at it for too long! Thanks for the assistance (and putting up with my oversights)! I'll give it a test and report back the results - although I'm sure it'll work now I understand what you're all getting at. ~~R Link to comment Share on other sites More sharing options...
ReeKorl Posted April 24, 2016 Author Share Posted April 24, 2016 Hi all, Just a quick one to confirm that it's now working exactly as expected from those code snippets suggested. Thanks for the input! ~~R 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