Jump to content

Recommended Posts

Hello and happy new Year to everybody! :)

I'm trying to catch some events occuring within a browser control by simply using the ObjEvent() function.
I think I'm not using that function in a proper way since some events are captured, while other are not.

more precisely, events like those listed in this page are working:
https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx

while other events listed in other "interfaces", as in the following links, does not works.
https://msdn.microsoft.com/en-us/library/hh801967(v=vs.85).aspx

For exemple, Here I would like to catch events like "DragOver" and/or "Drop" fired while dragging the image on the web control, but I'm not been able to obtain a result.
Those events are listed in the HTMLDocumentEvents4 interface or also in the HTMLImgEvents interface, but I failed to use them.

Any hint that can help to see what I'm doing wrong, or even better that can show how to achieve the result by using the ObjEvent() function (if it's possible?) is welcome.
Thanks a lot.

Here is the simple script that I'm using for my tests:

#include <GUIConstantsEx.au3>
#include <string.au3>

; read html page from bottom of this script
; and write it to a file on disk for later
; usage by the $oIE.navigate
CreateHtmlPage()

Example()
Exit

Func Example()
    Local $hGUIMain = GUICreate("Event Test", 540, 400)

    ; We generate the Browser Control...
    Global $oIE = ObjCreate("Shell.Explorer.2")

    ; and we embed it into the AutoIt GUI
    $hIE = GUICtrlCreateObj($oIE, 5, 5, 530, 390)

    GUISetState() ;Show GUI

    ; load in the browser our previously created web page
    $oIE.navigate('file:///' & @ScriptDir & '\Page.html')

    Do ; wait for document
        Sleep(250)
        $oDocument = $oIE.document
    Until IsObj($oDocument)
    $oDocument.execCommand("Refresh")


    ; --- Setup catch of events ---

    Local $oEventObjects[2]
    $oImage = $oDocument.getElementById('drag1') ; Object reference to The image on the page

    ; https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx
    ; HTMLDocumentEvents2 interface (catch OnClick, OnMouseOver, .... etc

    ; ObjEvent() "Handles incoming events from the given Object."
    ;   ObjEvent($oParam1, $sParam2 [,$sParam3])
    ; Parameters
    ;               $oParam1 A variable containing an Object from which you want to receive events
    ;
    ;               $sParam2 The prefix of the functions you define to handle receiving events.
    ;                        The prefix is appended by the Objects method name.
    ;
    ;               $sParam3 "interface name" [optional] name of an Event interface to use.
    ;                        Note: It must be a supported as outgoing for the Object AND it must be of type DISPATCH.


    ; Using third parameter as "HTMLDocumentEvents2" as event interface, or even leaving it blank,
    ; is the only way by which I've been able to catch some events from the browser control

    ; OK, events listed here are catched --> https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx
    $oEventObjects[0] = ObjEvent($oDocument, "IEEvent2_") ;, "HTMLDocumentEvents2")

    ; when I try to catch events fired by the Image dragged on the web page
    ; following attempts do not work (no event is captured and passed to AutoIt)

    ; $oEventObjects[1] = ObjEvent($oDocument, "IEEvent2_", "HTMLDocumentEvents2")
    ; $oEventObjects[1] = ObjEvent($oDocument, "IEEvent2_", "HTMLDocumentEvents4")
    ; $oEventObjects[1] = ObjEvent($oImage, "IEEvent2_", "HTMLDocumentEvents2")
    ; $oEventObjects[1] = ObjEvent($oImage, "IEEvent2_")
    $oEventObjects[1] = ObjEvent($oImage, "IEEvent2_", "HTMLImgEvents2")
    ; -----------------------------

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    ; the end
    For $i = 0 To UBound($oEventObjects) - 1
        $oEventObjects[$i].Stop ; Tell IE we don't want to receive events.
        $oEventObjects[$i] = 0
    Next
    $oEventObject = 0 ; Kill the Event Object
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUIMain) ; Remove GUI
EndFunc   ;==>Example

; below function should be fired by events
; occurred in the browser's objects
; --- events management zone ---
Volatile Func IEEvent2_onClick($oEvent)
    ConsolePrint("mouse click:")
EndFunc   ;==>IEEvent2_onClick

Volatile Func IEEvent2_onDblClick($oEvent)
    ConsolePrint("mouse DoubleClick:")
EndFunc   ;==>IEEvent2_onDblClick

; Drag related events
Volatile Func IEEvent2_onDragstart($oEvent)
    ConsolePrint("Drag action started")
EndFunc   ;==>IEEvent2_onDragstart

; --- following events are not catched --- ???
Volatile Func IEEvent2_onDragOver($oEvent)
    ConsolePrint("DragOver event")
EndFunc   ;==>IEEvent2_onDragOver

Volatile Func IEEvent2_onDrop($oEvent)
    ConsolePrint("Drop action performed ")
EndFunc   ;==>IEEvent2_onDrop
; ------------------------------

Func ConsolePrint($sMsg)
    ConsoleWrite($sMsg & @CRLF)
EndFunc   ;==>ConsolePrint

Func CreateHtmlPage()
    Local $sStart = @LF & "#cs;HTML"
    Local $sEnd = "#ce;HTML" & @CR
    Local $aArray = _StringBetween(FileRead(@ScriptFullPath), $sStart, $sEnd)
    Local $sPage = @ScriptDir & '\Page.html'
    Local $hFile = FileOpen($sPage, 2) ;  $FO_OVERWRITE (2) = Write mode (erase previous contents)
    FileWrite($hFile, $aArray[0])
    FileFlush($hFile)
    FileClose($hFile)
EndFunc   ;==>CreateHtmlPage

; example got from here: http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_draganddrop2
#cs;HTML
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <style>
    #div1, #div2 {
    float: left;
    width: 214px;
    height: 214px;
    margin: 5px;
    padding: 10px;
    border: 1px solid black;
    }
    </style>
    <script>

    function allowDrop(ev) {ev.preventDefault();}

    function drag(ev)   {ev.dataTransfer.setData("text", ev.target.id);}

    function drop(ev)   {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    ev.target.appendChild(document.getElementById(data));}

    </script>
    </head>
    <body>

    <h2>Drag and Drop</h2>
    <p>Drag the image back and forth between the two div elements.</p>

    <div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">

    <img src="https://www.autoitscript.com/forum/uploads/monthly_2016_01/Chimp.jpg.688f81fa865450e2913b5dc2cb56215f.thumb.jpg.96a6bfa47c0fb8476f39aaf55ad68ed0.jpg"
    draggable="true" ondragstart="drag(event)" id="drag1" width="214" height="214">
    </div>

    <div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

    </body>
    </html>
#ce;HTML
;

 

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to post
Share on other sites

Hi,

What Follows works on systems with IE11 (doesn't works with IE9).
After further tests I've seen that:
If I want for example receive events from a DIV element, I have to pass to the ObjEvent() function an Object variable that points to that DIV,
But a strange "phenomenon" happens, that is:
If I get the Object reference to the DIV using this statement:

$oDiv1 = $oDocument.getElementById('div1')


The ObjEvent() function will not work,
while If I get the Object reference to that same DIV  by means of a reference to the global javascript object, then the ObjEvent() will work.

$oDiv1 = $ohJS.div1

.... this is strange because both ways used to get a reference to the DIV returns an object reference pointing to the same DIV (or in appearence it seems so).

anyway, the following listing works quite well and it can manage the events fired within the browser control directly in AutoIt.
Here the Drag&Drop of the Chimp picture is totally managed by AutoIt Functions.

Does someone knows why two Object variables, pointing to the same DIV, behave differently on the ObjEvent() function?

 

#include <GUIConstantsEx.au3>
#include <string.au3>
#include <file.au3>

Global $oDocument

Example()
Exit

Func Example()
    ; read html page from bottom of this script
    ; and write it to a temp file on disk for later
    ; usage by the $oIE.navigate
    Local $sFilename = CreateHtmlPage()

    Local $hGUIMain = GUICreate("Event Test", 540, 400)

    ; We generate the Browser Control...
    Global $oIE = ObjCreate("Shell.Explorer.2")

    ; and we embed it into the AutoIt GUI
    $hIE = GUICtrlCreateObj($oIE, 5, 5, 530, 390)

    GUISetState() ;Show GUI

    ; load in the browser the previously created web page
    $oIE.navigate('file:///' & $sFilename)

    Do ; wait for document
        Sleep(250)
        $oDocument = $oIE.document
    Until IsObj($oDocument)
    ; $oDocument.execCommand("Refresh")

    ; $ohJS is a reference to the javascript Global Obj
    ; JSglobal is a variable created within the HTML
    ; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
    ; -------------------------------------------------
    Global $ohJS = $oIE.document.parentwindow.JSglobal

    ; --- Setup catch of events ---

    ; The following array holds Handles returned by ObjEvent()
    ; (since this array is Local within a function, it will be
    ;  automatically destroyed when exiting from the function)
    Local $oEventObjects[3], $oDiv1, $oDiv2

    ; GETTING RFERENCE TO THE TARGET OBJ IN THIS WAY WILL NOT WORK
     $oDiv1 = $oDocument.getElementById('div1') ; Object reference to The DIV1 obj
     _ObjDescription($oDiv1, "refereced via $oDocument") ; show obj details just for debug
    ;  $oDiv2 = $oDocument.getElementById('div2') ; Object reference to The DIV2 obj

    ; GETTING RFERENCE IN THIS WAY WILL WORK INSTEAD (!!??) (don't ask me why.....)
     $oDiv1 = $ohJS.div1 ; Object reference to The DIV1 obj
     _ObjDescription($oDiv1, "refereced via $ohJS js gloaba obj") ; show obj details just for debug
     $oDiv2 = $ohJS.div2 ; Object reference to The DIV2 obj

    $oEventObjects[0] = ObjEvent($oDiv1, "IEEvent2_", "HTMLElementEvents2")
    _ObjDescription($oEventObjects[0], "ObjEvent for div1") ; show obj details just for debug
    $oEventObjects[1] = ObjEvent($oDiv2, "IEEvent2_", "HTMLElementEvents2")
    $oEventObjects[1] = ObjEvent($oDocument, "DocEvent2_", "HTMLDocumentEvents2")
    ; -----------------------------
    ConsoleWrite(@CR & @CR & @CR & "--- Events log ---" & @CR)
    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    ; the end
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUIMain) ; Remove GUI
    FileDelete($sFilename)
EndFunc   ;==>Example

; following function should be fired by events
; occurred in the browser's objects
;
; The function automatically called by an event
; will receive as parameter an Event Obj.
; This obj is loaded with many properties related to
; the object that fired the event. See following link:
; https://msdn.microsoft.com/en-us/library/aa703876(v=vs.85).aspx

; --- events management zone ---
Volatile Func DocEvent2_onClick($oEvent)
    ConsolePrint("mouse click on " & $oEvent.srcElement.NodeName) ; & " ID:" & $oEvent.srcElement.ID)
EndFunc   ;==>DocEvent2_onClick

Volatile Func DocEvent2_onDblClick($oEvent)
    ConsolePrint("mouse DoubleClick:")
EndFunc   ;==>DocEvent2_onDblClick

; Drag related events
Volatile Func IEEvent2_onDragstart($oEvent)
    ConsolePrint("Drag of element " & $oEvent.srcElement.ID & " started")
    ; we save the data that we want to send to the drop element int the "dataTransfer" object
    $oEvent.dataTransfer.setData("text", $oEvent.srcElement.ID)
EndFunc   ;==>IEEvent2_onDragstart

Volatile Func IEEvent2_onDragOver($oEvent)
    Local Static $iX, $iY
    ; ConsoleWrite("Cancelabe? " & $ohJS.event.cancelable & @CRLF)
    $ohJS.event.preventDefault()
    If $iX <> $oEvent.x Or $iY <> $oEvent.y Then
        ; remember previous position
        $iX = $oEvent.x
        $iY = $oEvent.y
        ConsolePrint( _
                "DragOver " & $oEvent.srcElement.NodeName & " ID: " & $oEvent.srcElement.ID & _
                ". mouse pos is X:" & $oEvent.x & " y:" & $oEvent.y)
    EndIf
EndFunc   ;==>IEEvent2_onDragOver

Volatile Func IEEvent2_onDrop($oEvent)
    ConsolePrint("Drop event on " & $oEvent.srcElement.ID & ".")
    $ohJS.event.preventDefault()
    If _
            ($oEvent.srcElement.ID = "div1" Or $oEvent.srcElement.ID = "div2") _
            And $oEvent.dataTransfer.getData("text") = "chimp" Then ; allowed only chimp dropped on div1 or div2
        ; we move the dragged element (the ID is into the 'dataTransfer' object) to the dropped target
        $oEvent.srcElement.appendChild($oDocument.getElementById($oEvent.dataTransfer.getData("text")))
        ConsolePrint( $oEvent.dataTransfer.getData("text") & " dropped.")
    Else
        ConsolePrint("Dropping '" & $oEvent.dataTransfer.getData("text") & "' is not allowed")
    EndIf
EndFunc   ;==>IEEvent2_onDrop
; ------------------------------

Func ConsolePrint($sMsg)
    ConsoleWrite($sMsg & @CRLF)
EndFunc   ;==>ConsolePrint

Func _ObjDescription(ByRef $oObj, $msg = "") ; for debug purpose
    ConsoleWrite('--Debug:----------------------------------------------------------------------------' & @CRLF & _
            "[" & $msg & "]" & @CRLF)
    If IsObj($oObj) Then
        ConsoleWrite( _
                'The name of the Object:.......................' & ObjName($oObj, $OBJ_NAME) & @CRLF & _
                'Description string of the Object:.............' & ObjName($oObj, $OBJ_STRING) & @CRLF & _
                'The ProgID of the Object:.....................' & ObjName($oObj, $OBJ_PROGID) & @CRLF & _
                'file associated with the obj in the Registry:.' & ObjName($oObj, $OBJ_FILE) & @CRLF & _
                'Module name in which the object runs:.........' & ObjName($oObj, $OBJ_MODULE) & @CRLF & _
                "CLSID of the object's coclass:................" & ObjName($oObj, $OBJ_CLSID) & @CRLF & _
                "IID of the object's interface:................" & ObjName($oObj, $OBJ_IID) & @CRLF)
    Else
        ConsoleWrite("Is not an object" & @CRLF)
    EndIf
EndFunc   ;==>_ObjDescription

Func CreateHtmlPage()
    Local $sStart = @LF & "#cs;HTML"
    Local $sEnd = "#ce;HTML" & @CR
    Local $aArray = _StringBetween(FileRead(@ScriptFullPath), $sStart, $sEnd)
    Local $sPage = _TempFile(@ScriptDir, Default, ".html")
    Local $hFile = FileOpen($sPage, 2) ;  $FO_OVERWRITE (2) = Write mode (erase previous contents)
    FileWrite($hFile, $aArray[0])
    FileFlush($hFile)
    FileClose($hFile)
    Return $sPage
EndFunc   ;==>CreateHtmlPage

#cs;HTML
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <script type="text/javascript">
    var JSglobal = (1,eval)("this");
    </script>
    <style>
    #div1, #div2 {
    float: left;
    width: 214px;
    height: 214px;
    margin: 5px;
    padding: 10px;
    border: 1px solid black;}
    </style>
    </head>
    <body>
    <h2>Drag and Drop</h2>
    <p>Drag the image back and forth between the two div elements.</p>
    <div id="div1">
    <img src="https://www.autoitscript.com/forum/uploads/monthly_2016_01/Chimp.jpg.688f81fa865450e2913b5dc2cb56215f.thumb.jpg.96a6bfa47c0fb8476f39aaf55ad68ed0.jpg"
    draggable="true" id="chimp" width="214" height="214">
    </div>
    <div id="div2"></div>
    </body>
    </html>
#ce;HTML
;

 

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Gianni
      (This example uses a "flash" animation and therefore needs the "flash player" to work. Since "flash player" is discontinued and no longer present on many systems, this script may not work. I have therefore prepared a new script which does not use flash, but is based only on javascript. You can find it in this new post: www.autoitscript.com/forum/topic/206853-aquarium)
      If you set within a window, a given color as transparent, every area of that window painted with that color, act as an hole through wich you can see what's behind, and click on what's behind as well.
      What's funny is that if you embed a browser control within that window, the "transparent" color works even within the browser! This allow some interesting effects by simply opening any of the many javascript animations, or css effects or whatever within a browser control embedded into a GUI:
      Here, for example, is a simple effect of fishes swimming around on the screen.
      For lazyness I have embedded an ready made swf flash by a link to the web, but is of course possible embed any web page with javascripts css or whatever.....
      Have fun
      #include <WinAPI.au3> #include <WindowsConstants.au3> #include <Misc.au3> ; for _IsPressed (23 END key) Local $hDLL = DllOpen("user32.dll"), $oIE = ObjCreate("Shell.Explorer.2") Local $hBackground = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUPWINDOW, $WS_EX_LAYERED + $WS_EX_TOPMOST) Local $AlphaKey = 0xF0F7FF ; everything with color $AlphaKey within this window will be transparent ; even if within an embedded browser control!..... _WinAPI_SetLayeredWindowAttributes($hBackground, $AlphaKey, 0, $LWA_COLORKEY) GUISetState(@SW_SHOW, $hBackground) $hIE = GUICtrlCreateObj($oIE, 0, 0, @DesktopWidth, @DesktopHeight) ; <- embedd $oIE in the AutoIt GUI GUISetBkColor($AlphaKey, $hBackground) ; $AlphaKey $hBackground transparent $oIE.navigate('http://cdn.abowman.com/widgets/fish/fish.swf') ; $oIE.navigate('http://cdn.abowman.com/widgets/spider/spider.swf') ; a spider goes around on the screen .... ; !! to use the spider.swf, you need to set $AlphaKey = 0xffffff on line 7 "! While True If _IsPressed("23", $hDLL) Then ExitLoop ; END key was pressed Sleep(250) WEnd $oIE = "" $hDLL = "" GUIDelete($hBackground)  
    • By Gianni
      This script is an alternative (improvement) to the script published at this link (www.autoitscript.com/forum/topic/186225-interesting-effect-with-transparency). In that post a flash animation was used and therefore you need the flash player to work, while here only javascript is used.
      Here, too, the aim is to show an interesting effect that can be obtained by exploiting transparency, but can also be used as it is just for fun.
      The animation consists of some fish wandering around the screen. You can continue working on the computer by letting them swim.
      The javascript source was not written by me, but I got it from this link: https://github.com/lrusso/Aquarium. I shrunk it down a bit and tweaked it so that fish can swim across the entire screen even with different sized monitors.
      The fish images and html and javascript sources have been bundled into a single "monolithic" AutoIt script, so it's easier to run.
      I hope you find it relaxing.
      Have fun
      fishMonolitic.zip
    • By tarretarretarre
      About AutoIt-Events
      AutoIt-Events is an event Observer and is a core dependency for Autoit-Socket-IO but can be used for any Autoit project.
      Example
      #include "Event.au3" ; Subscribe listeners _Event_Listen(UserCreatedEvent, SendWelcomeMail) _Event_Listen(UserCreatedEvent, RegisterNewsLetter) ; Fire event _Event(UserCreatedEvent, @UserName, "tarre.islam@gmail.com") Func UserCreatedEvent(Const ByRef $oEvent, $name, $email) ; via $oEvent you can pass data to its listeners $oEvent.add("name", $name) $oEvent.add("email", $email) $oEvent.add("id", 1) EndFunc Func SendWelcomeMail(Const $oEvent) MsgBox(64, "Welcome mail sent", "Welcome mail sent to " & $oEvent.item("name") & " with email " & $oEvent.item("email")) EndFunc Func RegisterNewsLetter(Const $oEvent) MsgBox(64, "News letter registred", "News letter bound to user id " & $oEvent.item("id")) EndFunc  
      The code is also available at Github
       
      Autoit-Events-1.0.0.zip
    • By tarretarretarre
      Version 2.x.x and 3.x.x has been moved to branch 3.x
      About Autoit-Socket-IO
      Autoit-Socket-IO is a event driven TCP/IP wrapper heavily inspired from Socket.IO with focus on user friendliness and long term sustainability.
      I constantly want to make this UDF faster and better, so if you have any suggestions or questions (beginner and advanced) Do not hesitate to ask them, I will gladly help!
      Key features
      Simple API 99% data-type serialization thanks to Autoit-Serialize Can easily be extended with your own functionality thanks to Autoit-Events "Educational" examples Data encryption thanks to _<Crypt.au3> Limitations
      Speed. This UDF will sacrifice some speed for convenience Getting started
      Download the script from AutoIt or pull it from the official github repo git@github.com:tarreislam/Autoit-Socket-IO.git and checkout the tag 4.0.0-beta Check out the documentaion Take a look in the examples/ folder Changelog
      To see changes from 3.x.x and 2.x.x please checkout the 3.x branch
      Version 4.0.0-beta (This update break scripts.)
      Code base fully rewritten with Autoit-Events and decoupled to improve code quality and reduce bloat. The new UDF is very different from 3.x.x so please checkout the UPGRADE guide to fully understand all changes Added new documentation documentaion Success stories
      Since December 2017-now I have used version 1.5.0 in an production environment for 150+ clients with great success, the only downtime is planned windows updates and power outages.
       
      Newest version (2020-09-15!)

       
      Older versions (Not supported anymore)
      Autoit-Socket-IO-1.0.0.zip Autoit-Socket-IO-1.1.0.zip Autoit-Socket-IO-1.3.0.zip Autoit-Socket-IO-1.4.0.zip Autoit-Socket-IO-1.5.0.zip
      Autoit-Socket-IO-2.0.0.zip
    • By Yodavish
      I have this AutoIt script that works on Windows 7. However, when I test it on Windows 10, the objEvent will not execute the function it's supposed to call. So I have a webpage the script will check if it is active, then it will search if a popup button exist (elementId), if so, assign it to the event handler so that when that button is clicked, then handler function will move the focus back to the main GUI again.
      If WinActive("Website Title - Internet Explorer") Then    $ie = _IEAttach("Website Title")    $objElement= _IEGetObjById ($ie, "elementId")    local $oEvent = ObjEvent($objElement, "_MY_EVENT_HANDLER_") EndIf Func _MY_EVENT_HANDLER_onclick($oEvtObj)     msgbox(0,"Alert Window", "Button Clicked!") setMainWindow() ; sets focus back to main GUI EndFunc  
      I've verified, on Windows 10, that it does see the object element. But it will not trigger the event. Could it be related to some timing issues due to Windows 10 Internet Explorer over Windows 7 Internet Explorer? 
      Windows 7 IE version 11.0.9600.19507
      Windows 10 IE version 11.418.18362.0
      AutoIt v 3.3
       
×
×
  • Create New...