1

在过去的 5 天里一直在努力解决这个问题,所以决定发布这个问题。

我有一个附加到 IE 工具栏(IE 插件)的应用程序。如果打开了一个 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);
   }


 }

请任何帮助将不胜感激。

4

1 回答 1

1

解决了这个问题。万一有人发现自己处于这种情况下,这对我有帮助http://www.codeproject.com/Articles/204929/Getting-current-browser-URL-with-VB-NET

于 2013-09-16T14:23:30.577 回答