2013-09-10 4 views
1

Были проблемы с этим в течение последних 5 дней, поэтому решили опубликовать эту проблему.IE Automation - идентификация активной вкладки

У меня есть приложение, прикрепленное к панели инструментов IE (IE Addon). Если один экземпляр IE открыт (без каких-либо вкладок), приложение работает нормально. Однако, если у нас открыто несколько вкладок, он попытается обработать все вкладки, а не те, на которые нажата кнопка.

Проблема в том, что значение HWND (из IE.HWND), генерируемое всеми вкладками, одинаково, включая родительские вкладки.

Это проверка я выступаю перед запуском приложения:

Dim SWs As New SHDocVw.ShellWindows 
Dim IE As SHDocVw.InternetExplorer 
Dim mhWnd As Long 
myhWnd = GetForegroundWindow() 
For Each IE In SWs 
    If Strings.Left(IE.LocationURL, 4) = "http" Then 'if the document is IE then  proceed because EXPLORER window returns in the same group 


    Set Doc = IE.document 

     MsgBox ("Debugging 3 IE.hwnd :" & IE.hwnd & "myHwnd : " & myhWnd) 
     If (IE.hwnd = myhWnd) Then 
    'application launch code 

Каждый раз вышеприведенные работает, он пытается обработать все открытые вкладки, которые, наоборот, я заинтересован только в вкладка, в которой пользователь в данный момент включен.

Попробовали использовать IAccessibility для идентификации текущей вкладки, но IAccessible продолжает возвращать null. Пожалуйста, см. Ниже код IAccessibility:

using System; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 
using SHDocVw; 
using Accessibility; 
using System.Windows.Forms; 

namespace FinWindowsTab 
{ 
public class FindWindowsTab 
{ 
    public enum OBJID : uint 
    { 
     OBJID_WINDOW = 0x00000000, 

    } 
    private const int IE_ACTIVE_TAB = 2097154; 
    private const int CHILDID_SELF = 0; 
    private IAccessible accessible; 
    private FindWindowsTab[] Children; 

    public static void Main(String[] args) 
    { 
     // InternetExplorer IE = new InternetExplorer(); 
     ShellWindows SW = new ShellWindows(); 
     try 
     { 
      foreach (InternetExplorer IE in SW) 
      { 
       if (IE.Name == "Windows Internet Explorer") 
       { 

        string urlOfTabToActivate = IE.LocationURL; 

        var directUi = GetDirectUIHWND((IntPtr)IE.HWND); 
        var iacc = AccessibleObjectFromWindow(directUi); 
        var tabRow = FindAccessibleDescendant(iacc, "Tab Row"); 
        var tabs = AccChildren(tabRow); 
        int tc = tabs.Count; 
        int k = 0; 

        // walk through the tabs and tick the chosen one 
        foreach (var candidateTab in tabs) 
        { 
         k++; 
         // the last tab is "New Tab", which we don't want 
         if (k == tc) continue; 

         // the URL on *this* tab 
         string localUrl = UrlForTab(candidateTab); 
         MessageBox.Show("Local Url :" + localUrl); 
         // same? if so, tick it. This selects the given tab among all 
         // the others, if any. 
         if (urlOfTabToActivate != null && localUrl.Equals(urlOfTabToActivate)) 
         { 
          candidateTab.accDoDefaultAction(0); 
          return; 
         } 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("An exception has occured : " + ex.Message); 
     } 


    } 

    private static IntPtr GetDirectUIHWND(IntPtr ieFrame) 
    { 
     // try IE 9 first: 

     IntPtr intptr = FindWindowEx(ieFrame, IntPtr.Zero, "WorkerW", null); 
     if (intptr == IntPtr.Zero) 
     { 
      // IE8 and IE7 
      intptr = FindWindowEx(ieFrame, IntPtr.Zero, "CommandBarClass", null); 
     } 
     intptr = FindWindowEx(intptr, IntPtr.Zero, "ReBarWindow32", null); 
     intptr = FindWindowEx(intptr, IntPtr.Zero, "TabBandClass", null); 
     intptr = FindWindowEx(intptr, IntPtr.Zero, "DirectUIHWND", null); 
     return intptr; 
    } 

    private static IAccessible AccessibleObjectFromWindow(IntPtr hwnd) 
    { 

     Guid guid = new Guid("{2359BD84-0175-4783-8909-CBD181217D3C}"); // IAccessible 
     object obj = null; 
     uint id = 0U; 
     int num = AccessibleObjectFromWindow(hwnd, id, ref guid, ref obj); 
     var acc = (IAccessible)obj; 
     return acc; 
    } 

    private static object[] GetAccessibleChildren(IAccessible ao) 
    { 
     var childs = 0; 
     object[] ret = null; 
     int count = 0; 
     count = ao.accChildCount; 
     MessageBox.Show("Count value : " + count); 
     if (count > 0) 
     { 
      ret = new object[count]; 
      AccessibleChildren(ao, 0, count, ret, out childs); 
     } 
     return ret; 
    } 

    private static IAccessible FindAccessibleDescendant(IAccessible parent, String strName) 
    { 
     int c = 0; 
      c = parent.accChildCount; 
     if (c == 0) 
      return null; 

     var children = AccChildren(parent); 

     foreach (var child in children) 
     { 
      if (child == null) continue; 
      if (strName.Equals(child.get_accName(0))) 
       return child; 

      var x = FindAccessibleDescendant(child, strName); 
      if (x != null) return x; 
     } 

     return null; 
    } 

    private static List<IAccessible> AccChildren(IAccessible accessible) 
    { 
     object[] res = GetAccessibleChildren(accessible); 
     var list = new List<IAccessible>(); 
     if (res == null) return list; 

     foreach (object obj in res) 
     { 
      IAccessible acc = obj as IAccessible; 
      if (acc != null) list.Add(acc); 
     } 
     return list; 
    } 

    private static string UrlForTab(IAccessible tab) 
    { 
     try 
     { 
      var desc = tab.get_accDescription(0); 
      if (desc != null) 
      { 
       if (desc.Contains("\n")) 
       { 
        string url = desc.Substring(desc.IndexOf("\n")).Trim(); 
        return url; 
       } 
       else 
       { 
        return desc; 
       } 
      } 
     } 
     catch { } 
     return "??"; 
    } 


    [DllImport("user32.dll", SetLastError = true)] 
    private static extern IntPtr FindWindowEx(IntPtr hwndParent, 
               IntPtr hwndChildAfter, 
               string lpszClass, 
               string lpszWindow); 
    [DllImport("oleacc.dll")] 
    internal static extern int AccessibleObjectFromWindow 
     (IntPtr hwnd, uint id, ref Guid iid, 
     [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object ppvObject); 


    [DllImport("oleacc.dll")] 
    private static extern int AccessibleChildren(IAccessible paccContainer, int iChildStart, int cChildren, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] object[] rgvarChildren, out int pcObtained); 
    } 


} 

Пожалуйста, любая помощь будет оценена по достоинству.

+0

Решили эту проблему. Просто в том, что кто-то оказался в этом сценарии, это помогло мне http://www.codeproject.com/Articles/204929/Getting-current-browser-URL-with-VB-NET – Addy

ответ

Смежные вопросы