获取使用Microsoft UI Automation的任何应用程序的TitleBar标题?

时间:2015-06-16 18:29:50

标签: c# .net vb.net ui-automation microsoft-ui-automation

C# VB.Net 中,如何使用 Microsoft UI Automation 检索包含文本的任何控件的文本?

我一直在研究MSDN文档,但我没有得到它。

Obtain Text Attributes Using UI Automation

然后,例如,使用下面的代码,我试图通过给出该窗口的hwnd来检索Window标题栏的文本,但我并不完全知道如何按照标题栏查找真正包含文本的子控件(标签?)。

Imports System.Windows.Automation
Imports System.Windows.Automation.Text

Dim hwnd As IntPtr = Process.GetProcessesByName("notepad").First.MainWindowHandle

Dim targetApp As AutomationElement = AutomationElement.FromHandle(hwnd)

' The control type we're looking for; in this case 'TitleBar' 
Dim cond1 As New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TitleBar)

Dim targetTextElement As AutomationElement =
    targetApp.FindFirst(TreeScope.Descendants, cond1)

Debug.WriteLine(targetTextElement Is Nothing)

在上面的示例中,我尝试使用标题栏,但我只想使用包含文本的任何其他控件...如标题栏。

PS:我知道P / Invoking GetWindowText API。

1 个答案:

答案 0 :(得分:3)

通常,使用UI自动化,您必须使用SDK工具分析目标应用程序(UISpy或Inspect - 确保它是Inspect 7.2.0.0,具有树视图的那个)。 所以这里例如,当我运行记事本时,我运行检查并看到:

enter image description here

我看到标题栏是主窗口的直接子项,所以我可以只查询窗口树直接子项,并使用TitleBar控件类型作为判别式,因为主窗口下面没有其他类型的子项。

这是一个示例控制台应用程序C#代码,演示如何获得“无标题 - 记事本”标题。请注意,TitleBar也支持Value模式,但我们不需要这里,因为标题栏的名称也是值。

class Program
{
    static void Main(string[] args)    
    {
        // start our own notepad from scratch
        Process process = Process.Start("notepad.exe");
        // wait for main window to appear
        while(process.MainWindowHandle == IntPtr.Zero)
        {
            Thread.Sleep(100);
            process.Refresh();
        }
        var window = AutomationElement.FromHandle(process.MainWindowHandle);
        Console.WriteLine("window: " + window.Current.Name);

        // note: carefully choose the tree scope for perf reasons
        // try to avoid SubTree although it seems easier...
        var titleBar = window.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TitleBar));
        Console.WriteLine("titleBar: " + titleBar.Current.Name);
    }
}