I'm facing difficulties to get access to IE events (IDOMEvent) in the context of a Test Automation tool written in C# and running standalone (i.e.: The tool is not an IE plug-in). I can produce the problem with IE11 and web applications enforcing the IE=EDGE
compatibility mode via the HEAD meta-information:
<meta http-equiv="X-UA-Compatible" content="IE=EDGE">
I have created an EventSink class which registers for the "click" events at the body HTML element using the IEventTarget.addEventListener method:
public class EventSink : IDisposable, IReflect
{
private IEventTarget mm_eventTarget;
bool mm_attached = false;
public void Attach(IHTMLDocument2 observedDocument)
{
mm_eventTarget = observedDocument.body as IEventTarget;
//mm_eventTarget = observedDocument as IEventTarget;
if (mm_eventTarget != null)
{
mm_eventTarget.addEventListener("click", this, true); //Registration for click during the "capturing" phase
mm_attached = true;
}
}
...
}
The EventSink class implements the IReflect interface and thus gets called back in its IReflect.InvokeMember method when a mouse click occurs.
public class EventSink : IDisposable, IReflect
{
...
object IReflect.InvokeMember(string name,
BindingFlags invokeAttr,
Binder binder,
object target, object[] args,
ParameterModifier[] modifiers,
CultureInfo culture,
string[] namedParameters)
{
if ("[DISPID=0]" == name)
{
try
{
IHTMLElement bodyElement = args[0] as IHTMLElement;
IDOMEvent domEvent = args[1] as IDOMEvent; //<== This works properly - domEvent is not null!
IHTMLElement element = domEvent.target as IHTMLElement; //COM Exception here - DISP_E_MEMBERNOTFOUND
}
catch (Exception e)
{
Console.
}
}
return null;
}
The IReflect.InvokeMember method receives two arguments as described at:
https://msdn.microsoft.com/en-us/library/ie/ff975245%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
- The first one is the body HTML element
- The second one is supposed to be the IDOMEvent
The problem is that the C# class can't access to it. A COM exception occurs as soon as I manipulate the proxy to the DOM Event. Note that casting args[1] to IDomEvent works properly but afterwards all methods are triggering the same error:
==> "Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))
Here is the IDL definition of the IEventTarget and IDOMEvent interfaces that my project is using:
[Guid("305104B9-98B5-11CF-BB82-00AA00BDCE0B")]
[TypeLibType(4160)]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface IEventTarget
{
[DispId(-2147417602)]
void addEventListener(string type, object listener, bool useCapture);
[DispId(-2147417600)]
bool dispatchEvent(IDOMEvent evt);
[DispId(-2147417601)]
void removeEventListener(string type, object listener, bool useCapture);
}
[TypeLibType(4160)]
[Guid("305104BA-98B5-11CF-BB82-00AA00BDCE0B")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface IDOMEvent
{
[DispId(1001)]
bool bubbles { get; }
[DispId(1002)]
bool cancelable { get; }
[DispId(1014)]
bool cancelBubble { get; set; }
[DispId(1003)]
IEventTarget currentTarget { get; }
[DispId(1004)]
bool defaultPrevented { get; }
[DispId(1005)]
ushort eventPhase { get; }
[DispId(1013)]
bool isTrusted { get; }
[DispId(1015)]
IHTMLElement srcElement { get; }
[DispId(1006)]
IEventTarget target { get; }
[DispId(1007)]
ulong timeStamp { get; }
[DispId(1008)]
string type { get; }
[DispId(1009)]
void initEvent(string eventType, bool canBubble, bool cancelable);
[DispId(1010)]
void preventDefault();
[DispId(1012)]
void stopImmediatePropagation();
[DispId(1011)]
void stopPropagation();
}
Does anybody face the same difficulties?
Any ideas? Thanks so much!
Claude