Search code examples
vb.netwindow-handles

Assign window to object via its handle


Just looking for a pointer as I'm struggling to find material online...

Is there a library or reference I can use in VB.NET to assign an arbitrary open window to an object via its handle, such that I can then view the elements & attributes associated with that window? I can identify the handle via Process.MainWindowHandle (i.e. System.Diagnostics.Process.GetProcesses) but how can I then use that handle to "hook" onto the window as an object?

(FYI The window is independent of my application, it's not a form or anything like that - it's just an open window)

All the material I find online is telling me how to get the handle but that's not the issue; I have the handle but I don't know how to use it to "hook" onto the window programmatically?

Would appreciate any pointers anyone could provide!

Thanks

Al


Solution

  • Here is the solution I arrived at, which is working exactly as intended. Cannot claim credit for it as @Jimi gave me all the necessary pointers for me to arrive at this. However, the snippet may be helpful for others trying to navigate UI Automation for the first time, like I was.

    Private Sub StartListening()
        Try
            Dim eventHandler As AutomationEventHandler = AddressOf OnWindowOpenOrClose
            Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Subtree, eventHandler)
    
        Catch ex As Exception
    
        End Try
    End Sub
    
    Private Sub StopListening()
        Try
            Automation.RemoveAllEventHandlers()
    
        Catch ex As Exception
    
        End Try
    End Sub
    
    Private Sub OnWindowOpenOrClose(ByVal src As Object, ByVal e As AutomationEventArgs)
    
        Dim sourceElement As AutomationElement
        Dim okButton As AutomationElement
        Dim okButtonCondition As Condition
        Dim okButtonInvokePattern As InvokePattern
    
        Try
            sourceElement = DirectCast(src, AutomationElement)
            If sourceElement IsNot Nothing Then
                If sourceElement.Current.ControlType.Equals(ControlType.Window) AndAlso sourceElement.Current.ClassName = "NUIDialog" AndAlso sourceElement.Current.Name = "<Insert Dialog Name Here As Necessary>" Then
                    If e.EventId Is WindowPattern.WindowOpenedEvent Then
                        okButtonCondition = New AndCondition(New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button),
                                                                New PropertyCondition(AutomationElement.NameProperty, "OK"))
                        okButton = sourceElement.FindFirst(TreeScope.Subtree, okButtonCondition)
                        If okButton IsNot Nothing Then
                            okButtonInvokePattern = DirectCast(okButton.GetCurrentPattern(InvokePattern.Pattern), InvokePattern)
                            okButtonInvokePattern.Invoke()
                        End If
                        Return
                    End If
                End If
            End If
    
        Catch
            Return
        End Try
    
    End Sub