Chimp

how to capture some events from a javascript (custom) object?

11 posts in this topic

Hi to all, in this script I'm using a Javascript library called VIS to display data on a timeline. All is performed within a browser control embedded in the AutoIt GUI, and the AutoIt script should interact with what is going on in the browser control.
what I'm stuck on is on finding a way to get notified in the AutoIt script on some events fired from that javascript library.

When I use the ObjEvent()  to get notified about events fired by html elements from the html page, all works ok...
I'm stuck instead on how to receive notifications from events fired by a javascript (custom?) object. The DataSet object.

in very short:
To add, edit or remove Items on the Timeline, first a DataSet is created and bound to the Timeline, then all variations performed on the DataSet will be automatically visualized in the form of Items located on the Timeline. All variations on the DataSet will also fire events. (use the button to create new items from autoit, or doubbleclick on the timeline to also create new items by the javascript library)

now my problem is:
since the DataSet is setted to fire events anytime some data in the DatSet is added and/or changed and/or deleted, i would like to be notified about such events in my AutoIt program, but I've not achieved the goal so far.

In this example the events generated by the DataSet are notified within the HTML page and displayed within the browser control, but not forwarded to AutoIt.

Any help to achieve this goal is higly appreciated.
Thanks

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <string.au3>
#include <array.au3>
Global $g_idGUIEdit

 ; read html page from bottom of this script
 ; and write it to a file on disk
CreateHtmlPage()

Example()
Exit

Func Example()
    Local $hGUIMain = GUICreate("Event Test", 1000, 600)
    $g_idGUIEdit = GUICtrlCreateEdit("", 500, 405, 490, 175)
    GUICtrlSetFont(-1, 9, 400, -1, 'Courier New')
    GUICtrlCreateLabel("Below are some Browser events 'captured' from the above web page by AutoIt", 500, 385, 990, 20)
    Local $idGUIExit = GUICtrlCreateButton(" Close and exit", 5, 580, 990, 15)

    Local $hButton1 = GUICtrlCreateButton("Add an Item to timeline", 10, 400, 150, 40)
    GUISetState() ;Show GUI

    ; We prepare the Internet Explorer as our test subject
    Global $oIE = ObjCreate("Shell.Explorer.2")
    $hIE = GUICtrlCreateObj($oIE, 5, 5, 990, 380) ; <- embedd $oIE in the AutoIt GUI

    ; load our web page, javascript and css in the browser
    ToolTip("...downloading javascript, please wait")
    $oIE.navigate('file:///' & @ScriptDir & '\Page.html')
    Sleep(1000) ; Give it some time to load the web page
    ToolTip("")

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

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

    ; --- Setup catch of events ---

    ;   https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx
    ;   HTMLDocumentEvents2 interface (catch OnClick, OnMouseOver, .... etc
    Global $oEventObject = ObjEvent($oDocument, "IEEvent2_", "HTMLDocumentEvents2") ; OK, this events are catched

    ; Attempt to catch events fired by the DataSet.
    ; items is the DataSet obj created in the Browser
    ; Global $oEventObject = ObjEvent($ohJS.items, "OnDataSet_") ; ???? how to catch events from the DataSet <---- ?????

    ; -----------------------------

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

            Case $hButton1
                ; add a job to the timeline (a simple example just to test)
                ; to generate a unique ID I use the following: @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC
                Local $result = $ohJS.eval("items.add([{id: " & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC & ", content: '<b>item 4</b> Added at " & @HOUR & ":" & @MIN & ":" & @SEC & " ', start: '2014-01-19'}]);")
                ConsoleWrite("DataSet now contains " & $ohJS.items.length & " Items" & @CRLF)

        EndSwitch
    WEnd

    ; the end
    $oEventObject.Stop ; Tell IE we don't want to receive events.
    $oEventObject = 0 ; Kill the Event Object
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUIMain) ; Remove GUI
EndFunc   ;==>Example

; --- event management zone ---
; A few Internet Explorer Event Functions
; below function are fired by events occurred in the browser
Volatile Func IEEvent2_onClick($oEvent)
    ConsolePrint("mouse click: " & $oEvent.clientX & ',' & $oEvent.clientY & '  on ' & $oEvent.srcElement.NodeName & '  - ' & $oEvent.srcElement.ID)
EndFunc   ;==>IEEvent2_onClick

Volatile Func IEEvent2_onDblClick($oEvent)
    ConsolePrint("mouse DoubleClick: @" & $oEvent.clientX & ',' & $oEvent.clientY)
EndFunc   ;==>IEEvent2_onDblClick

Volatile Func OnDataSet_add($oEvent)
    ConsolePrint("!!!! event from DataSet " & IsObj($oEvent)) ; type
EndFunc   ;==>OnDataSet_add

Func ConsolePrint($sMsg)
    Local Const $iMaxLines = 9 ; keep last 12 lines only
    $sMsg = @HOUR & ':' & @MIN & ':' & @SEC & ':' & @MSEC & @TAB & $sMsg & @CRLF
    $sMsg = StringReplace(GUICtrlRead($g_idGUIEdit) & $sMsg, @CR, @CR)
    If @extended > $iMaxLines Then ; more than $iMaxLines
        $sMsg = StringMid($sMsg, StringInStr($sMsg, @CR, 0, -1 * $iMaxLines) + 2)
    EndIf
    GUICtrlSetData($g_idGUIEdit, $sMsg)
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

#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 type="text/css">
    body, html {
    font-family: arial, sans-serif;
    font-size: 11pt;
    }
    </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.css" rel="stylesheet" type="text/css" />
    </head>
    <body>

    <div id="visualization" style="border-width:3px; border-color:yellow; border-style:double;"></div>
    <p></p>
    <div id="log"></div>

    <script type="text/javascript">
    // DOM element where the Timeline will be attached
    var container = document.getElementById('visualization');

    // Create an empty DataSet (allows two way data-binding)
    var items = new vis.DataSet({type: { start: 'ISODate', end: 'ISODate', notes: '' }});

    // items.addEventListener('click',resetElements,true);

    // add items to the DataSet
    items.add([
    {id: 1, content: 'item 1 <b>start</b>', start: '2014-01-23'},
    {id: 2, content: 'item 2', start: '2014-01-18 00:00', end: '2014-01-18 23:59'},
    {id: 3, content: 'item 3', start: '2014-01-21'},
    {id: 5, content: 'item 5', start: '2014-01-28', type:'point'},
    {id: 6, content: 'item 6', start: '2014-01-26'}
    ]);

    // Configuration for the Timeline
    var options = {orientation: 'top',
    editable: {
    add: true,
    remove: true,
    updateTime: true,
    updateGroup: true
    }
    };

    // Create a Timeline
    var timeline = new vis.Timeline(container, items, options);

    // turn events on
    timeline.on('rangechange', function (properties) {
    logEvent('rangechange', properties);
    });
    timeline.on('rangechanged', function (properties) {
    logEvent('rangechanged', properties);
    });
    timeline.on('select', function (properties) {
    logEvent('select', properties);
    });

    items.on('*', function (event, properties) {
    logEvent(event, properties);
    });

    function logEvent(event, properties) {
    var log = document.getElementById('log');
    var msg = document.createElement('div');
    msg.innerHTML = 'event=' + JSON.stringify(event) + ', ' +
    'properties=' + JSON.stringify(properties);
    log.firstChild ? log.insertBefore(msg, log.firstChild) : log.appendChild(msg);
    }
    </script>
    </body>
    </html>
#ce;HTML
;

 


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

Share this post


Link to post
Share on other sites



I would suggest creating a object with AutoItObject UDF, adding the autoit functions to it, and you can call them from the javascript.

Share this post


Link to post
Share on other sites

Hi @genius257 thanks for answering,
... I'm afraid I don't get your hint, all the needed objects are already created in the Browser Control, what I'm trying to achieve is a way to receive notifications about events fired by the javascript DataSet object, hopefully simply using the ObjEvent() function in a "correct" way (it's what I'm not been able)
 could you please elaborate on your hint?


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

Share this post


Link to post
Share on other sites
2 hours ago, Chimp said:

Hi @genius257 thanks for answering,
... I'm afraid I don't get your hint, all the needed objects are already created in the Browser Control, what I'm trying to achieve is a way to receive notifications about events fired by the javascript DataSet object, hopefully simply using the ObjEvent() function in a "correct" way (it's what I'm not been able)
 could you please elaborate on your hint?

Hi @Chimp.

No i would say not all object are created, at least not if you want to push JS notifications to AutoIt. Below is your code, and I've added functionality to run AutoIt function instead of your js function named "logEvent".

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <string.au3>
#include <array.au3>
Global $g_idGUIEdit

#include <AutoItObject.au3>
Func logEvent($oThis, $event, $properties)
    #forcedef $ohJS
    MsgBox(0, "AutoIt function logEvent", "event=" & $ohJS.JSON.stringify($event) & ", properties=" & $ohJS.JSON.stringify($properties))
EndFunc

 ; read html page from bottom of this script
 ; and write it to a file on disk
CreateHtmlPage()

Example()
Exit

Func Example()
    Local $hGUIMain = GUICreate("Event Test", 1000, 600)
    $g_idGUIEdit = GUICtrlCreateEdit("", 500, 405, 490, 175)
    GUICtrlSetFont(-1, 9, 400, -1, 'Courier New')
    GUICtrlCreateLabel("Below are some Browser events 'captured' from the above web page by AutoIt", 500, 385, 990, 20)
    Local $idGUIExit = GUICtrlCreateButton(" Close and exit", 5, 580, 990, 15)

    Local $hButton1 = GUICtrlCreateButton("Add an Item to timeline", 10, 400, 150, 40)
    GUISetState() ;Show GUI

    ; We prepare the Internet Explorer as our test subject
    Global $oIE = ObjCreate("Shell.Explorer.2")
    $hIE = GUICtrlCreateObj($oIE, 5, 5, 990, 380) ; <- embedd $oIE in the AutoIt GUI

    ; load our web page, javascript and css in the browser
    ToolTip("...downloading javascript, please wait")
    $oIE.navigate('file:///' & @ScriptDir & '\Page.html')
    Sleep(1000) ; Give it some time to load the web page
    ToolTip("")

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

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


    $ohJS.eval("var AutoIt = undefined");create varialbe to hold the object
    _AutoItObject_Startup()
    $oObject = _AutoItObject_Create()
    _AutoItObject_AddMethod($oObject, "logEvent", "logEvent")
    $ohJS.AutoIt = $oObject
;~  $ohJS.eval("alert(AutoIt.logEvent())")

    ; --- Setup catch of events ---

    ;   https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx
    ;   HTMLDocumentEvents2 interface (catch OnClick, OnMouseOver, .... etc
    Global $oEventObject = ObjEvent($oDocument, "IEEvent2_", "HTMLDocumentEvents2") ; OK, this events are catched

    ; Attempt to catch events fired by the DataSet.
    ; items is the DataSet obj created in the Browser
    ; Global $oEventObject = ObjEvent($ohJS.items, "OnDataSet_") ; ???? how to catch events from the DataSet <---- ?????

    ; -----------------------------

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

            Case $hButton1
                ; add a job to the timeline (a simple example just to test)
                ; to generate a unique ID I use the following: @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC
                Local $result = $ohJS.eval("items.add([{id: " & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC & ", content: '<b>item 4</b> Added at " & @HOUR & ":" & @MIN & ":" & @SEC & " ', start: '2014-01-19'}]);")
                ConsoleWrite("DataSet now contains " & $ohJS.items.length & " Items" & @CRLF)

        EndSwitch
    WEnd

    ; the end
    $oEventObject.Stop ; Tell IE we don't want to receive events.
    $oEventObject = 0 ; Kill the Event Object
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUIMain) ; Remove GUI
EndFunc   ;==>Example

; --- event management zone ---
; A few Internet Explorer Event Functions
; below function are fired by events occurred in the browser
Volatile Func IEEvent2_onClick($oEvent)
    ConsolePrint("mouse click: " & $oEvent.clientX & ',' & $oEvent.clientY & '  on ' & $oEvent.srcElement.NodeName & '  - ' & $oEvent.srcElement.ID)
EndFunc   ;==>IEEvent2_onClick

Volatile Func IEEvent2_onDblClick($oEvent)
    ConsolePrint("mouse DoubleClick: @" & $oEvent.clientX & ',' & $oEvent.clientY)
EndFunc   ;==>IEEvent2_onDblClick

Volatile Func OnDataSet_add($oEvent)
    ConsolePrint("!!!! event from DataSet " & IsObj($oEvent)) ; type
EndFunc   ;==>OnDataSet_add

Func ConsolePrint($sMsg)
    Local Const $iMaxLines = 9 ; keep last 12 lines only
    $sMsg = @HOUR & ':' & @MIN & ':' & @SEC & ':' & @MSEC & @TAB & $sMsg & @CRLF
    $sMsg = StringReplace(GUICtrlRead($g_idGUIEdit) & $sMsg, @CR, @CR)
    If @extended > $iMaxLines Then ; more than $iMaxLines
        $sMsg = StringMid($sMsg, StringInStr($sMsg, @CR, 0, -1 * $iMaxLines) + 2)
    EndIf
    GUICtrlSetData($g_idGUIEdit, $sMsg)
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

#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 type="text/css">
    body, html {
    font-family: arial, sans-serif;
    font-size: 11pt;
    }
    </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.css" rel="stylesheet" type="text/css" />
    </head>
    <body>

    <div id="visualization" style="border-width:3px; border-color:yellow; border-style:double;"></div>
    <p></p>
    <div id="log"></div>

    <script type="text/javascript">
    // DOM element where the Timeline will be attached
    var container = document.getElementById('visualization');

    // Create an empty DataSet (allows two way data-binding)
    var items = new vis.DataSet({type: { start: 'ISODate', end: 'ISODate', notes: '' }});

    // items.addEventListener('click',resetElements,true);

    // add items to the DataSet
    items.add([
    {id: 1, content: 'item 1 <b>start</b>', start: '2014-01-23'},
    {id: 2, content: 'item 2', start: '2014-01-18 00:00', end: '2014-01-18 23:59'},
    {id: 3, content: 'item 3', start: '2014-01-21'},
    {id: 5, content: 'item 5', start: '2014-01-28', type:'point'},
    {id: 6, content: 'item 6', start: '2014-01-26'}
    ]);

    // Configuration for the Timeline
    var options = {orientation: 'top',
    editable: {
    add: true,
    remove: true,
    updateTime: true,
    updateGroup: true
    }
    };

    // Create a Timeline
    var timeline = new vis.Timeline(container, items, options);

    // turn events on
    timeline.on('rangechange', function (properties) {
    logEvent('rangechange', properties);
    });
    timeline.on('rangechanged', function (properties) {
    logEvent('rangechanged', properties);
    });
    timeline.on('select', function (properties) {
    logEvent('select', properties);
    });

    items.on('*', function (event, properties) {
    //logEvent(event, properties);
        AutoIt.logEvent(event, properties);
    });

    function logEvent(event, properties) {
    var log = document.getElementById('log');
    var msg = document.createElement('div');
    msg.innerHTML = 'event=' + JSON.stringify(event) + ', ' +
    'properties=' + JSON.stringify(properties);
    log.firstChild ? log.insertBefore(msg, log.firstChild) : log.appendChild(msg);
    }
    </script>
    </body>
    </html>
#ce;HTML
;

 

3 people like this

Share this post


Link to post
Share on other sites

Just to add to what @genius257 suggested, you can use that method to directly call any AutoIt function (either built-in or user defined) from within javascript.

#AutoIt3Wrapper_UseX64=n
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <string.au3>
#include <array.au3>

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#include "AutoItObject.au3"
_AutoItObject_StartUp()
; set up a mini framework of AutoIt Functions/constants and stick them on an object
Global $oAutoIt = _AutoItObject_Create()
_AutoItObject_AddMethod($oAutoIt, "call", "_call")
; Maybe to directly acess any function
Func _call($oSelf, $sFunc, _
        $vParam1 = 0, $vParam2 = 0, $vParam3 = 0, $vParam4 = 0, $vParam5 = 0, $vParam6 = 0, _
        $vParam7 = 0, $vParam8 = 0, $vParam9 = 0, $vParam10 = 0, $vParam11 = 0, $vParam12 = 0, _
        $vParam13 = 0, $vParam14 = 0, $vParam15 = 0, $vParam16 = 0, $vParam17 = 0, $vParam18 = 0, _
        $vParam19 = 0, $vParam20 = 0, $vParam21 = 0, $vParam22 = 0, $vParam23 = 0, $vParam24 = 0, _
        $vParam25 = 0, $vParam26 = 0, $vParam27 = 0, $vParam28 = 0, $vParam29 = 0, $vParam30 = 0)
    Local $sExec = $sFunc & "("
    If @NumParams = 3 And IsArray($vParam1) And UBound($vParam1, 0) = 1 Then
        For $n = 0 To UBound($vParam1) - 1
            $sExec &= "$vParam1[" & $n & "],"
        Next
    Else
        If @NumParams = 2 Then
            $sExec &= ")"
        Else
            For $n = 1 To @NumParams - 2
                $sExec &= "$vParam" & $n & ","
            Next
        EndIf
    EndIf
    Return Execute(StringTrimRight($sExec, 1) & ")")
EndFunc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Global $g_idGUIEdit

; read html page from bottom of this script
; and write it to a file on disk
CreateHtmlPage()

Example()
Exit

Func Example()
    Local $hGUIMain = GUICreate("Event Test", 1000, 600)
    $g_idGUIEdit = GUICtrlCreateEdit("", 500, 405, 490, 175)
    GUICtrlSetFont(-1, 9, 400, -1, 'Courier New')
    GUICtrlCreateLabel("Below are some Browser events 'captured' from the above web page by AutoIt", 500, 385, 990, 20)
    Local $idGUIExit = GUICtrlCreateButton(" Close and exit", 5, 580, 990, 15)

    Local $hButton1 = GUICtrlCreateButton("Add an Item to timeline", 10, 400, 150, 40)
    GUISetState() ;Show GUI

    ; We prepare the Internet Explorer as our test subject
    Global $oIE = ObjCreate("Shell.Explorer.2")
    $hIE = GUICtrlCreateObj($oIE, 5, 5, 990, 380) ; <- embedd $oIE in the AutoIt GUI

    ; load our web page, javascript and css in the browser
    ToolTip("...downloading javascript, please wait")
    $oIE.navigate('file:///' & @ScriptDir & '\Page.html')
    Sleep(1000) ; Give it some time to load the web page
    ToolTip("")

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

    ; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
    ; $ohJS is a reference to the javascript Global Obj
    ; -------------------------------------------------
    Global $ohJS = $oIE.document.parentwindow.JSglobal
    $ohJS.AutoIt = $oAutoIt
    ; --- Setup catch of events ---

    ;   https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx
    ;   HTMLDocumentEvents2 interface (catch OnClick, OnMouseOver, .... etc
    Global $oEventObject = ObjEvent($oDocument, "IEEvent2_", "HTMLDocumentEvents2") ; OK, this events are catched

    ; Attempt to catch events fired by the DataSet.
    ; items is the DataSet obj created in the Browser
;~   Global $oEventObject = ObjEvent($ohJS.items);, "OnDataSet_") ; ???? how to catch events from the DataSet <---- ?????

    ; -----------------------------

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

            Case $hButton1
                ; add a job to the timeline (a simple example just to test)
                ; to generate a unique ID I use the following: @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC
                Local $result = $ohJS.eval("items.add([{id: " & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC & ", content: '<b>item 4</b> Added at " & @HOUR & ":" & @MIN & ":" & @SEC & " ', start: '2014-01-19'}]);")
                ConsoleWrite("DataSet now contains " & $ohJS.items.length & " Items" & @CRLF)

        EndSwitch
    WEnd

    ; the end
    $oEventObject.Stop ; Tell IE we don't want to receive events.
    $oEventObject = 0 ; Kill the Event Object
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUIMain) ; Remove GUI
EndFunc   ;==>Example

; --- event management zone ---
; A few Internet Explorer Event Functions
; below function are fired by events occurred in the browser
Volatile Func IEEvent2_onClick($oEvent)
    ConsolePrint("mouse click: " & $oEvent.clientX & ',' & $oEvent.clientY & '  on ' & $oEvent.srcElement.NodeName & '  - ' & $oEvent.srcElement.ID)
EndFunc   ;==>IEEvent2_onClick

Volatile Func IEEvent2_onDblClick($oEvent)
    ConsolePrint("mouse DoubleClick: @" & $oEvent.clientX & ',' & $oEvent.clientY)
EndFunc   ;==>IEEvent2_onDblClick

Volatile Func OnDataSet_add($oEvent)
    ConsolePrint("!!!! event from DataSet " & IsObj($oEvent)) ; type
EndFunc   ;==>OnDataSet_add

Func ConsolePrint($sMsg)
    Local Const $iMaxLines = 9 ; keep last 12 lines only
    $sMsg = @HOUR & ':' & @MIN & ':' & @SEC & ':' & @MSEC & @TAB & $sMsg & @CRLF
    $sMsg = StringReplace(GUICtrlRead($g_idGUIEdit) & $sMsg, @CR, @CR)
    If @extended > $iMaxLines Then ; more than $iMaxLines
        $sMsg = StringMid($sMsg, StringInStr($sMsg, @CR, 0, -1 * $iMaxLines) + 2)
    EndIf
    GUICtrlSetData($g_idGUIEdit, $sMsg)
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

#cs;HTML
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <script type="text/javascript">
    var JSglobal = (1,eval)("this"), AutoIt;
    </script>
    <style type="text/css">
    body, html {
    font-family: arial, sans-serif;
    font-size: 11pt;
    }
    </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.16.1/vis.min.css" rel="stylesheet" type="text/css" />
    </head>
    <body>

    <div id="visualization" style="border-width:3px; border-color:yellow; border-style:double;"></div>
    <p></p>
    <div id="log"></div>

    <script type="text/javascript">
    // DOM element where the Timeline will be attached
    var container = document.getElementById('visualization');

    // Create an empty DataSet (allows two way data-binding)
    var items = new vis.DataSet({type: { start: 'ISODate', end: 'ISODate', notes: '' }});

    // items.addEventListener('click',resetElements,true);

    // add items to the DataSet
    items.add([
    {id: 1, content: 'item 1 <b>start</b>', start: '2014-01-23'},
    {id: 2, content: 'item 2', start: '2014-01-18 00:00', end: '2014-01-18 23:59'},
    {id: 3, content: 'item 3', start: '2014-01-21'},
    {id: 5, content: 'item 5', start: '2014-01-28', type:'point'},
    {id: 6, content: 'item 6', start: '2014-01-26'}
    ]);

    // Configuration for the Timeline
    var options = {orientation: 'top',
    editable: {
    add: true,
    remove: true,
    updateTime: true,
    updateGroup: true
    }
    };

    // Create a Timeline
    var timeline = new vis.Timeline(container, items, options);

    // turn events on
    timeline.on('rangechange', function (properties) {
    logEvent('rangechange', properties);
    });
    timeline.on('rangechanged', function (properties) {
    logEvent('rangechanged', properties);
    });
    timeline.on('select', function (properties) {
    logEvent('select', properties);
    });

    items.on('*', function (event, properties) {
    logEvent(event, properties);
    });

    function logEvent(event, properties) {
    var log = document.getElementById('log');
    var msg = document.createElement('div');
    msg.innerHTML = 'event=' + JSON.stringify(event) + ', ' +
    'properties=' + JSON.stringify(properties);
    log.firstChild ? log.insertBefore(msg, log.firstChild) : log.appendChild(msg);
    AutoIt.call("ConsolePrint", msg.innerHTML);
    //AutoIt.call("MsgBox", 4096, "Maybe like this", msg.innerHTML);
    }
    </script>
    </body>
    </html>
#ce;HTML
;

 

1 person likes this

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Hi @genius257, thanks very much for your interesting example (as usual from you)

Since I also like understand what's happening under the hood, and since I've never made use before of the AutoitObject.udf, in short this is what I understand:

I thought you built a mechanism that pushes events from Javascript to AutoIt. A reverse way from that used by the ObjEvent(), that instead it "Pulls" events directly  from within AutoIt by listening what's autonomously dispatched by javascript's objects. A bit twisted but quite interesting way,
But it's not like that, It's even better, as @trancexx kindly pointed out (many thanks @trancexx ),  you are not pushing events to AutoIt, but executing AutoiT code directly from within javascript as callback function in response to javascript events... surprising! (now I know why your name is @genius... :)

I've never looked at the AutoitObject.udf before, but I think I've missed something interesting... It's a very powerful tool indeed (if you know how and when to use it of course). It can open a very deep integration between AutoIt and the embedde Browser Control as in this case for example.
Wondering, since it seems an abbandoned thread :'( , if this is a stable and safe tool to use in production and with new OSes...

Many thanks again! @genius257 and @trancexx for the very appreciated and enlightening examples !

P.S.

:huh2: I'm still wondering why this isn't feasible using native ObjEvent() can't listen events fired by the javascript DataSet... ??

Edited by Chimp

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

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

-- Doublepost by accident on edit. look below --

Edited by genius257

Share this post


Link to post
Share on other sites

 

3 hours ago, Chimp said:

Wondering, since it seems an abbandoned thread :'( , if this is a stable and safe tool to use in production and with new OSes.

Well if you want to make sure or change something, the source for the dll is included in the thread. I've tried looking into adding functionality for getter and setter, but I'm not experienced enough to fully understand it, and too lazy to read up so far :) maybe a day when I'm bored.

4 hours ago, Chimp said:

:huh2: I'm still wondering why this isn't feasible using native ObjEvent() can't listen events fired by the javascript DataSet... ??

As i understand the ObjEvent catches events from the object itself, so the browser object would haft to have some extra functionality, or javascript could use "fireEvent", with some information sent along with the event.

44 minutes ago, trancexx said:

You actually don't need AutoItObject for simple tasks like this, because ObjCreateInterface() exist for some time now, so you can write:

Wow! I didn't know that was possible thank you ;)

 

Edit:

4 hours ago, Chimp said:

code directly from within javascript as callback function in response to javascript events... surprising! (now I know why your name is @genius... :)

Thank you for your flattering compliment *blush*

4 hours ago, Chimp said:

Many thanks again! @genius257 and @trancexx for the very appreciated and enlightening examples !

Anytime! :D Glad i could help

Share this post


Link to post
Share on other sites

#10 ·  Posted

1 hour ago, trancexx said:

.... You actually don't need AutoItObject for simple tasks like this ...

... simple taks like this??? :frantics: ....you are centuries ahead!

1 hour ago, trancexx said:

.... because ObjCreateInterface() exist for some time now, so you can write: .....

... you really fly high, even over the eagles :thumbsup:

 

@trancexx, WAW! you made my day. Thank you very much for this pearl of code! It simply achieves the goal without relying on 'third parts'...,

I really like it very much.... (even if I don't understand much of what's happening inner the script..:blink:).

what other to say?  ....thanks for existing! :)

 

 

49 minutes ago, genius257 said:

Well if you want to make sure or change something, the source for the dll is included in the thread. I've tried looking into adding functionality for getter and setter, but I'm not experienced enough to fully understand it, and too lazy to read up so far :) maybe a day when I'm bored.

@genius257 I am not able to do this, but.... I hope that you get bored sooner or later.... ;)

 

Thank you everybody !


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

Share this post


Link to post
Share on other sites

#11 ·  Posted

4 hours ago, trancexx said:

^^ AutoitObject isn't maintained. The version I tested with was compiled by @AdmiralAlkex and I think x64 version isn't working. I'm not sure if he changed some compile options or is it something else.

I had to install some helpfile creator or something, you can see my ramblings in the post before the upload... But I'm fairly sure I wouldn't have changed something that could affect the running of the code.

If anything's broken in a way it shouldn't be, maybe I didn't have the last version of the code. No one did ever clearly confirm that I did. I am not the only one with a copy of the SVN, am I?

Share this post


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

  • Similar Content

    • rynow
      roma() - autoit Framework - (needed support)
      By rynow
      Hello,
      I´m using AutoIt for a long time not only to automate applications but to develop complex stand-alone applications. I am particularly annoyed by the fact that the logic in AutoIt is difficult to separate from the presentation and the standard GUI elements are very inflexible. If you want to create something more sophisticated, you have to use GDI and write many lines for simple effects or animations.
      With these thoughts in mind, I looked around for alternatives and unfortunately found nothing that corresponded to my ideas. Therefore, I have thought of a different solution. I have created this framework in order to separate the logic from the presentation and to use HTML & CSS in my GUI to the full extent.
      Goals of the Framework
      MVC development with AutoIt HTML & CSS GUI in AutoIt Better and more modern package system(UDF) like npm CLI support like Laravel Artisan faster and more structured application development roma() is strongly inspired by Laravel PHP Framework so Laravel users will notice many similarities.
      Support
      Unfortunately, I do not have much time for the project at the moment. So I thought to myself, I share it and ask you for support.
      Content
      The framework primarily serves for the development of stand-alone applications.
      All necessary settings are preconfigured. You can start immediately with the logic or the view All settings are in one place The logic(controller) and the presentation are clearly separated from each other Development with MVC structure You can develop the GUI in realTimer without restarting AutoIt GUI can be developed in HTML & CSS Any graphic & video integration is possible (.png, .gif etc.). Also everything that is possible in HTML5 and CSS3 JavaScript & Frameworks are supported Debug logs are created including console output It is possible to work with multiple languages All UDFs are contained in the framework. Reloading is not necessary The AutoIt UDFs are also included in the Framework. This ensures that it workds correctly for different Versions of AutoIt The framework also provides functions that are necessary for communication between AutoIt and HTML. For example, evaluation of form data (GET & POST) (documentation for this and examples follow.) I also developed a template engine. (Similar to Laravel Blade) The template engine supports if statements (would like to have help to make loops possible). In the Future I will publish a complete documentation of the template engine and examples. Almost finished is a database package. This makes communication with databases an absolute child's play. So that was it for once. If something else occurs to me, I will update the list. Small Example
      url: http://localhost:8080/welcome ;application.au3 ;----------------------------------------------------------------------------------------------/ ; Initial ;----------------------------------------------------------------------------------------------/ #include 'vendor\initial.au3' func _roma_routes() ;----------------------------------------------------------------------------------------------/ ; GET Request ;----------------------------------------------------------------------------------------------/ $route_get('welcome', 'welcome') endfunc ;roma\controller\welcome.au3 ;----------------------------------------------------------------------------------------------/ ; Welcome Controller ;----------------------------------------------------------------------------------------------/ func controller_welcome() Local $name = 'Eduard', $lastname = 'Tschernjaew' ;----------------------------------------------------------------------------------------------/ ; passed variable to view (Array are possible) ;----------------------------------------------------------------------------------------------/ $toView('name', $name) $toView('lastname', $lastname) ;----------------------------------------------------------------------------------------------/ ; Return a View ;----------------------------------------------------------------------------------------------/ return $VIEW('welcome') endfunc <html> <head> <title>roma() - Template Test</title> </head> <body> <h1>Hello {{ $name }} {{ $lastname }}</h1> </body> </html>  
      Download
      The framework is under the Open-Source license.
      Github: https://github.com/4ern/roma/
      git clone https://github.com/4ern/roma.git or download the ZIP. 
      Documentaion: https://github.com/4ern/roma/blob/master/README_EN.md 
      ToDo
      [ ] Loop Funktion in Template.au3
      [ ] CLI module like Laravel Artisan
      [ ] Solution approaches, how the framework can be optimally compiled, so that in the compiled state all files are available.
      [ ] Framework Tests & Bugfixes
      roma() is still in development. Documentation and application examples will soon be available. I am looking forward to any Contributing.
      Thanks for Feedback and Contributing
    • scintilla4evr
      ChakraCore UDF - executing JavaScript in AutoIt
      By scintilla4evr
      Hello!
      Microsoft Edge, the new browser released with Windows 10, uses Chakra as its JavaScript engine. In January, Microsoft released ChakraCore - the open source version of the engine that can be used in other apps.
      So, how about using it in AutoIt? I tried 2 times to create ChakraCore UDF, and I succeeded.
      So here it is - the ChakraCore UDF.
      Features:
      Executing JavaScript from AutoIt (obviously) Passing data from AutoIt to JavaScript Calling AutoIt functions from JavaScript ChakraCore UDF
      Have fun!
    • scintilla4evr
      ChakraCore UDF
      By scintilla4evr
      A basic UDF enabling JavaScript execution using Microsoft's ChakraCore engine.
    • genius257
      Is it possible to throw an error in a ScriptControl object, via AutoIt
      By genius257
      First of all I've been searching on the forum, and while there's been done something like this with: https://www.autoitscript.com/forum/topic/141004-comobject-proxy-seamless-windows-script-control-autoitobj/
      I could not find any solution to my predicament.
       
      Is it possible to throw an error in a ScriptControl object, via AutoIt?
      I have a script, where AutoIt calls ScriptControl:JavaScript which in turn calls AutoIt.
      However i would like to be able to make AutoIt invoke an exception within ScriptControl, if the called functionality fails.
      Here's some code for reference:
      #AutoIt3Wrapper_Run_AU3Check=n #include-once #include "AutoitObject.au3" #include <WinAPIDiag.au3> $oJS = ObjCreate("ScriptControl") $oJS.Language = "JScript" $oJS.TimeOut = 0; A value of 0 means that the ScriptControl will monitor the execution of the script and will trigger the Timeout event if it determines that the script is hung. _AutoItObject_Startup() $oAutoIt = _AutoItObject_Create() _AutoItObject_AddMethod($oAutoIt, "Execute", "_Execute", False) $oJS.AddObject("AutoIt", $oAutoIt, True) OnAutoItExitRegister("_CleanUp") $_AutoItError = ObjEvent("AutoIt.Error", "_AutoItError") Func _CleanUp() ConsoleWrite("Cleaning up..."&@CRLF) $oJS = 0 $oAutoIt = 0 _AutoItObject_Shutdown() EndFunc Func _Execute($oSelf, $sString) $vReturn = Execute($sString) If @error<>0 Then Return $oJS.Eval("throw new SyntaxError();"); Does invoke exception, but not within the try/catch Return $vReturn EndFunc Func _AutoItError($oError) $oError2 = $oJS.Error ConsoleWrite( _ "Column: " & $oError2.Column & @CRLF & _ "Description: " & $oError2.Description & @CRLF & _ "HelpContext: " & $oError2.HelpContext & @CRLF & _ "HelpFile: " & $oError2.HelpFile & @CRLF & _ "Line: " & $oError2.Line & @CRLF & _ "Number: " & $oError2.Number & @CRLF & _ "Source: " & $oError2.Source & @CRLF & _ "Text: " & $oError2.Text & @CRLF _ ) $oError2.Clear() EndFunc $oJS.Eval("(function(){"& _ "try{"& _ "AutoIt.Execute('MsgBox(0,\'\', \'a\')');"& _ "AutoIt.Execute('a.b');/*error should occur here*/"& _ "AutoIt.Execute('MsgBox(0,\'\', \'b\')');"& _ "}catch(e){"& _ "AutoIt.Execute('ConsoleWrite(\'Error\'&@CRLF)');"& _ "}"& _ "})()")  
    • jiggunjer
      Event-based scripting with the windows shell COM object
      By jiggunjer
      I want to listen for certain windows events like window open/closed. After reading the help I think I need to use ObjCreate('shell.application') and ObjEvent with that object to create/register a listener. The problem is I don't know what interface or events (i.e. the specific event names) are available for the listener. I tried searching MSDN but it is a labyrinth and I'm not that familiar with the programming frameworks/models used by Windows, and all the examples seem to refer to compiled code using .NET or some other api.
      Can any1 point me in the right direction? Also is using COM objects considered the 'modern' way to do this, or should I be using some other framework/resources?