Jump to content

Another way to identified components?


Recommended Posts

Hello everyone,

I’m quite new with AutoIt.

I’m using it to automate test of software. So I’m making scripts that make a sequence of action on the GUI of the software.

But often it’s seems that the script lost his way, I guess it’s because the custom component of software change their instance:

ControlClick($cst_WinTitle, "", "[CLASS:AfxWnd80; INSTANCE:3]", "secondary")

For example, and sometimes the same component change its instance and it’s 9. It’s really annoying. Do you have any clues to fix that and be sure of the identification of a component?

Thanks a lot!

Link to comment
Share on other sites

It's "our apps", I'm working at EVS. Its made in C++.

Posted Image

http://www.live-production.tv/system/files/imagecache/FW_GALLERY/Thumbnails.PNG

http://www.live-production.tv/system/files/imagecache/FW_GALLERY/Timeline.PNG

http://www.live-production.tv/system/files/imagecache/FW_GALLERY/Keywords_Grid.PNG

http://www.live-production.tv/case-studies/production-facilities/support-xdcam-evs-server-environment.html

Edited by Vincs
Link to comment
Share on other sites

  • 2 weeks later...

So, if the control instances change, is there more then 1 instance of the class at a time (or can Instance just be skipped?)? And if so, can the control then maybe identified by the order of creation? Give Ascend4nts _EnumChildWindows UDF a try...

Link to comment
Share on other sites

Yeah, I see. What about looping through the resulting array? I see a pattern in the AfxWnd80 classname occurence.

Try something like _EnumChildWindows($hWnd,0,0,"AfxWnd80"), this should result in something like this:

[4]|0x000605EC|AfxWnd80|4001|1|

[5]|0x00070612|AfxWnd80|4002|2|

[6]|0x0006055E|AfxWnd80|1|3|

[7]|0x01AB07A8|AfxWnd80|2|4|

[8]|0x00100758|AfxWnd80|3|5|

[9]|0x002B07DC|AfxWnd80|4|6|

[10]|0x000707FA|AfxWnd80|5|7|

[19]|0x0006058A|AfxWnd80|1000|8|

[30]|0x0031068E|AfxWnd80|2002|9|

[31]|0x0006055A|AfxWnd80|1|10|

[32]|0x002E0626|AfxWnd80|2|11|

[33]|0x000605F6|AfxWnd80|3|12|

[34]|0x0008062A|AfxWnd80|4|13|

[35]|0x000705FA|AfxWnd80|5|14|

[69]|0x000F0148|AfxWnd80|6001|15|

[70]|0x000C01F0|AfxWnd80|1|16|

[71]|0x001501F2|AfxWnd80|2|17|

[72]|0x002D03D0|AfxWnd80|3|18|

[73]|0x007303C6|AfxWnd80|4|19|

[74]|0x002603EE|AfxWnd80|5|20|

First there two controls with id of 4000+ then there are 5 starting from 1, then 1000 & 2002, then 5 starting from 1 again, then 6000, then again 5 starting from 1. Looping through the array and definying some rules (e.g. 2nd handle of 2nd 5er bunch) might help you.

Link to comment
Share on other sites

The result looks just like you said, the same controls, but apparently created in a different order...nevertheless the same creation pattern. Try this:

$aHwndChilds = _EnumChildWindows($hWnd, 0, 0, "AfxWnd80")
Dim $aHwndChilds_cID_1[1]
Dim $aHwndChilds_cID_4[1]
Dim $aHwndChilds_cID_6[1]

$iSwitchFillArray = 0
For $i = 1 To $aHwndChilds[0][0]
    If StringLen($aHwndChilds[$i][2], 4) Then
        Switch StringLeft($aHwndChilds[$i][2], 1)
            Case 1
                $iSwitchFillArray = 1
            Case 4
                $iSwitchFillArray = 4
            Case 6
                $iSwitchFillArray = 6
        EndSwitch
    EndIf
    Switch $iSwitchFillArray
        Case 1
            $aHwndChilds_cID_1[0] = +1
            ReDim $aHwndChilds_cID_1[UBound($aHwndChilds_cID_1) + 1]
            $aHwndChilds_cID_1[UBound($aHwndChilds_cID_1) - 1] = $aHwndChilds[$i][0]
        Case 4
            $aHwndChilds_cID_4[0] = +1
            ReDim $aHwndChilds_cID_4[UBound($aHwndChilds_cID_4) + 1]
            $aHwndChilds_cID_4[UBound($aHwndChilds_cID_4) - 1] = $aHwndChilds[$i][0]
        Case 6
            $aHwndChilds_cID_6[0] = +1
            ReDim $aHwndChilds_cID_6[UBound($aHwndChilds_cID_6) + 1]
            $aHwndChilds_cID_6[UBound($aHwndChilds_cID_6) - 1] = $aHwndChilds[$i][0]
    EndSwitch
Next

_ArrayDisplay($aHwndChilds_cID_1)
_ArrayDisplay($aHwndChilds_cID_4)
_ArrayDisplay($aHwndChilds_cID_6)

The resulting arrays should always point the the same control handles... of course you'll have to test which group is relevant to you :mellow:, use au3info to check which batch suites your needs.

Edit: Ubound error in for loop, that happens if you write code without being able to test it :P...

Edited by KaFu
Link to comment
Share on other sites

A strange thing is that The ID doesn't match the instance between two launches of the software.

I've run the little file you give to me.

I don't really understand the aim of it, you're trying to put the component in different array depending of the length of id number ?

Only the last array is filled the other are blank.

StringLen($aHwndChilds[$i][2], 4)

Is the 4 normal ? I deleted it to make the script working.

EnumFiltred.txt

Link to comment
Share on other sites

StringLen($aHwndChilds[$i][2], 4)

Is the 4 normal ? I deleted it to make the script working.

No, it is not... it's a typo :mellow: ... retest script below. To me it seems that there are 3 different sets of controls which are not created in the same order every time. A new set starts with a control id of a length of 4 (4001,1000,6001). Thus the script below loops through all controls and tries to assign every control to one of the sets. So regardless of the order of creation, e.g. $aHwndChilds_cID_4[4] should always return the handle for one specifc control.

$aHwndChilds = _EnumChildWindows($hWnd, 0, 0, "AfxWnd80")
Dim $aHwndChilds_cID_1[1]
Dim $aHwndChilds_cID_4[1]
Dim $aHwndChilds_cID_6[1]

$iSwitchFillArray = 0
For $i = 1 To $aHwndChilds[0][0]
    If StringLen($aHwndChilds[$i][2]) = 4 Then
        Switch StringLeft($aHwndChilds[$i][2], 1)
            Case 1
                $iSwitchFillArray = 1
            Case 4
                $iSwitchFillArray = 4
            Case 6
                $iSwitchFillArray = 6
        EndSwitch
    EndIf
    Switch $iSwitchFillArray
        Case 1
            $aHwndChilds_cID_1[0] = +1
            ReDim $aHwndChilds_cID_1[UBound($aHwndChilds_cID_1) + 1]
            $aHwndChilds_cID_1[UBound($aHwndChilds_cID_1) - 1] = $aHwndChilds[$i][0]
        Case 4
            $aHwndChilds_cID_4[0] = +1
            ReDim $aHwndChilds_cID_4[UBound($aHwndChilds_cID_4) + 1]
            $aHwndChilds_cID_4[UBound($aHwndChilds_cID_4) - 1] = $aHwndChilds[$i][0]
        Case 6
            $aHwndChilds_cID_6[0] = +1
            ReDim $aHwndChilds_cID_6[UBound($aHwndChilds_cID_6) + 1]
            $aHwndChilds_cID_6[UBound($aHwndChilds_cID_6) - 1] = $aHwndChilds[$i][0]
    EndSwitch
Next

_ArrayDisplay($aHwndChilds_cID_1)
_ArrayDisplay($aHwndChilds_cID_4)
_ArrayDisplay($aHwndChilds_cID_6)
Link to comment
Share on other sites

It works, it makes 3 arrays.

But I still don't understand how to use it, especially the hexadecimal value displayed in the array.

And I don't understand how you're sorting the array in the second switch :mellow: (and you could do it in only one switch no, don't you?)

Anyway, I really appreciate your concern and assist.

Link to comment
Share on other sites

But I still don't understand how to use it, especially the hexadecimal value displayed in the array.

The hex values are the handles of the controls (valid system-wide), controlids are only valid per application. Control functions in au3 can be accessed using either the controlid or the handle, both are valid inputs.

Start your app, start this script and start au3info. Use au3info to find the control handle you're looking for, compare that value to the result of the arrays to identify your control.

Lets say you find that the button you want to click has in au3info the same control handle as the 3rd element of the second array... then something like this:

ControlClick($cst_WinTitle, "", $aHwndChilds_cID_4[3], "secondary")

should always work (assuming you incooperate my script as a function :P ).

And I don't understand how you're sorting the array in the second switch :mellow: (and you could do it in only one switch no, don't you?)

No, because the first switch is only triggered if the controlid has 4 digits, the second switch is triggered every time using a trigger set by the first switch (or the old one if first switch was not triggered in current loop). This is because of the pattern in control creation, only certain controlids indicate that a new set starts. Edited by KaFu
Link to comment
Share on other sites

Ok I will try this next time I will make an apps.

(I don't want to rewrite the whole apps for now, I've found a few work around to avoid the trouble).

Really really thanks !

P.S.: Why the spy doesn't display the handles of the controls ? There are unique system wide ? Or they change every time we restart the apps ?

Edited by Vincs
Link to comment
Share on other sites

Hello !

It's me again :mellow:

I was trying to identify component on an other application.

The strange thing is that TestPartner detect and display the components much deeper than AutoIt spy. (See the screenshot).

TestPartner : Posted Image AutoIt : Posted Image

And when I launch the EnumChild it finds the component.

Edited by Vincs
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...