0

I am able to get top active window (title) in my code but I wanted to know how to get all the children(content and controls or elements -image, link, button etc) inside the active top window in my code. I searched many links such as - Retrieve all the controls of any window with their types and value which suggests- To enumerate top level windows use EnumWindows(), to get their child windows use EnumChildWindows(). But I am not able to understand how to implement it in my code and get the children of top active windows which is focused.

It would be great if someone helped me around with some sample code. Stuck from long time exploring and checking different links.

Below is the code which gives me top active window title and displaying in the grid.

xaml code -

 <Grid x:Name="grid">
</Grid>

.cs Class code -

 public partial class MainWindow : Window
    {

     [DllImport("user32.dll")]
            static extern IntPtr GetForegroundWindow();
            private static IntPtr GetActiveWindow()
            {
                IntPtr handle = IntPtr.Zero;
                return GetForegroundWindow();
            }
            [DllImport("user32.dll", EntryPoint = "GetWindowTextW", CharSet = CharSet.Unicode)]
            private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxLength);
            ListBox lst = new ListBox();
            public MainWindow()
            {
                InitializeComponent();
    
                DispatcherTimer dispatcherTimer = new DispatcherTimer();
                dispatcherTimer.Tick += new EventHandler(DispatcherTimer_Tick);
                dispatcherTimer.Interval = new TimeSpan(0, 0, 5);
                dispatcherTimer.Start();
                var d = ActiveWindowTitle();
                var t = GetForegroundWindow();
                grid.Children.Add(lst);
            }
            public static IntPtr GetTopWindow(string wClass, string wCaption)
            {
                if (string.IsNullOrEmpty(string.Concat(wClass, wCaption)))
                {
                    return (IntPtr)0;
                }
                return (IntPtr)0;
            }
            private void DispatcherTimer_Tick(object sender, EventArgs e)
            {
                string title = ActiveWindowTitle();
                var current = this.Title;
                if (!current.Equals(title) && !String.IsNullOrEmpty(title))
                    lst.Items.Add("Title: " + title );
            }
    
            private string ActiveWindowTitle()
            {
                const int nChar = 256;
                StringBuilder ss = new StringBuilder(nChar);
                IntPtr handle = IntPtr.Zero;
                handle = GetForegroundWindow();
    
                if (GetWindowText(handle, ss, nChar) > 0)
                    return ss.ToString();
                else return "";
    
            }
}
  • You want to use UI Automation instead of playing with hwnd: https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-overview this is the official accessibility framework for Microsoft Windows – Simon Mourier Jun 24 '22 at 05:58
  • Hi @SimonMourier, Thanks for reply.. I saw this post but not sure how to use it. Is there any link or source which demonstrates samples so I can try and and experiment on? – RisingDeveloper Jun 24 '22 at 06:04
  • You can search the web of look here https://stackoverflow.com/questions/tagged/microsoft-ui-automation – Simon Mourier Jun 24 '22 at 07:50
  • The .NET documentation links to the [native documentation](https://learn.microsoft.com/en-us/windows/win32/winauto/entry-uiauto-win32) that contains numerous [samples](https://learn.microsoft.com/en-us/windows/win32/winauto/samples-entry). This assumes familiarity with COM. – IInspectable Jun 24 '22 at 12:23
  • I searched for UI automation, My main goal is to read controls or elements from active top windows (Like narrator does) not write but I am finding difficult to get the output with available information. How do I proceed or learn about ?? any help would be appreciated – RisingDeveloper Jun 27 '22 at 05:41
  • You should find all you need here: https://stackoverflow.com/questions/874380/wpf-how-do-i-loop-through-the-all-controls-in-a-window – Jeronymite Jul 14 '22 at 05:06

1 Answers1

0

After log research I am able to achieve it but still facing problems while drawing overlay window.

I am able get handle of top active window and I am also able to draw an overlay window on top of each control .

Below is my code I used to create an overlay window on active window children. I am using FlaUI automation for getting all Children of active top window. To get all children of active window I am attaching processId of active window to get children and storing all Hyperlink children in a list and passing same list to show overlay bubble window.

Code -

 var processId = GetFileNameFormHandle();
                GetAllChildrenOfTopWindow(processId);
    [DllImport("user32.dll")]
            static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    
            public UInt32 GetFileNameFormHandle()
            {
                var handle = GetForegroundWindow();
                uint pid = 0;
                GetWindowThreadProcessId(handle, out pid);
                string wmiQuery = string.Format("SELECT ProcessId, ExecutablePath FROM Win32_Process WHERE ProcessId LIKE '{0}'", pid.ToString());
                var pro = new ManagementObjectSearcher(wmiQuery).Get().Cast<ManagementObject>().FirstOrDefault();
                UInt32 processid = (UInt32)pro["ProcessId"];
                return processid;
            }
     

  

      public static List<FlaUI.Core.AutomationElements.AutomationElement> ChildLinksList = new List<FlaUI.Core.AutomationElements.AutomationElement>();
         public void GetAllChildrenOfTopWindow(UInt32 topActiveWindowName)
                {
                    var app = FlaUI.Core.Application.Attach((int)topActiveWindowName);
                    var automation = new UIA3Automation();
                    var mainwindow = app.GetMainWindow(automation,TimeSpan.MinValue);
             

       ConditionFactory cf = new ConditionFactory(new UIA3PropertyLibrary());
                var Elements = mainwindow.FindAllDescendants();
     foreach (var child in Elements)
                    {
                        if (child.ControlType == FlaUI.Core.Definitions.ControlType.Hyperlink)
                            ChildLinksList.Add(child);
    }
     childBubbleWindow(ChildLinksList);
}

To show Bubble/OverlayWindow -

 public static void childBubbleWindow(List<FlaUI.Core.AutomationElements.AutomationElement> childrenList)
        {
            int i = 0;

            foreach (var links in childrenList)
            {
                if (links.IsAvailable == true && links.IsOffscreen != true)
                {
                    var linkbounding = links.Properties.BoundingRectangle.Value;
                    var handle = GetForegroundWindow();
var hwndSource = new HwndSource(new HwndSourceParameters("OverlayWindow")
                    {
                        ParentWindow = handle,
                        UsesPerPixelTransparency = true,
                        PositionX = linkbounding.X,
                        PositionY = linkbounding.Y,

                    })
                    {
                        RootVisual = new System.Windows.Controls.TextBox()
                        {
                            Width = 30,
                            Height = 30,
                            BorderThickness = new Thickness(3),
                            BorderBrush = new SolidColorBrush(Colors.Red),
                            TextAlignment = TextAlignment.Right,
                            FontWeight = FontWeights.Bold, 
                            Background = new SolidColorBrush(Colors.DodgerBlue),
                            Text = i.ToString(),
                            IsHitTestVisible = true,
                        }
                    };
                    i++;
                }
            }  
        }