tshaffer Posted May 28, 2014 Share Posted May 28, 2014 I am trying to write an AutoIt script to use a search feature in a program and print out some records. I am having issues with the script moving on before the program is ready. So far I am trying to trigger the next steps based on the active windows title(WinWaitActive()), and the status of the cursor(Do Sleep(500) Until MouseGetCursor() == 2), however the script keeps trying to do the next step before the application is ready. It will try to select a record before the search results have been returned, or it will try to open the file-> print options before the item I searched for has finished loading. Are there any other common tricks for determining the status of an application in order to tell if it is ready for the next step of the script? Any help would be appreciated. Link to comment Share on other sites More sharing options...
Sori Posted May 28, 2014 Share Posted May 28, 2014 Perhaps looking for certain text inside the window, or if you don't care about resources you could use image search. If you need help with your stuff, feel free to get me on my Skype. I often get bored and enjoy helping with projects. Link to comment Share on other sites More sharing options...
Moderators JLogan3o13 Posted May 29, 2014 Moderators Share Posted May 29, 2014 Any help would be appreciated. Help us help you, post your script or a reproducer. "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum! Link to comment Share on other sites More sharing options...
tshaffer Posted May 29, 2014 Author Share Posted May 29, 2014 I am not sure what the code will do for you as you are not able to see it in action as it acting against a propriatary dental records application. but you will find a copy of the script attached. The current pain points are at line 49 when sometimes the cursor changes to an arrow while its still loading the patient, and line 88 where i ended up putting in an arbitrarily large pause (10 seconds) in order to give it time to load the record. Note that the end goal is to have it process ~70k patients so efficency is really important as under the current script takes ~1 minute per patient so it will take ~2 months to process all of the records. I think if everything was running smoothly and optimally it could be closer to 15 seconds per patient. Script.au3 Link to comment Share on other sites More sharing options...
jdelaney Posted May 29, 2014 Share Posted May 29, 2014 Ouch, at 15 seconds each, that would take 12 days. You should look into database updates, instead. IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
tshaffer Posted May 29, 2014 Author Share Posted May 29, 2014 Would be nice, but im not making updates...im printing their dental chart to a PDF so they can be exported into a new system. the current application is horribly slow, which as I understand is a primary modivation to move to a new system. The dental charts have to be printed from inside the application Link to comment Share on other sites More sharing options...
BrewManNH Posted May 29, 2014 Share Posted May 29, 2014 As previously mentioned, you might want to look for the text in the windows rather than the mouse cursor changing. That doesn't seem very robust, and is extremely error prone. Also, don't use Send if you can avoid it, use ControlSend to send the text to the control you need the text in rather than tabbing through the window, if anything comes up that causes the window to lose focus, your sends are going to the wrong place and you're going to have to start all over again. Also, don't use == unless you're doing case sensitive string comparisons, it shouldn't affet this script, but it might in the future. Another thing, you should be using FileReadLine in a loop and not opening and closing the text file every time, and then deleting the line from the file. You'd probably see a huge decrease in the time taken over the run of the program. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
tshaffer Posted May 29, 2014 Author Share Posted May 29, 2014 For anyone looking for extra tricks while doing similar tasks I ended up coming up with decent solution. The first issue was waiting for the search to finish...select the item and then open it. What ended up working was starting the search, sending '!o' (alt open) in a loop, when the search was ready it would pop up a box saying that no item was selected. At that point I exit out of the notification box. select the item and open it. The second issue involved waiting for the patient chart to open so it was ready to open the file menu and print the item. again i started a do until loop that would continually try to open an inocuouse popup ('!h' followed by 'a' to open the help menu's about box). once it successfully opened the 'about' textbox then i closed it and opened the file menu -> print. Thanks for the help, I will let you konw if i have any further issues. For reference the current script is attached Script.au3 Link to comment Share on other sites More sharing options...
jdelaney Posted May 29, 2014 Share Posted May 29, 2014 Your script may work once or twice, but to get through ALL records with send, is impossible. There are tons of things you can do, to make your script more robust, and already mentioned above... Another one you should look into is: #include <WinAPI.au3> $hPopup = _WinAPI_GetWindow($hParent,6) This will actually get your enabled popups window, rather than just waiting in a loop for the active window to match your title...If some other process opens a window, and becomes active, then your script will never finish..._winapi_getwindow will get the window, regardless IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
tshaffer Posted May 29, 2014 Author Share Posted May 29, 2014 I am looking through the documentation for ControlSend and I am not sure I follow, how am I supposed to get the ControlID of the appropriate control that it is supposed to send the command to? Link to comment Share on other sites More sharing options...
BrewManNH Posted May 29, 2014 Share Posted May 29, 2014 There is a program in the AutoIt folder called Au3Info (or Au3Info_64) that will allow you to find that out. Drag the pointer to the controls you want to work with and it will tell you. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
tshaffer Posted May 29, 2014 Author Share Posted May 29, 2014 What about when part of the title is dynamic, it doesnt seem to work if you give it no title or a partial title. Link to comment Share on other sites More sharing options...
BrewManNH Posted May 29, 2014 Share Posted May 29, 2014 As the help file states, you can use partial title matches depending upon what you set Opt("WinTitleMatchMode", x) to. The default is to match what you put in as a partial match starting from the begining of the title. You can also use mode 2 which matches the title text anywhere in the title. You can also make it case insensitive by using -1 through -4. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
tshaffer Posted May 30, 2014 Author Share Posted May 30, 2014 I am having some major issues with switching it to use ControlSend. The script keeps seeing the controls before they open and doing stuff on non visable controls. For example the first thing I do is open the patient search window (F2) and then wait for the active title to be "Select Patient" The problem is the WinWaitActive("Select Patient") command fires off seconds before the box is visable on the screen. I then enter the search term and start the search which seems to work fine if I am using the 'Send' command, but when I use ControlSend it is sending those commands to a box that isnt even loaded yet and never performs the commands. Any idea what I might be doing wrong? Link to comment Share on other sites More sharing options...
jdelaney Posted May 30, 2014 Share Posted May 30, 2014 (edited) The state 'active' of a window, is only one of many. You should wait for it to be enabled, and visible as well...I don't think it can be active with out visibility, but still a good check. WinGetState Also, add logging, and a msgbox() so you can debug that you are in fact focusing on the proper window...again, use the window info tool, and match the handles. Even after the window is present, you still need to loop until the control is present, also. ControlGetHandle Edited May 30, 2014 by jdelaney IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
tshaffer Posted May 30, 2014 Author Share Posted May 30, 2014 Thanks again for all the help. I ended up writing a method to watch for a specific window title to be visable which really helped. It is no longer getting hung up on sending a command to a control before it is ready as long as I call this method first: Func WaitForWindowVisable($title) Local $hWnd Local $iState $hWnd = WinWaitActive($title) do Sleep(250) $iState = WinGetState($hWnd) Until BitAND($iState, 2) EndFunc Link to comment Share on other sites More sharing options...
jdelaney Posted May 30, 2014 Share Posted May 30, 2014 (edited) Add Enabled to that, as well: Until BitAND($iState, 2) and BitAND($iState, 4) Then you can add error handling: Func WaitForWindowVisable($title,$iTimeout=5000) Local $hWnd Local $iState Local $iTimer = TimerInit() $hWnd = WinWaitActive($title,"",$iTimeout) If Not IsHWnd($hWnd) Then ConsoleWrite("Window did not activate" & @CRLF) Return False EndIf $iState = WinGetState($hWnd) If BitAND($iState, 2) And BitAND($iState, 4) Then Return $hWnd EndIf While TimerDiff($iTimer)<$iTimeout $iState = WinGetState($hWnd) If BitAND($iState, 2) And BitAND($iState, 4) Then Return $hWnd EndIf Sleep(10) WEnd ConsoleWrite("Window state did not update" & @CRLF) Return False EndFunc Outside the function, check if the return IsHwnd, and continue if it is, or continueloop You could even just loop until WinExists, and then WinActivate it yourself. Edited May 30, 2014 by jdelaney IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. Link to comment Share on other sites More sharing options...
JohnComputerGuy Posted May 30, 2014 Share Posted May 30, 2014 You might try this after the WinWaitActive and before a sleep command IF WinExists(SameThingAsInWinWaitActive) Then Sleep(5000) Link to comment Share on other sites More sharing options...
jdelaney Posted May 30, 2014 Share Posted May 30, 2014 The window must exist, for it to be active. So it would be redundant after. IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window. 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