2012-09-25 74 views
4

我試圖在我的應用程序中使用MS UI Automation Framework進行一些自動化測試。我現在的目標是聽GUI事件並記錄它們,類似於Windows SDK中提供的示例(TestScriptGeneratorSample)。使用UI自動化,Winforms按鈕多次調用

只需使用該演示應用程序,我就可以通過一個按鈕啓動一個簡單的Windows窗體應用程序,並將它記錄爲「調用」UIA事件。但是,對於每次點擊該按鈕,演示應用程序都會記錄「調用」事件。這是爲什麼?我在使用WPF按鈕時看不到此問題。

我的猜測是,由於System.Windows.Forms.Button類支持MSAA而不是UIA,橋接MSAA接口的UIA部分行爲異常,或者至少表現爲我不明白和無法找到的方式任何有關文件。 也許它報告了鼠標向下,向上,點擊的調用事件,然後按下實際的按鈕?

任何人都可以解釋此行爲,和/或提供一種解決方法,以便一個按鈕按結果在一個調用事件?

編輯:這是在WinXP SP3下。我剛安裝了Windows Automation API 3.0update,仍然看到相同的行爲。

編輯2:我發現this example在這裏筆者斷一手提到這種行爲,因爲在Win32控件中的錯誤,但引用任何證據......

這裏是我的示例應用程序(表格上的按鈕它),隨着事件傾聽它。添加對UIAutomationClientUIAutomationTypes的引用。點擊按鈕,看到調用發生四次而不是一次。

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); 
      } 
     } 
    } 
} 
+0

+1自動化框架是一個有趣的。 –

+0

我看了你的代碼,這可能與你如何實現AppendText有關。嘗試使用'Invoke'而不是'BeginInvoke',看看它是否有任何區別。另外,你使用的是哪個版本的.NET? – DoronG

回答

0

對於什麼是值得的,我已經通過篩選多個事件發佈到一個來解決它。在測試過程中,我發現以下內容:

  • .NET按鈕(即,的WinForms)點擊時產生下述順序的事件:
    1. 調用
    2. 調用
    3. 調用
    4. 屬性更改(在Name屬性)
    5. 調用
  • Win32的按鈕生成以下事件在某些情況下(按鈕calc.exe):
    1. 屬性更改(在HasKeyboardFocus屬性)
    2. 調用
  • Win32的按鈕產生其他場景以下事件(在保存文件對話框中的 「取消」):
    1. 調用
    2. 屬性更改(在HasKeyboardFocus屬性)
    3. 調用

使用與事件關聯的AutomationElement上的FrameworkId屬性,我可以區分第一種和第二種情況(對於.NET按鈕,其值爲"Winform",對於Win32按鈕值爲"Win32")。然後,對於這兩個Win32場景,我只是確保在記錄調用的事件之前獲得HasKeyboardFocus屬性更改事件。

我還沒有看到這不工作,因爲我似乎總是得到HasKeyboardFocus屬性更改事件,即使按鈕已經集中(即我按兩次)。

我還是希望看到更多的見解,如果有人有一些...