sming Posted April 27, 2020 Posted April 27, 2020 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.
seadoggie01 Posted April 27, 2020 Posted April 27, 2020 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 My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types
sming Posted April 28, 2020 Author Posted April 28, 2020 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
seadoggie01 Posted April 29, 2020 Posted April 29, 2020 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 My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types
sming Posted May 8, 2020 Author Posted May 8, 2020 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.
sming Posted May 8, 2020 Author Posted May 8, 2020 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.
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