How to make SHDocVw.InternetExplorer fire events that get caught with JS addEventListener?

291 views Asked by At

The following problems:

  • I need to simulate a double-click on a div element.
  • I need to use/handle MS Internet Explorer 11.
  • I cannot change the source code of the target site.

My solution so far:

  • I use C# and SHDocVw.InternetExplorer and mshtml
  • I can fire "click" events al right, they show up in all handlers
  • When trying to simulate the double-click:
    • the "ondoubleclick" event gets triggered.
    • the el.addEventListener('dblclick', handler); does NOT get triggered

To reduce the complexity of the actual problem site, I have created this HTML code that simulates the problem, too:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>csi dbclick event handler</title>
    </head>
    <body>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <div 
            id="baba" 
            style="position: absolute; left: 80px; width: 100px; border: 2px solid green;"
            onclick="console.log('onclick');"
            ondblclick="console.log('ondblclick');"
            >
            GOODBYE!
        </div>
    </body>
    
    <script>
        function printEvent(pEvent1, pEvent2, pEvent3) {
            console.log("New Event: " + pEvent1);
            console.log(pEvent1);
            console.log("Timestamp: " + pEvent1.timeStamp);
        }
        
        const el = document.getElementById('baba');
        el.addEventListener('click', printEvent);       
        el.addEventListener('dblclick', printEvent);        
    </script>
</html>

My C# code is such:

InternetExplorer ie = new InternetExplorer();
HTMLDocument doc = (HTMLDocument) ie.Document;
IHTMLElement el = doc.getElementById("baba");
el.click();
Thread.Sleep(130);
el.click();
Thread.Sleep(5);

IHTMLEventObj eo3 = new MyEvent(el, "dblclick"); // class that extends IHTMLObject, returns values like a mouse click I logged from IE11 earlier, only type is adjusted
IHTMLElement3 el3 = (IHTMLElement3)el;
el3.FireEvent("ondblclick", eo3);

and my event class (which may not be needed at all):

class MyEvent : IHTMLEventObj {
    private readonly IHTMLElement mElement;
    private readonly String mType;
    public MyEvent(IHTMLElement pElement, String pType) {
        mElement = pElement;
        mType = pType;
    }
    bool IHTMLEventObj.altKey { get { return false; } }
    int IHTMLEventObj.button { get { return 0; } }
    bool IHTMLEventObj.cancelBubble { get { return false; } set { } }
    int IHTMLEventObj.clientX { get { return 85; } }
    int IHTMLEventObj.clientY { get { return 130; } }
    bool IHTMLEventObj.ctrlKey { get { return false; } }
    IHTMLElement IHTMLEventObj.fromElement { get { return null; } }
    int IHTMLEventObj.keyCode { get { return 0; } set { } }
    int IHTMLEventObj.offsetX { get { return 3; } }
    int IHTMLEventObj.offsetY { get { return 7; } }
    string IHTMLEventObj.qualifier { get { return "baba"; } }
    int IHTMLEventObj.reason { get { return 0; } }
    object IHTMLEventObj.returnValue { get { return null; } set { } }
    int IHTMLEventObj.screenX { get { return 353; } }
    int IHTMLEventObj.screenY { get { return 305; } }
    bool IHTMLEventObj.shiftKey { get { return false; } }
    IHTMLElement IHTMLEventObj.srcElement { get { return mElement; } }
    object IHTMLEventObj.srcFilter { get { return mElement; } }
    IHTMLElement IHTMLEventObj.toElement { get { return mElement; } }
    string IHTMLEventObj.type { get { return mType; } }
    int IHTMLEventObj.x { get { return 85; } }
    int IHTMLEventObj.y { get { return 127; } }
}

When running the code, I get these results:

onclick
New Event: [object PointerEvent]
[object PointerEvent]
   {
      [functions]: ,
      __proto__: { },
      altKey: false,
      AT_TARGET: 2,
      bubbles: true,
      BUBBLING_PHASE: 3,
      button: 0,
      buttons: 0,
      cancelable: true,
      cancelBubble: false,
      CAPTURING_PHASE: 1,
      clientX: -396.3999938964844,
      clientY: -146.84999084472656,
      constructor: { },
      ctrlKey: false,
      currentTarget: { },
      defaultPrevented: false,
      detail: 0,
      deviceSessionId: 0,
      eventPhase: 2,
      fromElement: null,
      height: 0,
      hwTimestamp: 0,
      isPrimary: false,
      isTrusted: true,
      layerX: -396.3999938964844,
      layerY: -146.84999084472656,
      metaKey: false,
      offsetX: -478.3999938964844,
      offsetY: -267.25,
      pageX: -396.3999938964844,
      pageY: -146.84999084472656,
      pointerId: 0,
      pointerType: "",
      pressure: 0,
      relatedTarget: null,
      rotation: 0,
      screenX: 0,
      screenY: 0,
      shiftKey: false,
      srcElement: { },
      target: { },
      tiltX: 0,
      tiltY: 0,
      timeStamp: 1612115536885,
      toElement: null,
      type: "click",
      view: { },
      which: 1,
      width: 0,
      x: -396.3999938964844,
      y: -146.84999084472656
   }

Timestamp: 1612115536885
onclick
New Event: [object PointerEvent]
[object PointerEvent]
   {
      [functions]: ,
      __proto__: { },
      altKey: false,
      AT_TARGET: 2,
      bubbles: true,
      BUBBLING_PHASE: 3,
      button: 0,
      buttons: 0,
      cancelable: true,
      cancelBubble: false,
      CAPTURING_PHASE: 1,
      clientX: -396.3999938964844,
      clientY: -146.84999084472656,
      constructor: { },
      ctrlKey: false,
      currentTarget: { },
      defaultPrevented: false,
      detail: 0,
      deviceSessionId: 0,
      eventPhase: 2,
      fromElement: null,
      height: 0,
      hwTimestamp: 0,
      isPrimary: false,
      isTrusted: true,
      layerX: -396.3999938964844,
      layerY: -146.84999084472656,
      metaKey: false,
      offsetX: -478.3999938964844,
      offsetY: -267.25,
      pageX: -396.3999938964844,
      pageY: -146.84999084472656,
      pointerId: 0,
      pointerType: "",
      pressure: 0,
      relatedTarget: null,
      rotation: 0,
      screenX: 0,
      screenY: 0,
      shiftKey: false,
      srcElement: { },
      target: { },
      tiltX: 0,
      tiltY: 0,
      timeStamp: 1612115537021,
      toElement: null,
      type: "click",
      view: { },
      which: 1,
      width: 0,
      x: -396.3999938964844,
      y: -146.84999084472656
   }

Timestamp: 1612115537021
ondblclick

As you see, the click events all arrive (onclick, click, onclick, click, ondblclick) , but the addEventListener('dblclick', ...) does not. Should be (onclick, click, onclick, click, ondblclick, dblclick) in the end. Any ideas how I can accomplish this?

My other solution would be to hijack the mouse and simulate a 'real' click-click, but that's too hackish for my taste.

1

There are 1 answers

3
Michael Navara On BEST ANSWER

I'm not familiar with SHDocVw.InternetExplorer, but is it possible use something like this? According to this post

How do I double-click on objects using javascript? Do I have to .click() twice?

Sorry when my answer is off topic.

void setupDblClick(HTMLDocument doc)
{
    string setupScriptJs = "window.baba_dblclick = function(){" +
                               "var targLink = document.getElementById ('baba');" +
                               "var clickEvent  = document.createEvent ('MouseEvents');" +
                               "clickEvent.initEvent ('dblclick', true, true);" +
                               "targLink.dispatchEvent (clickEvent);}";

    doc.parentWindow.execScript(setupScriptJs);
}

void dblClick(HTMLDocument doc)
{
    string dblclickScriptJs = "window.baba_dblclick()";

    doc.parentWindow.execScript(dblclickScriptJs);

}