IsKeyboardFocusable истинно в объекте Inspect, но всегда ложно в моем приложении

Я изучаю автоматизацию пользовательского интерфейса, и я обнаружил, что мой клон "Inspect Object" показывает, что IsKeyboardFocusable всегда ложно, даже если это правда, вся остальная информация идентична (как вы можете видеть из изображения). Кто-нибудь знает, почему я вижу это свойство как false при получении значения?

enter image description here

3 ответов


внутри Inspect Object application последняя версия 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 существует альтернативная реализация автоматизации пользовательского интерфейса, которая позволяет использовать новые интерфейсы Windows Automation API 3.0 COM с улучшенной надежностью и производительностью, при этом используя ту же систему.Окна.Классы автоматизации, как и в более ранних версиях UI Automation. Этот реализации проекта на CodePlex: автоматизация пользовательского интерфейса COM-to-.NET адаптер

Итак, попробовал эту альтернативную реализацию сегодня, и с этой альтернативной реализацией свойство IsKeyboardFocusable возвращает тот же результат, что и ! Более того, теперь можно использовать некоторые расширенные свойства, которые Inspect Objects отображает (например, LegacyIAccessible членов).


внутренняя реализация IsKeyboardFocusable использует GetCurrentPropertyValue (свойство: AutomationElement.IsKeyboardFocusableProperty, ignoreDefaultValue: false) функция. В случаях, когда он терпит неудачу, он просто возвращает false (и в вашем случае он терпит неудачу). Поэтому я рекомендую вам использовать GetCurrentPropertyValue (свойство: AutomationElement.IsKeyboardFocusableProperty, ignoreDefaultValue: true) вместо IsKeyboardFocusable, поэтому вы будете знать, если это не удастся.

вы можете получить точно такой же результат, как Inspect с помощью winapi. Olecc.dll дает вам IAccessible интерфейс (более подробно описание этого интерфейса). Экземпляр этого интерфейса может иметь дочерние экземпляры, часть из них может быть фокусируемой, а часть - нет. Если вы создаете IAccessible из HWnd, вы не можете быть уверены, что весь элемент управления является фокусируемым или не фокусируемым. Чтобы быть уверенным, вы должны создать IAccessible с точки экрана - это дает вам точно IAccessible что под этой точкой (вы можете видеть на своем скриншоте, что Inspect использует точку на экране - "как найдено - перемещение мыши (1120, 470)"). Также, если вы переключитесь с режима UIAutomation на MSAA в Inspect, вы увидите, как выглядит IAccessible.

но, если это возможно в вашем случае, лучше использовать альтернативные реализации UIAutomation. Он возвращает правильное значение IsKeyboardFocusable (в отличие от стандартной реализации UIAutomation). Я не проверял это сама библиотека (я тестировал только IsKeyboardFocusable), но, похоже, работает нормально, и имеет те же типы и интерфейсы, что и стандартная реализация. Как и в случае IAccessible, вы должны создать AutomationElement из точки, а не из HWnd.

о вашем вопросе-я еще не знаю, почему стандартная UIAutomation не может вернуть AutomationElement.IsKeyboardFocusableProperty corretly в некоторых случаях. Я думаю, это может быть ошибка.


вы пробовали этот инструмент UI Automation spy:https://ddeltasolutions.000webhostapp.com/ ? Я нашел случаи, когда IsKeyboardFocusableProperty истинно, например, в строке меню приложения Skype.