SamuelKerschbaumer Posted March 24, 2008 Share Posted March 24, 2008 Hi. Is there a possibility to ignore an invisible control. I mean such that when I do ControlGetHandle("", "", "CLASS:Button; TEXT:Test") i only want to get the handle of a visible button. The background of my question: I want to automate a program using a wizard (you know, those Next, Next, Finish dialogs). Unfortunately when clicking next, the contents of the previous page is still present in memory, the window tree looks like this: #32770 "Wizard" |- #32770 "" | | - Control 1 of page 1 | | - Control 2 of page 1 | - Button "Test" - #32770 "" | - Control 1 of page 2 | - Control 2 of page 2 - Button "Test" So when I search using string above, I might get (and I do actually) the wrong Button. A possibility to avoid the problem is ignoring the invisible controls, since the button of the first page is invisible. Any other suggestions? Did anyone of you have the same problem? Regards Link to comment Share on other sites More sharing options...
MHz Posted March 24, 2008 Share Posted March 24, 2008 Perhaps do a check with ControlCommand() first on the control. Look at using "IsVisible" and "IsEnabled" parameters. ControlCommand('', '', '', 'IsVisible') ControlCommand('', '', '', 'IsEnabled') Link to comment Share on other sites More sharing options...
SamuelKerschbaumer Posted March 24, 2008 Author Share Posted March 24, 2008 Perhaps do a check with ControlCommand() first on the control. Look at using "IsVisible" and "IsEnabled" parameters. ControlCommand('', '', '', 'IsVisible') ControlCommand('', '', '', 'IsEnabled') Yeah, but if I am checking the control returned from ControlGetHandle(), it is already too late. I need ControlGetHandle() to ignore the invisible Controls. Link to comment Share on other sites More sharing options...
weaponx Posted March 24, 2008 Share Posted March 24, 2008 Why is it too late? Check the visibility of the control after each handle is found, if its invisible then break the loop. $cID = ;ControlID ;Not required yet since ControlCommand requires ControlID, NOT HWND. ;$handle = ControlGetHandle("") If ControlCommand('', '', $cID, 'IsVisible') AND ControlCommand('', '', $cID, 'IsEnabled') Then ;Perform action EndIf Link to comment Share on other sites More sharing options...
SamuelKerschbaumer Posted March 25, 2008 Author Share Posted March 25, 2008 Why is it too late? Check the visibility of the control after each handle is found, if its invisible then break the loop. Hmm which loop? I have two buttons, both with the same text, one visible, the other one invisible. I want to click at the visible button. Where do you see a loop there? But anyway, I think I found a solution: Just add the INSTANCE: parameter and keep increasing the instance number until no more components are found. Not very elegant though... Is there another possibility, like ControlGetAllHandles("", "", "[.....]") which returns all handles that match a condition? Regards Link to comment Share on other sites More sharing options...
MHz Posted March 25, 2008 Share Posted March 25, 2008 Yeah, but if I am checking the control returned from ControlGetHandle(), it is already too late.I need ControlGetHandle() to ignore the invisible Controls.That is why you check before. Link to comment Share on other sites More sharing options...
SamuelKerschbaumer Posted March 26, 2008 Author Share Posted March 26, 2008 That is why you check before.That is not possible. Please re-read my post and try to understand whats the problem. Link to comment Share on other sites More sharing options...
FreeFry Posted March 26, 2008 Share Posted March 26, 2008 I use this for an auto-installer I made for winamp: Func _ControlWaitVisible($ivWindowhWnd, $svText, $ivControlID, $ivTimeout = 0) If Not WinExists($ivWindowhWnd, $svText) Then SetError(1) ; window doesn't exist Return 0 EndIf Local $ivTimer = TimerInit() Do Sleep(250) Until ControlCommand($ivWindowhWnd, "", $ivControlID, "IsVisible", "") Or ($ivTimeout > 0 And TimerDiff($ivTimer) > $ivTimeout) If $ivTimeout > 0 And TimerDiff($ivTimer) > $ivTimeout Then SetError(2) ; Timeout Return 0 EndIf SetError(0) Return 1 EndFunc Works like WinWait does.. Link to comment Share on other sites More sharing options...
SamuelKerschbaumer Posted March 26, 2008 Author Share Posted March 26, 2008 I use this for an auto-installer I made for winamp: Func _ControlWaitVisible($ivWindowhWnd, $svText, $ivControlID, $ivTimeout = 0) If Not WinExists($ivWindowhWnd, $svText) Then SetError(1) ; window doesn't exist Return 0 EndIf Local $ivTimer = TimerInit() Do Sleep(250) Until ControlCommand($ivWindowhWnd, "", $ivControlID, "IsVisible", "") Or ($ivTimeout > 0 And TimerDiff($ivTimer) > $ivTimeout) If $ivTimeout > 0 And TimerDiff($ivTimer) > $ivTimeout Then SetError(2) ; Timeout Return 0 EndIf SetError(0) Return 1 EndFunc Works like WinWait does.. But is not solving my problem. Let my quote myself: I have two buttons, both with the same text, one visible, the other one invisible. I want to click at the visible button. Anyway, I found some solutions (not very nice, though). Link to comment Share on other sites More sharing options...
FreeFry Posted March 26, 2008 Share Posted March 26, 2008 just use INSTANCE: in the control ID part if that's the case. Or you could create a function that finds the visible button of all the classnames... Something like this?: Func _ControlFindVisible($svTitle, $svText, $svCtrlClass) Local $i = 1 Do If ControlCommand($svTitle, $svText, "[CLASS:" & $svCtrlClass & "; INSTANCE:" & $i & "]", "IsVisible", "") Then ExitLoop $i += 1 Until $i >= 100 If $i >= 100 Then SetError(1) ; None was found Return 0 EndIf SetError(0) Return String($svCtrlClass & $i) EndFunc Link to comment Share on other sites More sharing options...
Siao Posted March 26, 2008 Share Posted March 26, 2008 (edited) If INSTANCE of each button is not constant, then $hWndParent = WinGetHandle("Test window") $hX = 0 Do $hX = _FindWindowEx($hWndParent,$hX,"Button","Test") Until $hX = 0 Or BitAND(WinGetState($hX), 2) Func _FindWindowEx($hWndParent, $hWndChildAfter, $sClassName, $sWinTitle="") Local $aRet = DllCall('user32.dll','hwnd','FindWindowEx', 'hwnd',$hWndParent, 'hwnd',$hWndChildAfter, 'str',$sClassName, 'str',$sWinTitle) Return $aRet[0] EndFunc Edited March 26, 2008 by Siao "be smart, drink your wine" 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