Jump to content

UIA_IsEnabled - Loop until False changes to True


Recommended Posts

Good Evening Everyone :)

Long time since I've been in the forums - missing AutoIt and programming dearly - but on with the question... I hope this one is easy :graduated:

I am using SimpleSpy / UIAWrappers.au3 to automate an application. I basically have a "Stop" button that I am waiting to change from UIA_IsEnabled:= <False> to UIA_IsEnabled:= <True>

How do I check for the UIA_IsEnabled condition ?  Of course SimpleSpy gives all the details of GUI elements... but what code do I use to just check the GUI "Stop" buttons UIA_IsEnabled condition?

Local $oUIElement=_UIA_getObjectByFindAll($oP0, "title:=Stop;ControlType:=UIA_ButtonControlTypeId", $treescope_subtree)

Thanks!

Edited by souldjer777

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Link to comment
Share on other sites

example 12 gives example for that and also examples 19/24 show you how to catch events based on certain changes of an element.

The UIAWrappers are not having function(s) to make life easier for you. you have to read the manuals of microsoft and the few examples as given. I almost never use the events (although that is the most speediest way of determining changes).

Normally you can just get the property with

_UIA_getPropertyValue($oUIElement,"IsEnabled")

But if you do it in a tight loop it has been observed (differs per element)  sometimes that the  properties of the element are not refreshed as inner mechanism of MS DLL is caching the stuff

Link to comment
Share on other sites

Thank you junkew - I'm looking at examples right now.

That's almost what I had after some googling / digging...

Local $sTest = _UIA_GetPropertyValue($oUIElement, UIA_IsEnabled)

So close, just slightly wrong - doh!

Will try what you have - much appreciated.

Since I haven't gotten far with the examples yet - Any way to get around element caching or what is your recommendation?

FYI - My loop will sleep (5000) - Don't know if that's considered a tight loop.

Edited by souldjer777
Another question added

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Link to comment
Share on other sites

refind the object based on its automationid (for that do not use the wrappers as thats then a little much overhead)

Basically to bypass any caching you should not use findall, findfirst but use the treewalkers to get to your element.

https://docs.microsoft.com/en-us/dotnet/framework/ui-automation/caching-in-ui-automation-clients

 

Link to comment
Share on other sites

I believe I'm much closer... hope I'm doing the right thing here - but still need some help getting the property of "IsEnabled" for button "Stop" if that's even what I should do...

 

#include <CUIAutomation2.au3>

    Test123()

    Func Test123()

    Local $hWindow = WinGetHandle("My Application")
    If Not $hWindow Then Return ConsoleWrite("Window handle ERR" & @CRLF)
    ConsoleWrite("Window handle OK" & @CRLF)


    ; Create UI Automation object
    Local $oUIAutomation = ObjCreateInterface($sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation)
    If Not IsObj($oUIAutomation) Then Return ConsoleWrite("UI Automation object ERR" & @CRLF)
    ConsoleWrite("UI Automation object OK" & @CRLF)


    ; Get UI Automation element from window handle
    Local $pWindow, $oWindow
    $oUIAutomation.ElementFromHandle($hWindow, $pWindow)
    $oWindow = ObjCreateInterface($pWindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
    If Not IsObj($oWindow) Then Return ConsoleWrite("Automation element from window ERR" & @CRLF)
    ConsoleWrite("Automation element from window OK" & @CRLF)


    ; Condition to find all BUTTON elements
    Local $pCondition
    $oUIAutomation.CreatePropertyCondition($UIA_ControlTypePropertyId, $UIA_ButtonControlTypeId, $pCondition)
    If Not $pCondition Then Return ConsoleWrite("Property condition ERR" & @CRLF)
    ConsoleWrite("Property condition OK" & @CRLF)


    ; Find all BUTTON elements
    Local $pUIElementArray, $oUIElementArray, $iElements
    $oWindow.FindAll($TreeScope_Descendants, $pCondition, $pUIElementArray) ; <<<< Use your own $oWindow element <<<<<<<<<<<
    $oUIElementArray = ObjCreateInterface($pUIElementArray, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray)
    $oUIElementArray.Length($iElements)
    If Not $iElements Then Return ConsoleWrite("Find BUTTON elements ERR" & @CRLF)
    ConsoleWrite("Find all BUTTON elements OK. Elements: " & $iElements & @CRLF)

    ; Find proper BUTTON element
    Local $pBUTTON, $oBUTTON, $sName, $oProperBUTTON
    For $i = 0 To $iElements - 1


        $oUIElementArray.GetElement($i, $pBUTTON)
        $oBUTTON = ObjCreateInterface($pBUTTON, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
        $oBUTTON.GetCurrentPropertyValue($UIA_NamePropertyId, $sName)

        ConsoleWrite("Name of BUTTON element " & $i & ": " & $sName & @CRLF)

        If StringInStr($sName, 'Stop') Then

        MsgBox ( 0, '' , 'Element: ' & $i & ":" & $sName)

        Local $sTest = $oBUTTON.GetCurrentPropertyValue($UIA_NamePropertyId, "IsEnabled")

        MsgBox ( 0, '' , 'Property Value: ' & $sTest)

        ExitLoop
        EndIf


    Next

    EndFunc

I saw the MSDN example:

autoElement.GetCurrentPropertyValue(AutomationElement.IsEnabledProperty);

Return values of the property are of type Boolean. The default value for the property is false. 
Edited by souldjer777

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Link to comment
Share on other sites

FYI - I don't believe I'm getting a cached value of the "stop" button... I've been running some tests and values seem to be coming back fine with both true and false - that match the buttons current state.

I'd much rather do this the proper / recommended way - but I honestly am having difficulty finding / reading the example code / output for "My Application". Been a very long time since I tried automating using these methods. Sorry.

#include "UIAWrappers.au3"
AutoItSetOption("MustDeclareVars", 1)

Local $oP1=_UIA_getObjectByFindAll($UIA_oDesktop, "Title:=My Application;controltype:=UIA_WindowControlTypeId;class:=#32770", $treescope_children)
_UIA_Action($oP1,"setfocus")
Local $oP0=_UIA_getObjectByFindAll($oP1, "Title:=;controltype:=UIA_ToolBarControlTypeId;class:=ToolbarWindow32", $treescope_children)
_UIA_Action($oP0,"setfocus")
;~ First find the object in the parent before you can do something
;~$oUIElement=_UIA_getObjectByFindAll("Stop.mainwindow", "title:=Stop;ControlType:=UIA_ButtonControlTypeId", $treescope_subtree)
Local $oUIElement=_UIA_getObjectByFindAll($oP0, "title:=Stop;ControlType:=UIA_ButtonControlTypeId", $treescope_subtree)
;~_UIA_action($oUIElement,"highlight")
;_UIA_action($oUIElement,"click")

Local $sTest = _UIA_getAllPropertyValues($oUIElement)

MsgBox (0, "", $sTest & @error & @extended)

 

Edited by souldjer777

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Link to comment
Share on other sites

A property change event can be detected with the IUIAutomation::AddPropertyChangedEventHandlerNativeArray method which is demonstrated in the last example in this post.

In the example $UIA_ValueValuePropertyId and $UIA_ToggleToggleStatePropertyId property changes are detected. Just replace one of these with the $UIA_IsEnabledPropertyId property.

Run the code in SciTE and leave it running. Test if it detects the button enable/disable events.

Link to comment
Share on other sites

$test=UIA_getPropertyValue($oButton,"IsEnabled")

The event catching or checking in a loop is just a matter of personal preference.

Above coding is a small wrapper to get a propertyvalue by string name instead of an id but internally it conerts back to the id. You can see the mapping array inbbthe wrapper udf.

Link to comment
Share on other sites

Thank you both very much with your assistance. I appreciate the support :) and tips :graduated:

 

Edited by souldjer777

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Link to comment
Share on other sites

No junkew, It's definitely not just a matter of personal preferences. AddPropertyChangedEventHandler can detect hundreds of property events per second from multiple properties. Your code cannot.

Link to comment
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
 Share

×
×
  • Create New...