C # IE BHO: Как мне маршалировать объекты DOM в рабочий поток? - PullRequest
3 голосов
/ 24 июня 2010

Я пытаюсь написать Browser Helper Object (BHO) на C #, который управляет DOM в отдельном потоке. Я видел несколько других вопросов, связанных с этим, и ответ, по-видимому, звучит так: «Вам нужно перенаправить объекты DOM из потока, в котором они были созданы, в ваш рабочий поток». Хороший совет, и он имеет смысл, но я не могу найти примеров C #, как это сделать. Есть некоторые расплывчатые указатели на некоторые P / Invoke API, которые необходимо использовать, но мне трудно понять, как реализовать это в BHO.

Я учусь лучше всего на примере, а в документации крайне не хватает .NET-примеров такого рода вещей. Может кто-нибудь указать мне пример, где в контексте управляемого кода BHO DOM манипулирует через рабочий поток?

1 Ответ

3 голосов
/ 22 июля 2010

Вам не нужно выполнять какой-либо ручной маршалинг; управляемая среда выполнения обрабатывает любые маршалинг 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
...