How to access missing/hidden HTMLDocumentEvents4 events (onchange event) or attach event listeners to element

715 views Asked by At

In MSHTML interface HTMLDocumentEvents4 should contain around 30 events (as per msdn page http://msdn.microsoft.com/en-us/library/ff976251(v=vs.85).aspx#events) but only onmssitemodejumplistitemremoved and onmsthumbnailclick are available I want to access other events..especially change event.. How to access those other events

using System.Runtime.InteropServices;
namespace MSHTML
{
 [ComVisible(false)]
 [TypeLibType(TypeLibTypeFlags.FHidden)]
 public interface HTMLDocumentEvents4_Event
 {
     event HTMLDocumentEvents4_onmssitemodejumplistitemremovedEventHandler onmssitemodejumplistitemremoved;
     event HTMLDocumentEvents4_onmsthumbnailclickEventHandler onmsthumbnailclick;
 }
}

In my code I tried to access like following but it is not working(listener not assigned)

//Event handler class
public delegate void DHTMLEvent(IHTMLEventObj e);

[ComVisible(true)]
public class DHTMLEventHandler
{

    public DHTMLEvent Handler;
    HTMLDocument Document;

    public DHTMLEventHandler(HTMLDocument doc)
    {
        this.Document = doc;
    }
    [DispId(0)]
    public void Call()
    {
        Handler(Document.parentWindow.@event);
    }


}

    //My code
        HTMLDocumentEvents2_Event Events = (HTMLDocumentEvents2_Event)document;
        Events.onclick += new HTMLDocumentEvents2_onclickEventHandler(Events_onclick);//working

         HTMLDocumentEvents4_Event Events2 = (HTMLDocumentEvents4_Event)document;
    //   Events2.change ->Not availabe so  as a workaround I did the below but that is also not      //     working

        DHTMLEventHandler onchangeHandler = new DHTMLEventHandler(document);
        onchangeHandler.Handler += new DHTMLEvent(Events_onchange);
        document.attachEvent("onchange", onchangeHandler);  //Not working
        document.onchange = onchangeHandler;                //Not Working

     private void Events_onchange(IHTMLEventObj e)
    {
        //I want to do my operation here but this is not called as listener is not assigned
    }

     private Boolean Events_onclick(IHTMLEventObj e)
    {
      //working perfectly 
     }

So I want to listen the onchange event either by custom methods or by using HTMLDocumentEvents4 interface's hidden event..Help me

1

There are 1 answers

0
Madhan On BEST ANSWER

I got a workaround for how to attach event listeners to element
1.create HTMLHandlerClass for attaching eventhandlers to element
2.get all the elements from document or the elements for which you want to attach listener
3.cast the element as IHTMLElement2
4.attach the eventlistener by calling element.attachEvent

Step 1

using MSHTML;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;

namespace IEToolbarEngine
{
class HtmlHandler : IReflect
{
    public HtmlHandler(EventHandler evHandler, IHTMLWindow2 sourceWindow)
    {
        this.eventHandler = evHandler;
        this.htmlWindow = sourceWindow;
    }

    public IHTMLWindow2 SourceHTMLWindow
    {
        get { return this.htmlWindow; }
    }

    #region IReflect

    FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr)
    {
        return this.typeIReflectImplementation.GetField(name, bindingAttr);
    }

    FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr)
    {
        return this.typeIReflectImplementation.GetFields(bindingAttr);
    }

    MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr)
    {
        return this.typeIReflectImplementation.GetMember(name, bindingAttr);
    }

    MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr)
    {
        return this.typeIReflectImplementation.GetMembers(bindingAttr);
    }

    MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr)
    {
        return this.typeIReflectImplementation.GetMethod(name, bindingAttr);
    }

    MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
    {
        return this.typeIReflectImplementation.GetMethod(name, bindingAttr, binder, types, modifiers);
    }

    MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr)
    {
        return this.typeIReflectImplementation.GetMethods(bindingAttr);
    }

    PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr)
    {
        return this.typeIReflectImplementation.GetProperties(bindingAttr);
    }

    PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr)
    {
        return this.typeIReflectImplementation.GetProperty(name, bindingAttr);
    }

    PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
    {
        return this.typeIReflectImplementation.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
    }

    object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
    {
        if (name == "[DISPID=0]")
        {
            if (this.eventHandler != null)
            {
                this.eventHandler(this, EventArgs.Empty);
            }
        }

        return null;
    }

    Type IReflect.UnderlyingSystemType
    {
        get
        {
            return this.typeIReflectImplementation.UnderlyingSystemType;
        }
    }

    #endregion


    private IReflect typeIReflectImplementation = typeof(HtmlHandler);
    private EventHandler eventHandler;
    private IHTMLWindow2 htmlWindow;
}
}

Step 2
Here i'm getting all the input elements as i want to attach onchange event listener

 private void attachOnChangeEvent(HTMLDocument doc, Boolean flag)
    {
        // Install onchange for <input type=password, text, file>.

        IHTMLElementCollection inputElementList = doc.getElementsByTagName("input");
        foreach (IHTMLElement el in inputElementList)
        {
            String inputType = el.getAttribute("type") as String;
            if (("text" == inputType) || ("password" == inputType) || ("file" == inputType))
            {
                IHTMLElement2 inputElement = el as IHTMLElement2;
                IHTMLWindow2 wnd = (el.document as IHTMLDocument2).parentWindow;
                inputElement.attachEvent("onchange", new HtmlHandler(onchangeInput, wnd));

            }

        }
   }


  private void onchangeInput(object sender, EventArgs e)
    {
        HtmlHandler htmlHandler = (HtmlHandler)sender;
        IHTMLElement element = [email protected];

      //Do whatever i want with the element

    }