MSHTML event handling in a BHO

MSHTML event handling in a BHO

Post by jwalliso » Tue, 27 May 2003 08:44:50



I have implemented a browser helper object in C#/Framework 1.1 that uses MSHTML to manipulate/display the DOM.  The code works great for MY event handlers, but the original behaviors for the document disappear when my event handlers are added..

The problem I am experiencing seems to indicate that the "+=" MulticastDelegate event handling syntax functions strictly as an "operator =", rather than an "add", because, when I use the following code, any existing keyboard or mouse processing goes south - link onclick handling does not function, the mouse can't be used to set the focus to an INPUT field, etc.

/// <summary>
/// Called once for each frame in IE when the document has finished downloading.
/// NOTE: MSDN states this Property does not fire if "visible" set to "false"
/// </summary>
/// <param name="pDisp">Object that specifies the top-level or frame WebBrowser object corresponding to the event</param>
/// <param name="rURL">String that specifies the URL, Universal Naming Convention (UNC) file name, or pointer to an item identifier list (PIDL) of the loaded document.</param>

void OnDocumentComplete( Object pDisp, ref Object rURL)
{

    ...
    InitializeEvents()
    ...

Quote:}

/// <summary>
/// Establish (and save) the interface to the HTML document after it is loaded and hookup new event handlers
/// </summary>
/// <returns>true if document events were registered</returns>

internal bool InitializeEvents()
{

  bool bRet = false;

  try
  {

    mshtml.IHTMLDocument3 IHTMLDocument3 = (mshtml.IHTMLDocument3)m_IExplorer.Document;
    mshtml.IHTMLElement element = IHTMLDocument3.documentElement;
    // if the event interface is not stored, it appears to get GC'd, and events are no longer handled!!
    m_evtIntfc = (mshtml.HTMLElementEvents2_Event)element;

    m_MouseMoveHandler = new mshtml.HTMLElementEvents2_onmousemoveEventHandler(this.OnMouseMove);
    m_evtIntfc.onmousemove += m_MouseMoveHandler;

    ... other event handlers ...

    bRet = true;

  }

  catch (Exception e)
  {

    MessageBox.Show ( "EXCEPTION: \"" + e.Message + "\"", "Collimator",

          MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

  }

  m_DisplayInfo.Enable(bRet);    // update display status

  return bRet;

Quote:}

Long story short, to get the web page to process "normally" again in IE, I have to "unhook" the events (using "-=" syntax).  Once I do this, the page behaves "normally" again.

Does anyone have a clue WHY a MulticastDelegate would behave like this, and/or a solution to allow MY events to be added to the default event processing behavior of the document?

--
Regards,

Jim Allison

(de-mung by removing '.1')

 
 
 

MSHTML event handling in a BHO

Post by jwalliso » Tue, 27 May 2003 21:54:32


BTW - I have researched this item on Google, etc. and have found several recent references to the same issue, but nothing that looks like a solution (or an explanation).  

I have seen code that implements "workarounds" by going the down-and-dirty COM approach to solve problems that aren't really problems (such as event handling disappearing because your event interface has been GC'd because it isn't referenced in managed code), and I'm wondering if this is a similar conceptual, rather than MS code, problem .

If not, it would seem that the MSHTML RCW has some issues?


  I have implemented a browser helper object in C#/Framework 1.1 that uses MSHTML to manipulate/display the DOM.  The code works great for MY event handlers, but the original behaviors for the document disappear when my event handlers are added..

  The problem I am experiencing seems to indicate that the "+=" MulticastDelegate event handling syntax functions strictly as an "operator =", rather than an "add", because, when I use the following code, any existing keyboard or mouse processing goes south - link onclick handling does not function, the mouse can't be used to set the focus to an INPUT field, etc.

  /// <summary>
  /// Called once for each frame in IE when the document has finished downloading.
  /// NOTE: MSDN states this Property does not fire if "visible" set to "false"
  /// </summary>
  /// <param name="pDisp">Object that specifies the top-level or frame WebBrowser object corresponding to the event</param>
  /// <param name="rURL">String that specifies the URL, Universal Naming Convention (UNC) file name, or pointer to an item identifier list (PIDL) of the loaded document.</param>

  void OnDocumentComplete( Object pDisp, ref Object rURL)
  {

      ...
      InitializeEvents()
      ...

  }

  /// <summary>
  /// Establish (and save) the interface to the HTML document after it is loaded and hookup new event handlers
  /// </summary>
  /// <returns>true if document events were registered</returns>

  internal bool InitializeEvents()
  {

    bool bRet = false;

    try
    {

      mshtml.IHTMLDocument3 IHTMLDocument3 = (mshtml.IHTMLDocument3)m_IExplorer.Document;
      mshtml.IHTMLElement element = IHTMLDocument3.documentElement;
      // if the event interface is not stored, it appears to get GC'd, and events are no longer handled!!
      m_evtIntfc = (mshtml.HTMLElementEvents2_Event)element;

      m_MouseMoveHandler = new mshtml.HTMLElementEvents2_onmousemoveEventHandler(this.OnMouseMove);
      m_evtIntfc.onmousemove += m_MouseMoveHandler;

      ... other event handlers ...

      bRet = true;

    }

    catch (Exception e)
    {

      MessageBox.Show ( "EXCEPTION: \"" + e.Message + "\"", "Collimator",

            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

    }

    m_DisplayInfo.Enable(bRet);    // update display status

    return bRet;

  }

  Long story short, to get the web page to process "normally" again in IE, I have to "unhook" the events (using "-=" syntax).  Once I do this, the page behaves "normally" again.

  Does anyone have a clue WHY a MulticastDelegate would behave like this, and/or a solution to allow MY events to be added to the default event processing behavior of the document?

  --
  Regards,

  Jim Allison

  (de-mung by removing '.1')