3

別のスレッドで DOM を操作するブラウザ ヘルパー オブジェクト(BHO) を C# で記述しようとしています。これに関連する他のいくつかの質問を見たことがありますが、その答えは「作成されたスレッドからワーカー スレッドに DOM オブジェクトをマーシャリングする必要がある」と思われます。良いアドバイスです。完全に理にかなっていますが、これを行う方法に関する C# の例は見つかりません。使用する必要のある P/Invoke API へのあいまいなポインタがいくつかありますが、それを BHO に実装する方法を理解するのは困難です。

私は例から学ぶのが一番ですが、ドキュメントには、この種の .NET の例がひどく不足しています。マネージ コード BHO のコンテキスト内で、ワーカー スレッドを介して DOM が操作される例を教えてもらえますか?

4

1 に答える 1

3

手動でマーシャリングを行う必要はありません。マネージド ランタイムは、ユーザーに代わってアパートメント間の COM オブジェクト マーシャリングを処理します。

以下に例を示します。このサンプル マネージ BHO は、DocumentComplete イベントが発生するまで待機し、ThreadPool バックグラウンド スレッドを起動します。このスレッドは 1 秒間待機してから、ページのタイトルを「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
于 2010-07-22T18:08:25.393 に答える