我具有以下SysTreeView32元素,我希望从该元素中检索“描述”字段:
在我的pywinauto脚本(基于win32后端)中,我可以通过查找类类型并最终查看项目文本来轻松检索TreeViewWrapper元素,但是我需要的一些信息仅在这个元素。
我找不到一种方法来检索此信息。
我也在UIA模式下尝试过
但是在这种情况下,它甚至没有出现在信息中。
因此,我尝试在pywinauto中将TreeItemWrapper元素与UIA后端一起使用,但是即使在UIAElementInfo中也找不到合适的描述。尽管在下面的行中看起来很相似:
impl = uia_defs.get_elem_interface(elem, "LegacyIAccessible").
当我呼叫legacy_properties
中的uia_controls.TreeItemWrapper
时,我得到:
{'ChildId': 0,
'DefaultAction': '',
'Description': '',
'Help': '',
'KeyboardShortcut': '',
'Name': 'Execute multiple tasks(MultiTask_ImportSysD)',
'Role': 36,
'State': 3145730,
'Value': ''}
其中的描述为空。
答案 0 :(得分:1)
我猜该属性来自IAccessible::get_accDescription
。
MSDN说该属性已被弃用,但是如果您仍然想使用它,请调用AccessibleObjectFromWindow
以获取窗口的IAccessible
。
答案 1 :(得分:0)
最后,我无法通过pywinauto公开的API找到这种可能性。
尽管pywniauto确实通过legacy_properties
实例的uia_controls.TreeItemWrapper
公开了Description属性,但是它返回了一个空字符串。这与Windows SDK文档中的注释相关,该注释指出:
注意Description属性经常被错误地使用,并且Microsoft UI Automation不支持。 Microsoft Active Accessibility服务器开发人员不应使用此属性。如果可访问性和自动化方案需要更多信息,请使用UI自动化元素和控件模式支持的属性。
最后,我最终开发了一小段代码来搜索需要描述的元素,然后可以从中检索描述。这是代码:
# 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)