Jun 22, 2016 03:41 AM
(This post was last modified: Jun 22, 2016 09:59 AM by Josh.)
So I have the following code to get all firefox tabs, but it's fairly slow:
After some research, I found that FindAll is meant to be quicker, so I replaced it with this:
However the children array count returns 0, so I tried this:
And got 29 children, but all of them threw an invalid patter error.
Am I missing something, or is there another faster alternative to the TreeWalker?
Thanks in advance, Josh
So after hours of fucking about, I got this and it's much quicker (the aim of the program is to get youtube tabs):
After some more messing about, here's I think the final edit to get all windows:
Code
Dim con As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)
Dim tw As New TreeWalker(con)
Dim child As AutomationElement = tw.GetFirstChild(element)
While Not IsNothing(child)
Try
Dim url As String = DirectCast(child.GetCurrentPattern(ValuePattern.Pattern), ValuePattern).Current.Value.ToString
child = tw.GetNextSibling(child)
MsgBox(url)
Catch ex As Exception
MsgBox(ex.ToString)
Exit While
End Try
End WhileAfter some research, I found that FindAll is meant to be quicker, so I replaced it with this:
Code
Dim con As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)
Dim children As AutomationElementCollection = element.FindAll(TreeScope.Children, con)
For Each child As AutomationElement In children
Try
Dim url As String = DirectCast(child.GetCurrentPattern(ValuePattern.Pattern), ValuePattern).Current.Value.ToString
MsgBox(url)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
NextCode
Dim children As AutomationElementCollection = element.FindAll(TreeScope.Children, Condition.TrueCondition)
For Each child As AutomationElement In children
Try
Dim url As String = DirectCast(child.GetCurrentPattern(ValuePattern.Pattern), ValuePattern).Current.Value.ToString
MsgBox(url)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
NextAm I missing something, or is there another faster alternative to the TreeWalker?
Thanks in advance, Josh
So after hours of fucking about, I got this and it's much quicker (the aim of the program is to get youtube tabs):
Code
Private Function GetFirefoxTabs(process As Process) As List(Of String)
If process Is Nothing Then
Throw New ArgumentNullException("process")
ElseIf process.MainWindowHandle = IntPtr.Zero Then
Throw New ArgumentException("Invalid process.", "process")
Else
Dim element As AutomationElement = AutomationElement.FromHandle(process.MainWindowHandle)
If element Is Nothing Then
Return Nothing
Else
Try
Dim con As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom)
Dim docCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)
Dim imageCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Image)
Dim children As AutomationElementCollection = element.FindAll(TreeScope.Children, con)
Dim root As AutomationElement = Nothing
For Each child As AutomationElement In children
Dim items As AutomationElementCollection = child.FindAll(TreeScope.Children, Condition.TrueCondition)
If items.Count > 1 Then
If IsNothing(child.FindFirst(TreeScope.Children, imageCon)) Then
root = child
Exit For
End If
End If
Next
For Each child As AutomationElement In root.FindAll(TreeScope.Children, Condition.TrueCondition)
Dim childChildren As AutomationElementCollection = child.FindAll(TreeScope.Children, Condition.TrueCondition)
For Each item As AutomationElement In childChildren
Dim documents As AutomationElementCollection = item.FindAll(TreeScope.Children, docCon)
For Each doc As AutomationElement In documents
Dim title As String = doc.Current.Name
If Not String.IsNullOrWhiteSpace(title) Then title = Web.HttpUtility.HtmlDecode(title)
If Not String.IsNullOrWhiteSpace(title) AndAlso title.EndsWith(" - YouTube") Then FFTabs.Add(title.Substring(0, title.LastIndexOf(" - YouTube")).Trim)
Next
Next
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End If ' element Is Nothing
End If ' process Is Nothing
Return FFTabs
End FunctionAfter some more messing about, here's I think the final edit to get all windows:
Code
Private Declare Auto Function GetClassName Lib "User32.dll" (ByVal hwnd As IntPtr, <Out()> ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer
Private Delegate Function CallBack(ByVal hwnd As Integer, ByVal lParam As Integer) As Boolean
Private Declare Function EnumWindows Lib "user32" (ByVal Adress As CallBack, ByVal y As Integer) As Integer
Private Declare Function IsWindowVisible Lib "user32.dll" (ByVal hwnd As IntPtr) As Boolean
Private FFTabs As New List(Of String)
Private Function GetFFTabs() As List(Of String)
FFTabs.Clear()
EnumWindows(AddressOf FirefoxEnumerator, 0)
Return FFTabs
End Function
Private Function FirefoxEnumerator(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
If IsWindowVisible(hwnd) Then
Dim sClassName As New StringBuilder("", 256)
GetClassName(hwnd, sClassName, 256)
If sClassName.ToString = "MozillaWindowClass" Then
FindFirefoxTabs(hwnd)
End If
End If
Return True
End Function
Private Sub FindFirefoxTabs(hwnd As IntPtr)
Dim element As AutomationElement = AutomationElement.FromHandle(hwnd)
Try
Dim con As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom)
Dim docCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)
Dim imageCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Image)
Dim children As AutomationElementCollection = element.FindAll(TreeScope.Children, con)
Dim root As AutomationElement = Nothing
For Each child As AutomationElement In children
Dim items As AutomationElementCollection = child.FindAll(TreeScope.Children, Condition.TrueCondition)
If items.Count > 1 Then
If IsNothing(child.FindFirst(TreeScope.Children, imageCon)) Then
root = child
Exit For
End If
End If
Next
For Each child As AutomationElement In root.FindAll(TreeScope.Children, Condition.TrueCondition)
Dim childChildren As AutomationElementCollection = child.FindAll(TreeScope.Children, Condition.TrueCondition)
For Each item As AutomationElement In childChildren
Dim documents As AutomationElementCollection = item.FindAll(TreeScope.Children, docCon)
For Each doc As AutomationElement In documents
Dim title As String = doc.Current.Name
If Not String.IsNullOrWhiteSpace(title) Then title = Web.HttpUtility.HtmlDecode(title)
If Not String.IsNullOrWhiteSpace(title) AndAlso title.EndsWith(" - YouTube") Then FFTabs.Add(title.Substring(0, title.LastIndexOf(" - YouTube")).Trim)
Next
Next
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
