代码之家  ›  专栏  ›  技术社区  ›  JimEvans

C#IE BHO:如何将DOM对象封送到工作线程?

  •  3
  • JimEvans  · 技术社区  · 14 年前

    Browser Helper Object (BHO)在C语言中,在一个单独的线程上操作DOM。我看到了其他几个与此相关的问题,答案似乎是“您需要将DOM对象从创建它们的线程封送到您的工作线程”。这是一个很好的建议,而且非常有意义,但是我找不到关于如何做到这一点的C示例。有一些模糊的指针指向一些需要使用的P/Invoke api,但是我很难看到如何将其实现到BHO中。

    我从示例中学到了最好的东西,而文档中却非常缺少这种东西的.NET示例。有人能给我举一个例子,在托管代码BHO的上下文中,DOM是通过工作线程操作的吗?

    1 回复  |  直到 14 年前
        1
  •  3
  •   Andy Hopper    14 年前

    你不应该执行任何人工编组;托管运行时代表您处理任何跨单元COM对象封送。

    举个例子;此示例托管BHO将等待DocumentComplete事件触发并启动ThreadPool后台线程,该线程将等待一秒钟,然后将页面标题更改为“Hello,StackOverflow!”并添加带有特殊消息的新文本节点:

    private void OnDocumentComplete(object frame, ref object urlObj)
    {
        System.Threading.ThreadPool.QueueUserWorkItem((o) =>
        {
            System.Threading.Thread.Sleep(1000);
                HTMLDocument document = (HTMLDocument)this.browser.Document;
                document.title = "Hello, StackOverflow!";
    
                IHTMLDOMNode greetings = document.createTextNode("Hi there!");
    
                IHTMLDOMNode body = document.body as IHTMLDOMNode;
                body.insertBefore(greetings, body.firstChild);                
        }, this.browser);
    }
    
    #region IObjectWithSite Members
    
    int IObjectWithSite.SetSite(object site)
    {
        if (site != null)
        {
            this.browser = (WebBrowser)site;
            this.browser.DocumentComplete +=
             new DWebBrowserEvents2_DocumentCompleteEventHandler(
              this.OnDocumentComplete);
        }
        else
        {
            if (this.browser != null)
            {
                this.browser.DocumentComplete -=
                 new DWebBrowserEvents2_DocumentCompleteEventHandler(
                  this.OnDocumentComplete);
                this.browser = null;
            }
        }
        return 0;
    }
    
    int IObjectWithSite.GetSite(ref Guid guid, out IntPtr ppvSite)
    {
        IntPtr punk = Marshal.GetIUnknownForObject(this.browser);
        int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
        Marshal.Release(punk);
    
        return hr;
    }
    
    #endregion
    
    推荐文章