5

In C# or else VB.Net, how I could use Microsoft UI Automation to retrieve the text of any control that contains text?.

I've been researching in the MSDN Docs, but I don't get it.

Obtain Text Attributes Using UI Automation

Then, for example, with the code below I'm trying to retrieve the text of the Window titlebar by giving the hwnd of that window, but I don't know exactlly how to follow the titlebar to find the child control (label?) that really contains the text.

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)

In the example above I'm trying with the titlebar, but just I would like to do it with any other control that contains text ...like a titlebar.

PS: I'm aware of P/Invoking GetWindowText API.

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
ElektroStudios
  • 19,105
  • 33
  • 200
  • 417

1 Answers1

6

With UI Automation, in general, you have to analyze the target application using the SDK tools (UISpy or Inspect - make sure it's Inspect 7.2.0.0, the one with a tree view). So here for example, when I run notepad, I run inspect and see this:

enter image description here

I see the titlebar is a direct child of the main window, so I can just query the window tree for direct children and use the TitleBar control type as a discriminant because there's no other child of that type beneath the main window.

Here is a sample console app C# code that demonstrate how to get that 'Untitled - Notepad' title. Note the TitleBar also supports the Value pattern but we don't need here because the titlebar's name is also the 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);
    }
}
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • What if you want to get all window titles? For example: Notepad++ window titles...? – Trevor Jun 16 '15 at 21:11
  • This is another question. Every application is different with regards to UI automation. By chance the answer is also available from the same guy here: http://stackoverflow.com/questions/29951432/is-it-possible-to-activate-a-tab-in-another-program-using-an-intptr – Simon Mourier Jun 16 '15 at 21:15
  • @Simon Mourier thanks for your answer, I will test it later. `This is another question. Every application is different with regards to UI automation` but, for example the `GetwindowText` function can get any titlebar's text regardless of what kind of application is it, it just need the window hwnd and does the magic, then I supposed that using the UI automation "engine" I should get same or better results than using that WinAPI function. anyways I will read the linked answer later too. – ElektroStudios Jun 17 '15 at 00:35
  • 1
    Well the sentence "it just need the window hwnd" is the same problem in UIA. You just need to determine what's the window hierarchy whatever the technology is. It's just simpler with UIA IMHO, plus it's the official way. – Simon Mourier Jun 17 '15 at 05:05
  • @SimonMourier, sir, i was looking for it for my purpose, and in my purpose i also need to set/change the value of title bar.. as i am not very good with UIAutomation, i can't find the way to do it? can you please help? – Zakir_SZH Mar 16 '19 at 05:53
  • @Zakir_SZH - I don't think you can do that with UIA. you should ask another question. – Simon Mourier Mar 16 '19 at 07:51
  • @SimonMourier, opps! then i am out of luck? as "SetWindowText" does not work on all/most cases :( – Zakir_SZH Mar 16 '19 at 08:43
  • @Zakir_SZH - this is in general a security issue. A piece of code is allowed to change only windows for which it has enough credentials (UAC, etc.). – Simon Mourier Mar 16 '19 at 08:47