IsKeyboardFocusable在Inspect Object中为true,但在我的应用程序中始终为false

我正在学习UI自动化,我发现我的“Inspect Object”克隆显示IsKeyboardFocusable始终为false,即使它是真的,所有其他信息都是相同的(如图所示)。 有没有人知道为什么我在检索值时看到此属性为false?

在此处输入图像描述

Inspect Object应用程序中,最新版本的Windows Automation COM API(3.0)用于显示所有这些属性。 但默认的.NET UIAutomation实现不是基于Windows Automation 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 Automation API 3.0 COM接口,提高可靠性和性能,同时仍然使用与之前相同的System.Windows.Automation类。 UI自动化的版本。 此实现作为CodePlex上的项目提供: UI Automation COM-to-.NET Adapter

因此,今天尝试了这种替代实现,并且通过这种替代实现,IsKeyboardFocusable属性返回与Inspect Objects工具相同的结果! 此外,现在可以使用Inspect Objects显示的一些扩展属性(例如LegacyIAccessible成员)。

IsKeyboardFocusable的内部实现使用GetCurrentPropertyValue(属性:AutomationElement.IsKeyboardFocusableProperty,ignoreDefaultValue:false)函数。 在它失败的情况下,它只返回false(在你的情况下它失败)。 因此,我建议您使用GetCurrentPropertyValue(属性: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为真的情况,例如Skype应用程序的菜单栏。