我正在学习 UI 自动化,我发现我的“检查对象”克隆显示它IsKeyboardFocusable
总是错误的,即使它是真的,所有其他信息都是相同的(从图像中可以看到)。有谁知道为什么我在检索值时将此属性视为错误?
3 回答
在Inspect Object
应用程序中,最新版本的 Windows 自动化 COM API (3.0) 用于显示所有这些属性。但默认的 .NET UIAutomation 实现不是基于 Windows 自动化 API 3.0 COM 接口(它基于此 COM API 的先前版本)。因此,某些属性无法正常运行。例如,对于 Skype 的联系人列表,该AutomationElement.IsKeyboardFocusableProperty
属性表示根本不支持获取此属性的值。您可以使用以下代码片段进行检查:
object isKeyboardFocusable = listItem.GetCurrentPropertyValue(AutomationElement.IsKeyboardFocusableProperty, true);
if(isKeyboardFocusable == AutomationElement.NotSupported) {
// we will always goes here
}
现在,我不知道如何使用当前的 .Net UIAutomation 实现来避免这种行为。
好消息是 .NET 中有替代的 UI 自动化实现,可以使用新的 Windows 自动化 API 3.0 COM 接口,提高了可靠性和性能,同时仍然使用与之前相同的 System.Windows.Automation 类UI 自动化的版本。此实现可作为 CodePlex 上的一个项目获得:UI 自动化 COM-to-.NET 适配器
所以,今天尝试了这个替代实现,并且通过这个替代实现,IsKeyboardFocusable 属性返回与工具相同的结果Inspect Objects
!此外,现在可以使用Inspect Objects
显示的一些扩展属性(例如 LegacyIAccessible 成员)。
IsKeyboardFocusable 的内部实现使用 GetCurrentPropertyValue(property: AutomationElement.IsKeyboardFocusableProperty, ignoreDefaultValue: false) 函数。在它失败的情况下,它只是返回 false (在你的情况下它失败了)。因此,我建议您使用 GetCurrentPropertyValue(property: AutomationElement.IsKeyboardFocusableProperty, ignoreDefaultValue: true) 而不是 IsKeyboardFocusable,这样您就会知道它是否失败。
使用 winapi 可以得到与 Inspect 完全相同的结果。Olecc.dll 给你IAccessible接口(这个接口有更详细的描述)。该接口的一个实例可以有子实例,其中一部分可以是可聚焦的,而一部分则不是。如果从 HWnd 创建 IAccessible,则无法确定整个控件是否可聚焦。可以肯定的是,您应该从屏幕点创建 IAccessible - 它为您提供了该点下的 IAccessible(您可以在屏幕截图上看到,Inspect 使用屏幕上的点 - “如何找到 - 鼠标移动(1120、470)” )。此外,如果您在 Inspect 中从 UIAutomation 模式切换到 MSAA,您可以看到 IAccessible 的外观。
但是,如果可能的话,最好使用UIAutomation 的替代实现。它返回正确的 IsKeyboardFocusable 值(与标准 UIAutomation 实现不同)。我自己没有测试过这个库(我只测试了 IsKeyboardFocusable),但它似乎工作正常,并且它具有与标准实现相同的类型和接口。在 IAccessible 的情况下,您应该从一个点创建 AutomationElement,而不是从 HWnd。
关于您的问题-我还不知道,为什么标准 UIAutomation 在某些情况下无法正确返回 AutomationElement.IsKeyboardFocusableProperty。我想,这可能是一个错误。
您是否尝试过这个 UI 自动化间谍工具:https ://ddeltasolutions.000webhostapp.com/ ?我发现 IsKeyboardFocusableProperty 为 true 的情况,例如 Skype 应用程序的菜单栏。