使用.net 2.0从C#程序将焦点设置为已打开的Internet Explorer选项卡
我有两个问题使用.net 2.0从C#程序将焦点设置为已打开的Internet Explorer选项卡,c#,.net,internet-explorer,C#,.net,Internet Explorer,我有两个问题 如何使用.net 2.0从C#程序将焦点设置为已打开的Internet Explorer选项卡 如何从C#程序在运行Internet Explorer实例的新选项卡(而不是新窗口)中打开新URL 我最多只能使用.net 2.0 非常感谢您的帮助。以下是如何根据选项卡的URL地址激活选项卡的代码。我做了测试,效果很好。您可以根据文本/描述等添加如何激活选项卡的功能。如果需要在.net 2.0下运行,请将var更改为特定类型 这是一个实际的代码本身。我把它分门别类地包装起来 using
非常感谢您的帮助。以下是如何根据选项卡的URL地址激活选项卡的代码。我做了测试,效果很好。您可以根据文本/描述等添加如何激活选项卡的功能。如果需要在.net 2.0下运行,请将var更改为特定类型 这是一个实际的代码本身。我把它分门别类地包装起来
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Accessibility;
namespace IETabsInteraction
{
internal class TabActivator
{
#region Nested type: OBJID
private enum OBJID : uint
{
OBJID_WINDOW = 0x00000000,
}
#endregion
#region Declarations
private const int CHILDID_SELF = 0;
private readonly IntPtr _hWnd;
private IAccessible _accessible;
[DllImport("oleacc.dll")]
private static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint id, ref Guid iid,
[In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object
ppvObject);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass,
string lpszWindow);
[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);
#endregion
#region Constructors
internal TabActivator(IntPtr ieHandle)
{
_hWnd = ieHandle;
AccessibleObjectFromWindow(GetDirectUIHWND(ieHandle), OBJID.OBJID_WINDOW, ref _accessible);
CheckForAccessible();
}
private TabActivator(IAccessible acc)
{
if (acc == null)
throw new Exception("Could not get accessible");
_accessible = acc;
}
#endregion
private TabActivator[] Children
{
get
{
var num = 0;
var res = GetAccessibleChildren(_accessible, out num);
if (res == null)
return new TabActivator[0];
var list = new List<TabActivator>(res.Length);
foreach (object obj in res)
{
var acc = obj as IAccessible;
if (acc != null)
list.Add(new TabActivator(acc));
}
return list.ToArray();
}
}
private int ChildCount
{
get { return _accessible.accChildCount; }
}
/// <summary>
/// Gets LocationUrl of the tab
/// </summary>
private string LocationUrl
{
get
{
var url = _accessible.accDescription[CHILDID_SELF];
if (url.Contains(Environment.NewLine))
url = url.Split('\n')[1];
return url;
}
}
private void CheckForAccessible()
{
if (_accessible == null)
throw new Exception("Could not get accessible. Accessible can't be null");
}
internal void ActivateByTabsUrl(string tabsUrl)
{
var tabIndexToActivate = GetTabIndexToActivate(tabsUrl);
AccessibleObjectFromWindow(GetDirectUIHWND(_hWnd), OBJID.OBJID_WINDOW, ref _accessible);
CheckForAccessible();
var index = 0;
var ieDirectUIHWND = new TabActivator(_hWnd);
foreach (var accessor in ieDirectUIHWND.Children)
{
foreach (var child in accessor.Children)
{
foreach (var tab in child.Children)
{
if (tabIndexToActivate >= child.ChildCount - 1)
return;
if (index == tabIndexToActivate)
{
tab.ActivateTab();
return;
}
index++;
}
}
}
}
private void ActivateTab()
{
_accessible.accDoDefaultAction(CHILDID_SELF);
}
private int GetTabIndexToActivate(string tabsUrl)
{
AccessibleObjectFromWindow(GetDirectUIHWND(_hWnd), OBJID.OBJID_WINDOW, ref _accessible);
CheckForAccessible();
var index = 0;
var ieDirectUIHWND = new TabActivator(_hWnd);
foreach (var accessor in ieDirectUIHWND.Children)
{
foreach (var child in accessor.Children)
{
foreach (var tab in child.Children)
{
var tabUrl = tab.LocationUrl;
if (!string.IsNullOrEmpty(tabUrl))
{
if (tab.LocationUrl.Contains(tabsUrl))
return index;
}
index++;
}
}
}
return -1;
}
private IntPtr GetDirectUIHWND(IntPtr ieFrame)
{
// For IE 8:
var directUI = FindWindowEx(ieFrame, IntPtr.Zero, "CommandBarClass", null);
directUI = FindWindowEx(directUI, IntPtr.Zero, "ReBarWindow32", null);
directUI = FindWindowEx(directUI, IntPtr.Zero, "TabBandClass", null);
directUI = FindWindowEx(directUI, IntPtr.Zero, "DirectUIHWND", null);
if (directUI == IntPtr.Zero)
{
// For IE 9:
//directUI = FindWindowEx(ieFrame, IntPtr.Zero, "WorkerW", "Navigation Bar");
directUI = FindWindowEx(ieFrame, IntPtr.Zero, "WorkerW", null);
directUI = FindWindowEx(directUI, IntPtr.Zero, "ReBarWindow32", null);
directUI = FindWindowEx(directUI, IntPtr.Zero, "TabBandClass", null);
directUI = FindWindowEx(directUI, IntPtr.Zero, "DirectUIHWND", null);
}
return directUI;
}
private static int AccessibleObjectFromWindow(IntPtr hwnd, OBJID idObject, ref IAccessible acc)
{
var guid = new Guid("{618736e0-3c3d-11cf-810c-00aa00389b71}"); // IAccessibleobject obj = null;
object obj = null;
var num = AccessibleObjectFromWindow(hwnd, (uint) idObject, ref guid, ref obj);
acc = (IAccessible) obj;
return num;
}
private static object[] GetAccessibleChildren(IAccessible ao, out int childs)
{
childs = 0;
object[] ret = null;
var count = ao.accChildCount;
if (count > 0)
{
ret = new object[count];
AccessibleChildren(ao, 0, count, ret, out childs);
}
return ret;
}
}
}
回答你的第二个问题。您需要找到您已经运行的ie:
private static void OpenTabInExistingIE()
{
var shellWindows = new ShellWindows();
// check if IE is open
if (shellWindows.Count > 0)
((InternetExplorer)shellWindows.Item(0)).Navigate2("www.stackoverflow.com", 2048);
}
对于所有这些代码,您必须添加对SHDocVw.dll和
#using SHDocVw;
下面是Navigate2方法的标志
Enum BrowserNavConstants
navOpenInNewWindow = 1
navNoHistory = 2
navNoReadFromCache = 4
navNoWriteToCache = 8
navAllowAutosearch = 16
navBrowserBar = 32
navHyperlink = 64
navEnforceRestricted = 128
navNewWindowsManaged = 256
navUntrustedForDownload = 512
navTrustedForActiveX = 1024
navOpenInNewTab = 2048
navOpenInBackgroundTab = 4096
navKeepWordWheelText = 8192
navVirtualTab = 16384
navBlockRedirectsXDomain = 32768
navOpenNewForegroundTab = 65536
End Enum
看到你在没有应用程序的情况下托管IE了吗,例如使用IE WinForms控件?谢谢Stuart,但是这个链接帮不了我。我不想写任何附加组件。可能还有其他方法。@Ian:是的,我没有托管IE。它通常在窗口中运行。
var url=\u accessible.accscription[CHILDID\u SELF]代码>抛出错误<代码>属性、索引器或事件“accDescription”不受语言支持;尝试直接调用访问器方法“Accessibility.IAccessible.get_accscription(object)”
我已将该行更改为string url=\u accessible.get_accscription(CHILDID\u SELF)代码>并且它工作!在I.E.11中根本不起作用。没有任何项返回带有换行符的描述,许多项返回null,导致代码按原样抛出异常。但是,有了它,似乎所有的赌注都没有了。谢谢你的代码示例。我无耻地采用、修改并创建了一个不依赖SHDocVw.dll的版本。
Enum BrowserNavConstants
navOpenInNewWindow = 1
navNoHistory = 2
navNoReadFromCache = 4
navNoWriteToCache = 8
navAllowAutosearch = 16
navBrowserBar = 32
navHyperlink = 64
navEnforceRestricted = 128
navNewWindowsManaged = 256
navUntrustedForDownload = 512
navTrustedForActiveX = 1024
navOpenInNewTab = 2048
navOpenInBackgroundTab = 4096
navKeepWordWheelText = 8192
navVirtualTab = 16384
navBlockRedirectsXDomain = 32768
navOpenNewForegroundTab = 65536
End Enum