Получить заголовок заголовка любого приложения с помощью Microsoft UI Automation?

В C# или VB.Net, как я могу использовать Microsoft UI Automation для извлечения текста любого элемента управления, содержащего текст?

Я изучал документы MSDN, но не понял.

Получение текстовых атрибутов с помощью автоматизации пользовательского интерфейса

Затем, например, с помощью приведенного ниже кода я пытаюсь получить текст строки заголовка окна, указав hwnd этого окна, но я точно не знаю, как следовать строке заголовка, чтобы найти дочерний элемент управления (метка?) который действительно содержит текст.

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.


person ElektroStudios    schedule 16.06.2015    source источник
comment
Вы знаете, что это вещь WPF, верно?   -  person Ňɏssa Pøngjǣrdenlarp    schedule 16.06.2015
comment
Он также работает для WinForms и любой корзины C / C ++, с автоматизацией пользовательского интерфейса вы можете отслеживать / проверять все виды исполняемых файлов, а не только WPF, но я знаю, что информация MSDN очень сбивает с толку.   -  person ElektroStudios    schedule 16.06.2015
comment
Я просто хотел убедиться, что ты знаешь, что это такое.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 16.06.2015


Ответы (1)


С UI Automation, как правило, вы должны анализировать целевое приложение с помощью инструментов SDK (UISpy или Inspect — убедитесь, что это Inspect 7.2.0.0, тот, что с древовидным представлением). Так вот, например, когда я запускаю блокнот, я запускаю проверку и вижу это:

введите здесь описание изображения

Я вижу, что строка заголовка является прямым дочерним элементом главного окна, поэтому я могу просто запросить дерево окон для прямых дочерних элементов и использовать тип элемента управления TitleBar в качестве дискриминанта, поскольку под основным окном нет другого дочернего элемента этого типа.

Вот пример кода C# консольного приложения, который демонстрирует, как получить заголовок «Без названия — Блокнот». Обратите внимание, что заголовок также поддерживает шаблон 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);
    }
}
person Simon Mourier    schedule 16.06.2015
comment
Что делать, если вы хотите получить все заголовки окон? Например: заголовки окон Notepad++...? - person zaggler; 17.06.2015
comment
Это другой вопрос. Каждое приложение отличается автоматизацией пользовательского интерфейса. Случайно ответ также доступен от того же парня здесь: using-an-intptr" title="можно ли активировать вкладку в другой программе с помощью intptr">stackoverflow.com/questions/29951432/ - person Simon Mourier; 17.06.2015
comment
@Simon Mourier, спасибо за ваш ответ, я проверю его позже. This is another question. Every application is different with regards to UI automation но, например, функция GetwindowText может получить любой текст заголовка, независимо от того, какое это приложение, ей просто нужен hwnd окна и делает магию, тогда я предположил, что с помощью механизма автоматизации пользовательского интерфейса я должен получить такие же или лучшие результаты, чем используя эту функцию WinAPI. в любом случае я прочитаю связанный ответ позже. - person ElektroStudios; 17.06.2015
comment
Ну предложение это просто нужно окно hwnd это та же проблема в МАУ. Вам просто нужно определить, какова иерархия окон, какой бы ни была технология. Просто с МАУ ИМХО проще, плюс это официальный способ. - person Simon Mourier; 17.06.2015
comment
@SimonMourier, сэр, я искал это для своей цели, и для моей цели мне также нужно установить/изменить значение строки заголовка ... поскольку я не очень хорошо разбираюсь в UIAutomation, я не могу найти способ сделать Это? не могли бы вы помочь? - person Zakir_SZH; 16.03.2019
comment
@Zakir_SZH - Я не думаю, что вы можете сделать это с МАУ. вы должны задать другой вопрос. - person Simon Mourier; 16.03.2019
comment
@SimonMourier, оппс! тогда мне не повезло? поскольку SetWindowText не работает во всех/большинстве случаев :( - person Zakir_SZH; 16.03.2019
comment
@Zakir_SZH - это вообще вопрос безопасности. Кусок кода может изменять только те окна, для которых у него достаточно учетных данных (UAC и т. д.). - person Simon Mourier; 16.03.2019