Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
Ask Question
In my pywinauto script (based on win32 backend), I can retrieve pretty easily the TreeViewWrapper element by looking for the class type and eventually looking at the items text, but some information that I need is only available in the Description field of this element.
I was not able to find a way to retrieve this information.
I tried in UIA mode as well:
But in this case, it does not even appear in the information.
So I tried using the TreeItemWrapper element with the UIA backend in pywinauto, but I could not find the appropriate description not even in the UIAElementInfo. Although something looked pretty similar in the following line:
impl = uia_defs.get_elem_interface(elem, "LegacyIAccessible").
When I call the legacy_properties
of the uia_controls.TreeItemWrapper
, I get:
{'ChildId': 0,
'DefaultAction': '',
'Description': '',
'Help': '',
'KeyboardShortcut': '',
'Name': 'Execute multiple tasks(MultiTask_ImportSysD)',
'Role': 36,
'State': 3145730,
'Value': ''}
And in there, the Description is empty.
–
–
–
–
–
–
Finally, I could not find this possibility through the pywinauto exposed API.
Although pywniauto does expose the Description property through the legacy_properties
of the uia_controls.TreeItemWrapper
instance, but it returns an empty string. This correlates with the note in teh Windows SDK documentation that states:
Note The Description property is often used incorrectly and is not supported by Microsoft UI Automation. Microsoft Active Accessibility server developers should not use this property. If more information is needed for accessibility and automation scenarios, use the properties supported by UI Automation elements and control patterns.
In the end, I finally developed a small piece of code to search for the element that I need the description of and I could retrieve the Description from there. Here is the code:
# for OleAcc access
import ctypes
import comtypes, comtypes.automation, comtypes.client
comtypes.client.GetModule('oleacc.dll')
def accDescription(iaccessible, cid):
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objDescription = comtypes.automation.BSTR()
iaccessible._IAccessible__com__get_accDescription(objChildId, ctypes.byref(objDescription))
return objDescription.value
def accRole(iaccessible, cid):
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objRole = comtypes.automation.VARIANT()
objRole.vt = comtypes.automation.VT_BSTR
iaccessible._IAccessible__com__get_accRole(objChildId, objRole)
return AccRoleNameMap[objRole.value]
def accState(iaccessible, cid):
'''Get Element State'''
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objState = comtypes.automation.VARIANT()
iaccessible._IAccessible__com__get_accState(objChildId, ctypes.byref(objState))
return objState.value
def accName(iaccessible, cid):
'''Get Element Name'''
objChildId = comtypes.automation.VARIANT()
objChildId.vt = comtypes.automation.VT_I4
objChildId.value = cid
objName = comtypes.automation.BSTR()
iaccessible._IAccessible__com__get_accName(objChildId, ctypes.byref(objName))
return objName.value
def accDescendants(iaccessible):
"""Iterate all desencendants of an object iaccessible, including the current one.
Arguments:
iaccessible -- the IAccessible element to start from
Yields:
(IAcessible instance, Child id)
yield (iaccessible, 0)
objAccChildArray = (comtypes.automation.VARIANT * iaccessible.accChildCount)()
objAccChildCount = ctypes.c_long()
ctypes.oledll.oleacc.AccessibleChildren(iaccessible, 0, iaccessible.accChildCount, objAccChildArray, ctypes.byref(objAccChildCount))
for i in range(objAccChildCount.value):
objAccChild = objAccChildArray[i]
if objAccChild.vt == comtypes.automation.VT_DISPATCH:
# query the sub element accessible interface
newiaccessible = objAccChild.value.QueryInterface(comtypes.gen.Accessibility.IAccessible)
# then loop over its descendants
for (__i, __c) in accDescendants(newiaccessible):
yield (__i, __c)
else: #if objAccChild.vt == comtypes.automation.VT_I4:
yield (iaccessible, objAccChild.value)
def findObjIAccessible(handle, text):
"""Find the IAccessible based on the name, starting from a specific window handle
Arguments:
handle -- the window handle from which to search for the element
text -- text that should be contained in the name of the IAccessible instance
Return:
(None, 0) if not found
(IAccessible instance, child id) of the first element whose name contains the text
iacc = ctypes.POINTER(comtypes.gen.Accessibility.IAccessible)()
ctypes.oledll.oleacc.AccessibleObjectFromWindow(handle, 0, ctypes.byref(comtypes.gen.Accessibility.IAccessible._iid_), ctypes.byref(iacc))
for (ia, ch) in accDescendants(iacc):
n = accName(ia, ch)
if n != None and text in n:
return (ia, ch)
else:
return (None, 0)
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.