Используя UI Automation, кнопка Winforms вызывает несколько раз
Я пытаюсь использовать MS UI Automation Framework в своем приложении для автоматического тестирования. Моя цель на данный момент - прослушивать события графического интерфейса и записывать их, как в примере, представленном (TestScriptGeneratorSample) в Windows SDK.
Просто используя это демонстрационное приложение, я могу запустить простое приложение Windows Forms с помощью одной кнопки и увидеть, что оно записывает события нажатия как "вызов" событий UIA. Однако для каждого нажатия кнопки демо-приложение записывает 4 события "вызова". Это почему? Я не вижу этой проблемы при использовании кнопки WPF.
Я думаю, что так как System.Windows.Forms.Button
Класс поддерживает MSAA вместо UIA, часть UIA, которая соединяет интерфейс MSAA, ведет себя неправильно или, по крайней мере, ведет себя так, как я не понимаю, и не могу найти никакой документации. Может быть, он сообщает о событии вызова мышью вниз, вверх, щелчком, а затем фактическим нажатием кнопки?
Может кто-нибудь объяснить это поведение и / или предоставить обходной путь, чтобы одно нажатие кнопки приводило к одному событию вызова?
Изменить: это под WinXP SP3. Я только что установил обновление Windows Automation API 3.0 и все еще вижу такое же поведение.
Редактировать 2: я нашел этот пример, где автор неосознанно упоминает это поведение как ошибку в элементе управления Win32, но не приводит никаких доказательств...
Вот мой пример приложения (форма с кнопкой на нем), а также прослушивание событий. Добавить ссылки на UIAutomationClient
а также UIAutomationTypes
, Нажмите на кнопку и увидите, что вызов происходит четыре раза вместо одного.
using System;
using System.Drawing;
using System.Windows.Automation;
using System.Windows.Forms;
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
private TextBox m_Output;
public Form1()
{
InitializeComponent();
// set up the GUI with a single button...
Button b = new Button {Location = new Point(5, 5), Name = "Test", Text = "Click Me"};
// ... and a textbox to write events to.
m_Output = new TextBox { Location = new Point(5, 30), Name = "Output", Multiline = true, Size = new Size(250, 200) };
this.Controls.Add(b);
this.Controls.Add(m_Output);
// get the button as an UIA element
AutomationElement button = AutomationElement.FromHandle(b.Handle);
// attach a handler to the button, listening for the Invoke event
Automation.AddAutomationEventHandler(
InvokePattern.InvokedEvent,
button,
TreeScope.Element,
OnInvoked);
}
// Handler for button invoke events
private void OnInvoked(object Sender, AutomationEventArgs E)
{
AppendText("Invoked: " + ((AutomationElement)Sender).Current.AutomationId);
}
// Just dumps text to the textbox
private void AppendText(string Text)
{
if (m_Output.InvokeRequired)
{
m_Output.BeginInvoke((Action<string>)AppendText, Text);
}
else
{
m_Output.AppendText(DateTime.Now.ToString("hh:mm:ss.fff") + ": " + Text + Environment.NewLine);
}
}
}
}
1 ответ
Для чего бы это ни стоило, я обошел его, отфильтровав несколько событий, которые выдают в одно. Во время тестирования я обнаружил следующее:
- Кнопки.NET (например, Winforms) генерируют следующие события по порядку при нажатии:
- Вызванный
- Вызванный
- Вызванный
- Собственность изменилась (
Name
имущество) - Вызванный
- Кнопки Win32 генерируют следующие события в некоторых сценариях (кнопки в
calc.exe
):- Собственность изменилась (
HasKeyboardFocus
имущество) - Вызванный
- Собственность изменилась (
- Кнопки Win32 генерируют следующие события в других сценариях ("Отмена" в диалоговом окне сохранения файла):
- Вызванный
- Собственность изменилась (
HasKeyboardFocus
имущество) - Вызванный
С использованием FrameworkId
собственность на AutomationElement
что связано с событием, я могу различить первую и вторую две ситуации (это "Winform"
для кнопок.NET и "Win32"
для кнопок Win32). Затем для двух сценариев Win32 я просто гарантирую, что получаю HasKeyboardFocus
событие изменения свойства перед записью вызванного события.
Я еще не видел, чтобы это не работало, так как я всегда HasKeyboardFocus
событие изменения свойства, даже если кнопка уже была в фокусе (т.е. я нажимаю ее дважды).
Я все еще хотел бы видеть больше понимания, если у кого-то есть некоторые...