Author Topic: Switch to Tab in Chrome  (Read 6923 times)

Yamanox

  • Guest
Switch to Tab in Chrome
« on: May 16, 2017, 03:33:09 PM »
I currently  have it set up to where I can issue a command in order to maximize the chrome window itself but is there a way I can make it switch to a specific tab? If possible I want to somehow read the names from open tabs and switch based on name

EX:
-Issues command to maximize chrome
-Chrome popups with tab b open
- (trying to create a way for it to move to tab b or whatever tab I want on command)
« Last Edit: May 16, 2017, 05:34:11 PM by Yamanox »

iceblast

  • Sr. Member
  • ****
  • Posts: 374
Re: Switch to Tab in Chrome
« Reply #1 on: May 17, 2017, 12:52:41 AM »
Not sure you can have VA know the Windows Title for each tab, without having the tab active.

You can use CTRL+1, CTRL+2, CTRL+3 and so on for the tabs though. CTRL+TAB and CTRL+SHIFT+TAB to cycle back and forth through the tabs as well.


Yamanox

  • Guest
Re: Switch to Tab in Chrome
« Reply #2 on: May 17, 2017, 01:30:34 PM »
That's what I'm using for my current setup, Just trying to figure out if it's possible to read certain tab names

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4778
  • RTFM
Re: Switch to Tab in Chrome
« Reply #3 on: May 17, 2017, 02:59:08 PM »
It is possible; You could adapt this example to an inline function.

Alternatively, you could use the Chrome.tabs API, but that would require building a Chrome extension and combining that with a VoiceAttack inline function or plugin.

Exergist

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 405
  • Ride the lightning
Re: Switch to Tab in Chrome
« Reply #4 on: May 17, 2017, 03:39:11 PM »
There are probably other ways of doing this, but using the content of this post and this post I managed to get VA to provide the names of all the open tab titles in a single instance of Chrome through an inline VB.net function. This method leverages the same methodology as Pfeil provided. I also leveraged code from here for obtaining the active tab's URL. I had to search my PC for "UIAutomationClient.dll" and "UIAutomationTypes.dll" and copy those files to the highest version .NET framework folder located (for me) at C:\Windows\Microsoft.NET\Framework\v4.0.30319).

Here is the VA code:
Code: [Select]
Set Text [browser] to '*chrome'
Begin Text Compare : [{WINDOWEXISTS:browser}] Equals '0'
    Write '[Blue] Chrome is not open' to log
    Clear saved data from profile : small int (condition), integer, text, true/false (boolean), decimal
    DISABLED - Write '[Blue] Active Tab = Tab {INT:active tab number} = {TXT:active tab}' to log
    Exit Command
End Condition
Display window '*chrome' as [Show]
Pause 0.05 seconds
Set Text [active tab] to '{TXTREPLACEVAR:"{ACTIVEWINDOWTITLE}":" - Google Chrome":""}'
Inline VB Function: Get all Chrome tab titles, wait until execution finishes
Set integer [tab count] value to the converted value of {TXT:tab count}
Write '[Blue] Tab Count = {INT:tab count}' to log
Set integer [counter] value to 1
Start Loop While : [counter] Is Less Than Or Equals [tab count]
    Write '[Blue] Chrome Tab {INT:counter} Title = {TXT:{EXP:'chrome tab ' + {INT:counter}}}' to log
    Begin Text Compare : [{TXT:{EXP:'chrome tab ' + {INT:counter}}}] Equals [active tab]
        Set integer [active tab number] value to the value of [counter]
    End Condition
    Set integer [counter] to [counter] plus 1
End Loop
Write '[Blue] Active Tab = Tab {INT:active tab number} = {TXT:active tab}' to log
Inline VB Function: Get Chrome active tab URL, wait until execution finishes
Write '[Blue] Active Tab URL = {TXT:active tab URL}' to log

...and here is the inline function code for obtaining all open Chrome tab titles:
Code: [Select]
Referenced Assemblies:System.dll;System.Core.dll;System.Data.dll;System.Data.DataSetExtensions.dll;System.Deployment.dll;System.Drawing.dll;System.Net.Http.dll;System.Windows.Forms.dll;System.Xml.dll;System.Xml.Linq.dll;UIAutomationClient.dll;UIAutomationTypes.dll

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Data
Imports System.Drawing
Imports System.Diagnostics
Imports System.Windows.Forms
Imports System.Linq
Imports System.Xml.Linq
Imports System.Threading.Tasks
Imports System.Windows.Automation

'uses code and info from:
' http://www.bluelightdev.com/get-list-open-chrome-tabs
' http://stackoverflow.com/questions/1469386/referencing-system-windows-automation

Public Class VAInline

    Public Sub Main()

        '//Grab all the Chrome processes
        Dim chrome() As Process = Process.GetProcessesByName("chrome")
        Dim str as String
        Dim i as Integer
         
        '//Exit if chrome isn't running
        If chrome.Length <= 0 Then Exit Sub
         
        For Each chromeProcess As Process In chrome
         
            '//If the chrome process doesn't have a window handle then ignore it
            If chromeProcess.MainWindowHandle <> IntPtr.Zero Then
         
                '//To find the tabs we first need to locate something reliable - the 'New Tab' button
                Dim rootElement As AutomationElement = AutomationElement.FromHandle(chromeProcess.MainWindowHandle)
                Dim condNewTab As Condition = New PropertyCondition(AutomationElement.NameProperty, "New Tab")
                Dim elemNewTab As AutomationElement = rootElement.FindFirst(TreeScope.Subtree, condNewTab)

                '//Get the tabstrip by getting the parent of the 'new tab' button
                Dim tWalker As TreeWalker = TreeWalker.ControlViewWalker
                Dim elemTabStrip As AutomationElement = tWalker.GetParent(elemNewTab)
         
                '//Loop through all the tabs and get the names which is the page title
                Dim tabItemCondition As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem)
                i=1
                For Each tabItem As AutomationElement In elemTabStrip.FindAll(TreeScope.Children, tabItemCondition)
                    'MessageBox.Show(tabItem.Current.Name)
                    str = "chrome tab " & i
                    VA.SetText(str, tabItem.Current.Name)
                    i+=1
                Next
                VA.SetText("tab count", i-1)
            End If
        Next

    End Sub

End Class

..and here is the inline function code for obtaining the active tab's URL:
Code: [Select]
Referenced Assemblies:System.dll;System.Core.dll;System.Data.dll;System.Data.DataSetExtensions.dll;System.Deployment.dll;System.Drawing.dll;System.Net.Http.dll;System.Windows.Forms.dll;System.Xml.dll;System.Xml.Linq.dll;UIAutomationClient.dll;UIAutomationTypes.dll

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Data
Imports System.Drawing
Imports System.Diagnostics
Imports System.Windows.Forms
Imports System.Linq
Imports System.Xml.Linq
Imports System.Threading.Tasks
Imports System.Windows.Automation

'Uses code from:
' http://www.vbforums.com/showthread.php?843043-Get-URLs-from-all-open-Tabs-of-Chrome-and-Firefox

Public Class VAInline

Public Sub Main()

        Dim procsChrome As Process() = Process.GetProcessesByName("chrome")
        Dim result As String
        For Each chrome As Process In procsChrome
            If chrome.MainWindowHandle = IntPtr.Zero Then Continue For

            Dim elm As AutomationElement = AutomationElement.FromHandle(chrome.MainWindowHandle)
            Dim elmUrlBar As AutomationElement = elm.FindFirst(TreeScope.Descendants, New PropertyCondition(AutomationElement.NameProperty, "Address and search bar"))

            If elmUrlBar IsNot Nothing Then
                Dim patterns As AutomationPattern() = elmUrlBar.GetSupportedPatterns()
                If patterns.Length > 0 Then
                    Dim val As ValuePattern = DirectCast(elmUrlBar.GetCurrentPattern(patterns(0)), ValuePattern)
                    If Not elmUrlBar.GetCurrentPropertyValue(AutomationElement.HasKeyboardFocusProperty) Then result = LCase(val.Current.Value).Trim
                    'Exit For
                End If
            End If
        Next

        If Not result.StartsWith("http") Then
            result = "http://" + result
        End If

        VA.SetText("active tab URL", result)
        'MessageBox.Show(result)

End Sub
End Class

This will output a list of all the open tab names as well as deduce the name and URL of the tab that is currently open. The catch is that this method orders the tabs based on the order in which they were opened in the browser. So if you move tabs around on the browser bar the ordering provided by VA will not correspond to the left-to-right order on the browser. But as long as you DON'T change the tab ordering during your instance of Chrome then everything will work out and you can add keypresses like iceblast described to physically navigate the tabs in Chrome. Or there might be a way to do this with another inline function.

Sometimes VA drags a bit when running this, but it does the job. After exiting the VA "edit profile" mode I've found that the drag is less if you wait a few seconds before calling the command. Subsequent calls tend to be fairly responsive. As far as I've found the above methodology cannot obtain all open tab URLs without forcing Chrome to physically cycle through each tab to generate the corresponding URL in the address bar. Maybe others know of another way besides the other options previously suggested?

Edit - added code for obtaining active tab URL, cleaned up the main VA code, and provided additional comments.
« Last Edit: May 18, 2017, 03:07:40 PM by Exergist »