Sign in to follow this  
Followers 0
SamuelKerschbaumer

Ignore Invisible Controls

11 posts in this topic

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

Share this post


Link to post
Share on other sites



Perhaps do a check with ControlCommand() first on the control.

Look at using "IsVisible" and "IsEnabled" parameters.

ControlCommand('', '', '', 'IsVisible')
ControlCommand('', '', '', 'IsEnabled')

:)

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

That is why you check before.

That is not possible. Please re-read my post and try to understand whats the problem.

Share this post


Link to post
Share on other sites

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..

Share this post


Link to post
Share on other sites

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).

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

#11 ·  Posted (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 by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0