0

显然,你不能一边吃蛋糕一边吃。

我目前正在System.Windows.Forms.WebBrowser我的应用程序中使用。该程序目前依赖于使用该GetElementsByTagName功能。我用它来收集某种类型的所有元素(“input”或“textarea”),所以我可以对它们进行排序并返回特定元素的值。这是该函数的代码(我的 WebBrowser 名为 web1):

// returns the value from a element.
public String FetchValue(String strTagType, String strName) 
{
    HtmlElementCollection elems;
    HtmlDocument page = web1.Document.Window.Frames[1].Document;
    elems = page.GetElementsByTagName(strTagType);
    foreach (HtmlElement elem in elems)
    {
        if (elem.GetAttribute("name") == strName ||
            elem.GetAttribute("ref") == strName)
        {
            if (elem.GetAttribute("value") != null)
            {
                return elem.GetAttribute("value");
            }
        }
    }

    return null;
}

(注意点:我需要拉取的网页是在一个框架中,根据情况,元素的标识名称会在 name 或 ref 属性中)

所有这些对System.Windows.Forms.WebBrowser.

但它无法做的是重定向新窗口的打开以保留在应用程序中。在新窗口中打开的任何内容都会发送到用户的默认浏览器,从而丢失会话。此功能可以通过没有的NewWindow2事件轻松修复。System.Windows.Forms.WebBrowser

现在请原谅我对它的缺席感到震惊。我最近放弃了 VB6 并转向 C#(是的 VB6,显然我是在一块石头下工作的),而在 VB6 中,它WebBrowser同时拥有了GetElementsByTagName函数和NewWindow2事件。

AxSHDocVw.WebBrowser一个NewWindow2事件。如果能帮助我将新窗口路由到我需要它们的地方,我会非常高兴。执行此操作的代码WebBrowser是(frmNewWindow 是一个简单的表单,仅包含另一个WebBrowser名为 web2(Dock 设置为 Fill)):

private void web1_NewWindow2(
                      object sender, 
                      AxSHDocVw.DWebBrowserEvents2_NewWindow2Event e)
{
    frmNewWindow frmNW = new frmNewWindow();
    e.ppDisp = frmNW.web2.Application;
    frmNW.web2.RegisterAsBrowser = true;
    frmNW.Visible = true;
}

我无法自己制作一种方法来复制该功能与平淡无奇的常规 NewWindow 事件。

我也无法弄清楚如何FetchValue使用AxSHDocVw.WebBrowser. 它似乎以完全不同的方式处理事情,我所有关于如何做事的知识都是无用的。

我知道我是一个病态的、扭曲的人,因为在一个应用程序中使用这两个东西的奇怪幻想。但是你能找到帮助这个愚蠢的理想主义者的心吗?

4

3 回答 3

2

我不能再依赖解决方法,不得不放弃 System.Windows.Forms.WebBrowser。我需要NewWindow2。

我最终想出了如何使用 AxWebBrowser 来完成我所需要的。我原来的帖子是要求在 System.Windows.Forms.WebBrowser 上为 NewWindow2 提供解决方案,或者用 AxWebBrowser 替代 .GetElementsByTagName。替换需要大约 4 倍的代码,但可以完成工作。我认为发布我的解决方案是谨慎的做法,以供后来遇到同样困境的 Google 员工使用。(如果有更好的方法可以做到这一点)

IHTMLDocument2 webpage = (IHTMLDocument2)webbrowser.Document;
IHTMLFramesCollection2 allframes = webpage.frames;
IHTMLWindow2 targetframe = (IHTMLWindow2)allframes.item("name of target frame");
webpage = (IHTMLDocument2)targetframe.document;
IHTMLElementCollection elements = webpage.all.tags("target tagtype");

foreach (IHTMLElement element in elements)
{
  if (elem.getAttribute("name") == strTargetElementName)
   {
     return element.getAttribute("value");
   }
}

webbrowser.Document 被转换为 IHTMLDocument2,然后 IHTMLDocument2 的帧被放入 IHTMLFramesCollection2,然后我将特定的所需帧转换为 IHTMLWindow2(您可以通过索引 # 或名称选择帧),然后我转换帧的 .Document 成员到一个 IHTMLDocument2 (为了方便起见,最初使用的那个)。从那里开始,IHTMLDocument2 的 .all.tags() 方法在功能上与旧的 WebBrowser.Document.GetElementsByTagName() 方法相同,除了它需要 IHTMLElementCollection 而不是 HTMLElementCollection。然后,您可以 foreach 集合,需要 IHTMLElement 的单个元素,并使用 .getAttribute 来检索属性。请注意,g 是小写的。

于 2012-03-30T21:28:52.843 回答
0

WebBrowser 控件可以处理 NewWindow 事件,以便在 WebBrowser 中打开新的弹出窗口。

private void webBrowser1_NewWindow(object sender, CancelEventArgs e)
{
  // navigate current window to the url
  webBrowser1.Navigate(webBrowser1.StatusText);
  // cancel the new window opening
  e.Cancel = true;
}

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/361b6655-3145-4371-b92c-051c223518f2/

于 2012-03-21T17:51:56.593 回答
0

我见过的唯一解决方案是几年前的现在,称为 csExWb2,现在在 Google 代码

它为您提供了一个 ExWebBrowser 控件,但可以完全访问 IE 提供的所有界面和事件。我用它来对 Winforms 托管的 html 编辑器中的元素进行深入而肮脏的控制。

请注意,直接跳入其中可能有点跳跃。

于 2012-03-21T18:01:30.410 回答