WinActivate on a specific IE browser tab
WinActivate works great to bring the browser to the front if the title I am looking for is the current tab the user is on.
However, if the user has multiple tabs open and the one I am looking for is not the current tab, the the browser is never brought forward.
Is there a way to activate the specific tab of the browser if that tab is not the one the user is currently on?
Thanks!
Mark
http://www.vbmark.com
These examples were written for IE8.
This function will find the HWND of an IE window with a given tab name:
TabWinID(tabName) { WinGet, winList, List, ahk_class IEFrame While, winList%A_Index% { n:=A_Index, ErrorLevel:=0 While, !ErrorLevel { ControlGetText, tabText, TabWindowClass%A_Index%, % "ahk_id" winList%n% if InStr(tabText, tabName) return, winList%n% } } }
Then, activating that tab will require using COM. Here is an example function using AHKL & the Acc Library:
TabActivate(hwnd, tabName) { ;// http://www.autohotkey.com/forum/topic37651.html&p=231093#231093 ControlGet, hTabUI , hWnd,, DirectUIHWND1, ahk_id %hwnd% Acc := Acc_ObjectFromWindow(hTabUI) ;// access "Tabs" control If (Acc.accChildCount > 1) ;// more than 1 tab tabs := Acc.accChild(3) ;// access just "IE document tabs" While (tabs.accChildCount >= A_Index) { tab := tabs.accChild(A_Index) If (tab.accName(0) = tabName) ;// test vs. "tabName" return tab.accDoDefaultAction(0) ;// invoke tab } }
http://www.vbmark.com
Any explanation on how to winactivate to a certain tab I have open would be appriciated GREATLY.
TabActivate(TabName, WinTitle="") { ControlGet, hTabUI , hWnd,, DirectUIHWND2, % WinTitle=""? "ahk_class IEFrame":WinTitle Tabs := Acc_ObjectFromWindow(hTabUI).accChild(1) ; access "Tabs" control Loop, % Tabs.accChildCount if (Tabs.accChild(A_Index).accName(0) = TabName) return, Tabs.accChild(A_Index).accDoDefaultAction(0) }
What's the best way to convert these functions to grab the currently active tab, then activate it later on? Say a user triggers a script from a particular tab (not a specific one, unlike the previous example, but any tab they run it from), goes to a different tab and window...is there a way to activate what was active when the script was triggered? The browser this is being done in is IE6 or IE7, depends on the user.
Thanks for any assistance.
So, what I'm trying to do is figure out a way to hit the OK button. Currently I have it using "send {enter}", but if the user doesn't have the correct IE window activated it just sends the enter key at the active window instead.
Jethrow: The script I'm using (you're familiar with it and have helped on it before) uses COM to grab some of the DOM elements off the page the user is on. The problem I'm having is that sometimes that particular page generates a pop-up message with an OK button. The script is able to click on links and go to different pages even with that OK button being up, but the OK button stays where it is in the forefront. If the user doesn't manually click the OK button before running the script, and instead click OK after the page change, it crashes IE completely.
So, what I'm trying to do is figure out a way to hit the OK button. Currently I have it using "send {enter}", but if the user doesn't have the correct IE window activated it just sends the enter key at the active window instead.
If it's a popup it's at the foreground so if you send return it will send it to the foreground (activated) window.
I made my personnal popup blocker (work with anyversion of IE since it use the title of the window).
Example :
SetTimmer AutoClose, 100 AutoClose: WinGetActiveTitle PopUpTitle If InStr(PopUpList, PopUpTitle) Send ^w ; Close the current tab Return
Work even with Opera Browser.
DllCall("ole32\CoInitialize", "Uint", 0) EVENT_SYSTEM_SOUND = 0x1 EVENT_SYSTEM_ALERT = 0x2 EVENT_SYSTEM_FOREGROUND = 0x3 EVENT_SYSTEM_MENUSTART = 0x4 EVENT_SYSTEM_MENUEND = 0x5 EVENT_SYSTEM_MENUPOPUPSTART = 0x6 EVENT_SYSTEM_MENUPOPUPEND = 0x7 EVENT_SYSTEM_CAPTURESTART = 0x8 EVENT_SYSTEM_CAPTUREEND = 0x9 EVENT_SYSTEM_MOVESIZESTART = 0xa EVENT_SYSTEM_MOVESIZEEND = 0xb EVENT_SYSTEM_CONTEXTHELPSTART = 0xc EVENT_SYSTEM_CONTEXTHELPEND = 0xd EVENT_SYSTEM_DRAGDROPSTART = 0xe EVENT_SYSTEM_DRAGDROPEND = 0xf EVENT_SYSTEM_DIALOGSTART = 0x10 EVENT_SYSTEM_DIALOGEND = 0x11 EVENT_SYSTEM_SCROLLINGSTART = 0x12 EVENT_SYSTEM_SCROLLINGEND = 0x13 EVENT_SYSTEM_SWITCHSTART = 0x14 EVENT_SYSTEM_SWITCHEND = 0x15 EVENT_SYSTEM_MINIMIZESTART = 0x16 EVENT_SYSTEM_MINIMIZEEND = 0x17 DllCall("SetWinEventHook" ;;http://msdn.microsoft.com/en-us/library/dd373640(v=vs.85).aspx , Uint, EVENT_SYSTEM_FOREGROUND ;;lParam starting event range , Uint, EVENT_SYSTEM_FOREGROUND ;;lParam ending event range , Uint, 1*0 , Uint, RegisterCallback( "KillAlert", "F" ) ;;http://msdn.microsoft.com/en-us/library/dd373885 , Uint, 1*0 , Uint, 1*0 , Uint, 1*0) KillAlert(hWinEventHook, Event, hWnd) { WinClose, ahk_id %hWnd% }Listener and killer for ahk basic can easily be converted for ahk_l
For more info see this
WIN or LEARN.
Jethrow,
I'm having issue trying to add your TabActivate code into my example.
The example assumes you have multiple tab windows open and you don't have the google tab currently open.
I need it to activate the IE window and open it to the tab name.
Currently the code will interact with the page but it won't bring it to the front for the user to see.
Here's what I got so far:
Search1 = Hello Hotkey, F9, start return start: if Pwb := IEGet("Google") TabActivate("Google") IELoad(Pwb) Pwb.Document.All.q.Value := Search1 return IEGet(Name="") { IfEqual, Name,, WinGetTitle, Name, ahk_class IEFrame Name := ( Name="New Tab - Windows Internet Explorer" ) ? "about:Tabs" : RegExReplace( Name, " - (Windows|Microsoft) Internet Explorer.*" ) For Pwb in ComObjCreate( "Shell.Application" ).Windows If ( Pwb.LocationName = Name ) && InStr( Pwb.FullName, "iexplore.exe" ) Return Pwb } TabActivate(TabName, WinTitle="") { ControlGet, hTabUI , hWnd,, DirectUIHWND2, % WinTitle=""? "ahk_class IEFrame":WinTitle Tabs := Acc_ObjectFromWindow(hTabUI).accChild(1) ; access "Tabs" control Loop, % Tabs.accChildCount if (Tabs.accChild(A_Index).accName(0) = TabName) return, Tabs.accChild(A_Index).accDoDefaultAction(0) } IELoad(Pwb) { Loop Sleep, 50 Until (pwb.readyState=4 && pwb.document.readyState="complete" && !pwb.busy) }
Blackholyman,
I am using IE 8 but I'm still having the same issues. It's not bringing that tab to the users front view.
I tested this on IE 10 and changed DirectUIHWND2 to DirectUIHWND3 and it activates the correct tab.
So going back to Jethrow's first example that works with IE8, how do you catch the return value and put it into the next function?
Below is my sorry attempt that doesn't work. I'm forced to use IE8 at work.
Search1 = Hello Hotkey, F9, start HotKey, F10, ReloadScript return ReloadScript: Reload Return start: if Pwb := IEGet("Google") TabWinID("Google") TabActivate(winList%n%, Google) WinActivate, Google WinRestore, Google IELoad(Pwb) Pwb.Document.All.q.Value := Search1 return IEGet(Name="") { IfEqual, Name,, WinGetTitle, Name, ahk_class IEFrame Name := ( Name="New Tab - Windows Internet Explorer" ) ? "about:Tabs" : RegExReplace( Name, " - (Windows|Microsoft) Internet Explorer.*" ) For Pwb in ComObjCreate( "Shell.Application" ).Windows If ( Pwb.LocationName = Name ) && InStr( Pwb.FullName, "iexplore.exe" ) Return Pwb } TabWinID(tabName) { WinGet, winList, List, ahk_class IEFrame While, winList%A_Index% { n:=A_Index, ErrorLevel:=0 While, !ErrorLevel { ControlGetText, tabText, TabWindowClass%A_Index%, % "ahk_id" winList%n% if InStr(tabText, tabName) return, winList%n% } } } TabActivate(hwnd, tabName) { ControlGet, hTabUI , hWnd,, DirectUIHWND1, ahk_id %hwnd% Acc := Acc_ObjectFromWindow(hTabUI) ;// access "Tabs" control If (Acc.accChildCount > 1) ;// more than 1 tab tabs := Acc.accChild(3) ;// access just "IE document tabs" While (tabs.accChildCount >= A_Index) { tab := tabs.accChild(A_Index) If (tab.accName(0) = tabName) ;// test vs. "tabName" return tab.accDoDefaultAction(0) ;// invoke tab } } IELoad(Pwb) { Loop Sleep, 50 Until (pwb.readyState=4 && pwb.document.readyState="complete" && !pwb.busy) }
Sorry to dig up such an old post, but I can't seem to get my script to activate the correct tab
This is what I have so far:
#Include %A_ScriptDir%\Acc.ahk IEGet(Name="") ;Retrieve pointer to existing IE window/tab { IfEqual, Name,, WinGetTitle, Name, ahk_class IEFrame Name := ( Name="New Tab - Windows Internet Explorer" ) ? "about:Tabs" : RegExReplace( Name, " - (Windows|Microsoft) Internet Explorer" ) For wb in ComObjCreate( "Shell.Application" ).Windows If ( wb.LocationName = Name ) && InStr( wb.FullName, "iexplore.exe" ) Return wb } ;written by Jethrow TabActivate(TabName, WinTitle="") { ControlGet, hTabUI , hWnd,, DirectUIHWND3, % WinTitle=""? "ahk_class IEFrame":WinTitle Tabs := Acc_ObjectFromWindow(hTabUI).accChild(1) ; access "Tabs" control Loop, % Tabs.accChildCount if (Tabs.accChild(A_Index).accName(0) = TabName) return, Tabs.accChild(A_Index).accDoDefaultAction(0) } ^!n:: wb := IEGet("Google") TabActivate("Google", "Google - Windows Internet Explorer") Wait(wb) Return
What am I doing wrong? I am using IE 9