Activate browser tab in XP

Started by RAK, December 02, 2013, 11:21:00 AM

Previous topic - Next topic

RAK

I have a script that activates IE browsers using the window title.. It works fine on tabbed browsers in newer OS's (Vista+up), but in XP - only the active browser tab appears in the open window list; winexist = 0. So I figured I could use COM to activate the window but cannot seem to find a command to do it. I have looked at the OLECMDID functions and still cannot find anything like browser.activate or focus. I do have the required object, just looking for what to send it to make the window the active tab.. I found nothing in the Navigate2 method either.. I even tried refresh, swap visible status, nothing seems to work.. 
It must be there - just beyond me...
thanks
Roy

td

The problem likely has more to do with the version of IE than the version of Windows.  All the XP systems I have access to have IE 8 and the main IE window always has 'Windows Internet Explorer' as the final part of the window's title.  No matter which browser tab is active.

If the absence of  'Internet Explorer' in the title is causing the problem you may want to look at RoboScripter or just use one of the Control Manager searching functions to obtain a handle to the browser's main frame.

Untested but this might get what you want...
Code (winbatch) Select

hIeMain = cWndByClass( 0, "IEFrame")
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

RAK

Thanks for the idea but the window title is not the issue. I have the proper titles.. No matter the title - you cannot access an inactive tab in XP with any of the WB win commands. (winactivate, winexist, ETC.... I think I need COM to activate it - I went from IE7 to 8 and no difference.. IE 7 and 8 act different when run in Vista and up - I think inactive tab titles are available to WB in newer OS's

RAK

Basically - I need any way to activate an IE tab in any OS..  a click on the tab would do it I guess. Is there a way to locate the tab and click it? Guess I will look at the cWndByClass functions

Thanks


RAK

the tabbed browser titles appear in the WinItemChild list when used on the active browser but the winactivechild function has no effect - oh well - thought I had it.

td

Yes, IE tab windows are arranged differently relative to each other on Windows Vista and newer when compared to XP.

You could use Control Manger functions to find the appropriate child window handle.  Once you have the handle you can try using the cSetFocus function to bring the tab to the foreground.   RoboScripter or the Analysis.wbt script my be helpful and it will no doubt require some trial and error. 

The downside of using the extender is that the class names and window relationships change between versions of Windows and versions of  IE so so you would have to detect versions and modify the solution accordingly.

Since you mentioned Navigate2, you may have already tried this but there is an example in the tech DB that illustrates how to load a URL into a specific existing tab.  In theory you could force IE to reload a tab's existing site and there by forcing it to the foreground.  The article can be found here

http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/OLE~COM~ADO~CDO~ADSI~LDAP/OLE~with~MSIE+Working~with~Multiple~Tabs~in~Internet~Explorer.txt

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Quote from: RAK on December 02, 2013, 02:31:26 PM
the tabbed browser titles appear in the WinItemChild list when used on the active browser but the winactivechild function has no effect - oh well - thought I had it.


Might be because the window is disabled.  WinActiveChild will not bring a disabled child window to the foreground.  I have not tried it but you might be able to do something with the control manager cEnableState function to enable the tab.  You would just need to get the window handle associated with the child window. Perhaps using cWndbyname.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

RAK

thanks for your ideas.. I had to move on today as I spent too long on it.. Will be back on it later tonight or tom... any more info is very welcome and appreciated..

thanks
Roy

RAK

I see your 8.1 sig.. I just updated to it from 8 in one of my laptops.. I like it more but still no love.. You like it? I need to spend some more time on it to give it a chance.. I had very little like for 8.

td

I tested most of my suggestions and none seem to work.  I have some vague notion that there is a workaround for activating an IE tab on XP but... You may have to resort to SendKey or mouse moves unless someone else has a solution. 

I am not a fan of Windows 8 or Windows 8.1.  8.1 is a slight improvement over 8 but both OS's are more about advancing MSFT's marketing agenda that providing a great user experience for desktop and notebook users.   I think the reaction to Windows 8.1 will largely depend on an individual's primary computer related activities.  Those primarily interesting in social media, shopping and watching video will find it more to there liking than those that use their computers for more mundane tasks. 

I use several 8.1 systems.  My most frequently used 8.1 system is a touch enabled ultrabook with a modified Windows shell to get around some of the more egregious UI shortcomings of 8.1 .  That system is surprising responsive mostly because of hardware advances made by Intel but also because of improvements made in the Windows 8 kernel and SSD caching.

   
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

The following is based on the Tech. Supt. article mentioned above and is not elegant but it gets the job done on XP + IE 8.
Code (winbatch) Select

#DefineSubRoutine ActivateIeTab(strTabUrl)
   oShell = CreateObject("Shell.Application")
   nTab = 0
   ForEach obj In oShell.Windows
      If StrIndexNC(obj.fullname, "iexplore.exe", 1, @FWDSCAN)
         nTab=nTab+1
         strUrl = obj.locationURL
         if StrIndexNC( strUrl, strTabUrl, 1, @Fwdscan )
            SendKeysTo("~Internet Explorer", "^":nTab)
         endif
      Endif
   Next
   oShell=0
   Return(1)
#EndSubRoutine

; Activate tab displaying MSN.com
ActivateIeTab("MSN.com")
exit
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

RAK

Just tested it - Thanks!
It works when there is only one main browser window open - I need to fig a way for it to determine the correct window to send the keys to when there are 2 or more windows open. Will work on it this afternoon..
Thanks again..
Roy

td

Quote from: RAK on December 03, 2013, 10:05:31 AM
Just tested it - Thanks!
It works when there is only one main browser window open - I need to fig a way for it to determine the correct window to send the keys to when there are 2 or more windows open. Will work on it this afternoon..
Thanks again..
Roy

Of course you need to account for multiple instances. Perhaps I should have mentioned that in the previous post.  Anyway here is rough example but there are other approaches.

Code (winbatch) Select

AddExtender("wwctl44i.dll")

;; Needs additional error checks, etc.
;; Will activate tabs of all IE instance with the targeted partial URL.
#DefineFunction ActivateIeTab(strTabUrl)
   oShell = CreateObject("Shell.Application")
   nTab = 0
   ForEach obj In oShell.Windows
      If StrIndexNC(obj.fullname, "iexplore.exe", 1, @FWDSCAN)
         objApp = obj.Application
         if ObjectTypeGet(objApp) == "DISPATCH"
            hWnd =  objApp.HWND
           
            ;; Substitution not exactly needed but good enough for
            ;; a quick and dirty example.
            if IsDefined(nTab%hWnd%) then nTab%hWnd%=nTab%hWnd%+1
            else  nTab%hWnd%= 1
            strUrl = obj.locationURL
            if StrIndexNC( strUrl, strTabUrl, 1, @Fwdscan )
               SendKeysTo(cWinIdConvert(hWnd), "^":nTab%hWnd%)
            endif
         endif
      Endif
   Next
   oShell=0
   objApp=0
   Return(1)
#EndFunction


;; Make winbatch.com tab active.
ActivateIeTab("winbatch.com")
exit

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Don't need the application business so here is a simplified version.
Code (winbatch) Select

; Activate tab displaying MSN.com
ActivateIeTab("MSN.com")
exit

AddExtender("wwctl44i.dll")

;; Needs additional error checks, etc.
;; Will activate tabs of all IE instance with the targeted partial URL.
#DefineFunction ActivateIeTab(strTabUrl)
   oShell = CreateObject("Shell.Application")
   nTab = 0
   ForEach obj In oShell.Windows
      If StrIndexNC(obj.fullname, "iexplore.exe", 1, @FWDSCAN)
         hWnd =  obj.hwnd
           
         ;; Substitution not exactly needed but good enough for
         ;; a quick and dirty example.
          if IsDefined(nTab%hWnd%) then nTab%hWnd%=nTab%hWnd%+1
         else  nTab%hWnd%= 1
         strUrl = obj.locationURL
         if StrIndexNC( strUrl, strTabUrl, 1, @Fwdscan )
               SendKeysTo(cWinIdConvert(hWnd), "^":nTab%hWnd%)
         endif
      Endif
   Next
   oShell=0
   Return(1)
#EndFunction


;; Make winbatch.com tab active.
ActivateIeTab("winbatch.com")
exit
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

RAK

It works sometimes - it gets confused and selects the wrong tab. I think it's because it counts tabs when they may be from the other window so it throws off the tab reference number for that tab group. Is there a way to sort the shell windows by their parent window? Then the tab numbers would be in proper order.

I will now check your new post..

Thanks!

RAK

Seems that the active tab in each window effects it operation - if the last tab is the active tab - it's wrong almost every time - however - it seems to always select the proper window to attempt it's tab selection - that' valuable.

RAK

I think I found a way - If I separate the tab counts by the hwnd ID# then it will have the correct tab ID# - not sure how to do it yet but I think it will solve the issue

RAK

this is the list of hwnd's

132852
2818862
2818862
2818862
2818862
2818862
2818862
132852
132852

Not sure why there are 3 132852's when there are only 2 tab in that window but probably does not matter.. Seems that it would certainly throw off the tab counts as they are not in order.

Maybe I should detect the correct ID and focus on that one only.. ?

RAK

Got IT!
The hwnd and ^tab sendkey did the trick!
Thanks so much for your help!

I will play some more - maybe it can be done in a single loop
Roy

oShell = CreateObject("Shell.Application")
ForEach obj In oShell.Windows
   If StrIndexNC(obj.fullname, "iexplore.exe", 1, @FWDSCAN)
      if StrIndexNC( obj.locationURL, strTabUrl, 1, @Fwdscan )
         thWnd = obj.hwnd
         break
      endif
   Endif
Next
oShell=0
oShell = CreateObject("Shell.Application")
nTab = 1
ForEach obj In oShell.Windows
   If StrIndexNC(obj.fullname, "iexplore.exe", 1, @FWDSCAN) && thWnd == obj.hwnd
      if StrIndexNC( obj.locationURL, strTabUrl, 1, @Fwdscan )
         SendKeysTo(cWinIdConvert(obj.hwnd), "^":nTab)
         break
      endif
      nTab = nTab+1
   Endif   
Next
oShell=0

td

I tried the final script I posted as posted on XP,IE 8 with four IE processes executing, each with one or more tabs, and in no case did the script generate an incorrect tab count or select the wrong tab.  However, I can certainly see how that could happen, if a site displays a child frame like a popup or even a hidden window.  The popup, child or hidden window would likely have the same parent window handle as the tab windows for a given process and therefore be counted as a tab.

Your script as written would be vulnerable to the same type of problem.  However, I think your approach is better than messing around with substitution and if its working for you,  all the better.
 

   
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

RAK

I think it's effected by the order that the tabs are opened.. If you open a tab in one window and then the other for each of your tab sets - I think you will see the issue I had.. I think invisible windows will have a different ID#.  popups are another issue..

I know I can check for visible status - how would I identify an IE popup? objWindow.TopLevelContainer?

would this protect me?
If StrIndexNC(obj.fullname, "iexplore.exe", 1, @FWDSCAN) && thWnd == obj.hwnd && obj.TopLevelContainer && obj.visible

seems to work

thanks

RAK

I actually have the window title in the request so I have removed the url functions...
Here's the 'current' final routine to activate a tab using the window title in XP

Also to repeat my question: obj.TopLevelContainer will weed out popups?

#DefineSubroutine actBrowserTabByTitle8(wtitle)
   IntControl(73, 3, 1, "WBERROR", 0)
   Shell = ObjectOpen("Shell.Application")
   foreach objWindow In Shell.Windows
      If objWindow.TopLevelContainer
         If StrIndexNC(objWindow.fullname, "iexplore.exe", 1, @FWDSCAN) > 0
            If StrIndexNC(objWindow.document.title,wtitle, 1, @FWDSCAN) > 0
               thWnd = objWindow.hwnd
               break
            EndIf
         endif
      Endif
   Next
   shell = 0
   objWindow = 0
   oShell = CreateObject("Shell.Application")
   nTab = 1
   ForEach obj In oShell.Windows
      If StrIndexNC(obj.fullname, "iexplore.exe", 1, @FWDSCAN) && thWnd == obj.hwnd && obj.TopLevelContainer && obj.visible
         if StrIndexNC( obj.document.title, wtitle, 1, @Fwdscan )
            SendKeysTo(cWinIdConvert(obj.hwnd), "^":nTab)
            break
         endif
         nTab = nTab+1
      Endif     
   Next
   oShell=0
   Return(1)
#EndSubRoutine

td

Quote from: RAK on December 03, 2013, 02:30:05 PM
I think it's effected by the order that the tabs are opened.. If you open a tab in one window and then the other for each of your tab sets - I think you will see the issue I had..

Actually tried many different opening oder combinations using multiple instances but never saw your issue.

Quote
I think invisible windows will have a different ID#. 

Not necessarily the case.

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

RAK

obj.TopLevelContainer will weed out popups?

Maybe the issue is sendkey speed.. The Xp test machine I am using is a little slow.. Will test slowing it down a little or activating the parent window first as functions are still occasionally inconsistent. I think I remember there is an intcontrol function that causes sendkey to wait for window readiness.. will look for it..

thanks