Jump to content

Recommended Posts

Posted

Hi there,

I tried to get a selected/highlighted item in a SysTreeView32 control. Unfortunately, with the basic commands e.g. ControlTreeView ther is no way to get control.

The output of the Window Info tool:

  Quote

>>>> Control <<<<
Class:    SysTreeView32
Instance:    3
ClassnameNN:    SysTreeView323
Name:    
Advanced (Class):    [CLASS:SysTreeView32; INSTANCE:3]
ID:    1089
Text:    Tree1
Position:    778, 146
Size:    478, 428
ControlClick Coords:    172, 218
Style:    0x50011027
ExStyle:    0x00020305
Handle:    0x00000000000B02E8

Expand  

So I would like to go an alternative way and make use of the CUIAutomation functionality. I started with this piece of code from this topic.

This helped me to get the text of all items in the treeview but how can I receive only the text of the selected item in the program?

The output of UI Spy:
 

  Quote

 

AutomationElement
  General Accessibility
    AccessKey:    ""
    AcceleratorKey:    ""
    IsKeyboardFocusable:    "True"
    LabeledBy:    "(null)"
    HelpText:    ""

  State
    IsEnabled:    "True"
    HasKeyboardFocus:    "False"

  Identification
    ClassName:    ""
    ControlType:    "ControlType.TreeItem"
    Culture:    "(null)"
    AutomationId:    ""
    LocalizedControlType:    "Strukturelement"
    Name:    "*********"
    ProcessId:    "4980 (OM_64)"
    RuntimeId:    "1 721640 0 312827120"
    IsPassword:    "False"
    IsControlElement:    "True"
    IsContentElement:    "True"

  Visibility
    BoundingRectangle:    "(838, 509, 230, 18)"
    ClickablePoint:    "(null)"
    IsOffscreen:    "False"

ControlPatterns
  ExpandCollapse
    ExpandCollapseState:    "LeafNode"

  SelectionItem
    IsSelected:    "True"
    SelectionContainer:    ""Struktur" """

 

Expand  

Many thanks in advance.

 

Posted

I've never had an issue using ControlTreeView with SysTreeView32, unless I'm running x64 and it's a 32 bit application. After I tried running with #AutoIt3Wrapper_UseX64=n everything started working

If you need to though, you can check the Control Pattern Property: $UIA_SelectionItemIsSelectedPropertyId of the items in the TreeView

Local $bSelectionItemIsSelected
$oTreeItem.GetCurrentPropertyValue($UIA_SelectionItemIsSelectedPropertyId, $bSelectionItemIsSelected)
ConsoleWrite("Item is selected? = " & $bSelectionItemIsSelected & @CRLF)

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

  Reveal hidden contents
Posted

First I tried your suggestion with 32/36 bit application. Unfortunately with no success.

Your code pointed me in the right direction.

Local $pElement, $oElement, $sName, $bSelectionItemIsSelected, $bSelectionItemIsSelectedContainer
  For $i = 0 To $iElements - 1
    $oElementArray.GetElement( $i, $pElement )
    $oElement = ObjCreateInterface( $pElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
    $oElement.GetCurrentPropertyValue( $UIA_NamePropertyId, $sName )
    $oElement.GetCurrentPropertyValue($UIA_SelectionItemIsSelectedPropertyId, $bSelectionItemIsSelected)
    If $bSelectionItemIsSelected = True  Then
       ConsoleWrite($sName & @CRLF )
    EndIf
 Next

With this code I can get the text of the selected child item (P2C1). Additionally, is it possible to get the text of the not selected parent item (P2) ?

The structure of the treeview should be something like this:

P1
----> P1C1
----> P1C2
----> P1C3
P2
----> P2C1 (selected item)
P3

 

 

Posted

I think you must be doing something wrong if the native solution isn't working, but at least UI Automation works.

Anytime you ask "is it possible" in programming, the answer is nearly always yes. I found two simple-ish ways: AutomationElement.CachedParent and TreeWalker.GetParent. I'm not as well versed in UIAutomation as some, so I personally would use the TreeWalker as I've never cached elements. I'm pretty sure this would work, however.

A third option would be to search for the TreeViewItems by writing a property condition that isn't super specific and loop though all the elements using FindAll

Here some kinda pseudo code for that. I don't feel like writing it all, but it should give you a pretty good idea

; Get the tree view parent object, and search for all TreeViewItems
$oTreeView.FindAll 
; Convert the collection to an array
; ... See here: https://docs.microsoft.com/en-us/dotnet/api/system.windows.automation.automationelementcollection?view=netcore-3.1
; Loop through the elements
Local $i, $oParent
For $i=0 To Ubound($aTreeViewItems) - 1
    ; If this item has your item as a child (Use a function here)
    If IsParentOf($pCondition) Then ;...
        $oParent = $aTreeViewItems[$i]
    ; If this is the one you want
    ElseIf $aTreeViewItems[$i] ;...
        ; Save it
        $oSearchItem = $aTreeViewItems[$i]
        ; Stop looking
        ExitLoop
    EndIf
Next

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

  Reveal hidden contents
  • 2 weeks later...
Posted

Thanks for your effort.

But I solved it with another logical approach. I could catch the parent item with the keyword "name of parent [Target]", so it was easier than dick deeper in the microsoft docs and the UI Automation.

First I find the marked item and then I go backwards from this to catch the parent item.

Local $pElement, $oElement, $sName, $bSelectionItemIsSelected, $sLegacyIAccessibleName1, $sDigits, $result
  For $i = 0 To $iElements - 1
    $oElementArray.GetElement( $i, $pElement )
    $oElement = ObjCreateInterface( $pElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
    $oElement.GetCurrentPropertyValue( $UIA_NamePropertyId, $sName )
    $oElement.GetCurrentPropertyValue($UIA_SelectionItemIsSelectedPropertyId, $bSelectionItemIsSelected)
    If $bSelectionItemIsSelected = True  Then
       ExitLoop
    EndIf
 Next

For $in = $i To 1 Step -1
    $oElementArray.GetElement( $in, $pElement )
    $oElement = ObjCreateInterface( $pElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
    $oElement.GetCurrentPropertyValue( $UIA_NamePropertyId, $sName )
    $oElement.GetCurrentPropertyValue($UIA_SelectionItemIsSelectedPropertyId, $bSelectionItemIsSelected)
    If StringInStr($sName, "Target") <> 0  Then
        Local $pname = StringSplit ( $sName, " [")
        Exitloop
    EndIf
 Next

 

  Quote

I think you must be doing something wrong if the native solution isn't working

Expand  

I checked the program and it is 64bit file. Can we please investigate this together, so that I can doing it the next time right?

#AutoIt3Wrapper_UseX64=n
$hWnd = WinGetHandle("name of program")
$hTree = ControlGetHandle($hWnd, '', "[CLASS:SysTreeView32;INSTANCE:3]")

msgbox(0,"",ControlTreeView ( $hWnd, "", $hTree, "GetSelected" ))

$htree returns 0x0000000000000000 and ControlTreeView returns 0.

Posted

Aargh, I switched the workstation and ControlTreeView is working there flawlessly and give me the expected result.

First I thought it was the change of #AutoIt3Wrapper_UseX64 from n to y. I think AutoIt is set/installed there as 64bit version.

So, in the end you´re right with your guess.

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
  • Recently Browsing   0 members

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