Jump to content

Who is Who ? (a little drag&drop game)

Recommended Posts


This is a little experiment that makes use of a "Browser Control" embedded in a GUI in order to be able to use AutoIt, HTML, JavaScript and CSS all together.
This little toy will only work on systems with IE11.
The purpose is to drag all the names of the scientists & drop on the right ones. (among scientists it has also infiltrated an intruder). I hope you find it entertaining.
I've posted it here in the hope to have some suggestions on how to improve it all (I mean the interaction between Autoit Javascript html and css). Thanks

; this works on systems with IE11
; -------------------------------
#include <GUIConstantsEx.au3>
#include <array.au3>
Global $oIE, $oDocument, $ohJS, $sDroping
Global $iCorrect = 0, $iGoal = 11

Func Example()
    Local $aScientists[12][2] = _
            [["Schrodinger", "Schrodinger"],["Planck", "Planck"],["Pauli", "Pauli"],["Einstein", "Einstein"], _
            ["Chimp", "Chimp"],["Dirac", "Dirac"],["Heisenberg", "Heisenberg"],["Born", "Born"], _
            ["De Broglie", "De_Broglie"],["Bohr", "Bohr"],["Sommerfeld", "Sommerfeld"],["", "empty"]]

    Local $oIE = ObjCreate("Shell.Explorer.2") ; Create a BrowserControl
    Local $hGUI = GUICreate("", 660, 600, 30, 30)
    GUICtrlCreateObj($oIE, 0, 0, 660, 600) ; Place BrowserControl on the GUI
    GUISetState() ;Show GUI
    $oIE.navigate('about:blank') ; file:///' & @ScriptDir & '\WhoIsWho.html')
    While Not String($oIE.readyState) = 'complete' ; wait for about:blank

    ; this waits till the document is ready to be used (portion of code from IE.au3)
    While Not (String($oIE.readyState) = "complete" Or $oIE.readyState = 4)
    While Not (String($oIE.document.readyState) = "complete" Or $oIE.document.readyState = 4)

    $oIE.document.Write(_GetHTML()) ; inject lising directly to the HTML document:
    $oIE.document.close() ; close the write stream
    While Not String($oIE.readyState) = 'complete' ; wait for readyState after a refresh
    ; https://msdn.microsoft.com/en-us/library/52f50e9t(v=vs.94).aspx
    ; $ohJS is a reference to the javascript Global Obj
    ; -------------------------------------------------
    $ohJS = $oIE.document.parentwindow.JSglobal
    $oDocument = $oIE.document

    Local $oTable1 = $ohJS.table1
    Local $oTable2 = $ohJS.table2

    _Randomize($aScientists, $oTable1)

    ; --- Setup events ------------
    ; https://msdn.microsoft.com/en-us/library/hh801967(v=vs.85).aspx
    Local $aoEventObject[2]
    $aoEventObject[0] = ObjEvent($oTable1, "IEEvent_", "HTMLTableEvents2")
    $aoEventObject[1] = ObjEvent($oTable2, "IEEvent_", "HTMLTableEvents2")
    ; -----------------------------
    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE

        If $iCorrect = $iGoal Then
            _Randomize($aScientists, $oTable1)
            $iCorrect = 0

    ; the end
    For $i = 0 To UBound($aoEventObject) - 1
        $aoEventObject[$i] .stop
    $aoEventObject = 0 ; Kill the Event Object
    $oIE = 0 ; Remove IE from memory (not really necessary).
    GUIDelete($hGUI) ; Remove GUI
EndFunc   ;==>Example

; --- event management zone ---
; following functions are fired by events occurred in the browser control

Volatile Func IEEvent_onDragstart($oEvent)
    ; we save the ID of the dragged obj into the $sDroping variable
    ; for a later use in the drop function
    $sDroping = $oEvent.srcElement.ID
EndFunc   ;==>IEEvent_onDragstart

Volatile Func IEEvent_onDragOver($oEvent)
EndFunc   ;==>IEEvent_onDragOver

Volatile Func IEEvent_onDrop($oEvent)
    If $sDroping <> "" Then
        If $oDocument.getElementById($sDroping).innerText <> $oEvent.srcElement.innerText Then
            If $oEvent.srcElement.ClassName = $oDocument.getElementById($sDroping).ClassName Then
                $oEvent.srcElement.innerText = $oDocument.getElementById($sDroping).innerText
                $oDocument.getElementById($sDroping).innerText = ""
                $oDocument.getElementById($sDroping).draggable = False
                $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #80ff80;"
                $iCorrect += 1
                For $i = 1 To 3
                    $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #ff0000;"
                    $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #ffffff;"
        $sDroping = ""
EndFunc   ;==>IEEvent_onDrop

Func _Randomize(ByRef $aScientists, ByRef $oTable)
    Local $iRows = ($oTable.rows.length) - 1
    Local $iCols = ($oTable.rows.item(0).cells.length) - 1
    Local $index
    For $y = 0 To $iRows
        For $x = 0 To $iCols
            $index = ($y * ($iCols + 1)) + $x
            $oTable.rows.item($y).cells.item($x).innerText = $aScientists[$index][0] ; text
            $oTable.rows.item($y).cells.item($x).className = $aScientists[$index][1] ; class
            $oTable.rows.item($y).cells.item($x).draggable = $aScientists[$index][0] <> ""
EndFunc   ;==>_Randomize

Func _Goal()
    Local $oTable1 = $ohJS.table1 ; names
    Local $oTable2 = $ohJS.table2 ; photos
    Local $iRows = ($oTable1.rows.length)
    Local $iCols = 6 ; ($oTable1.rows.item(0).cells.length)
    Local $aIndex[$iRows * $iCols], $sTemp
    For $i = 0 To UBound($aIndex) - 1
        $aIndex[$i] = $i ; + 1
    For $i = 0 To UBound($aIndex) - 1
        $oTable2.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).innerText = ""
        $oTemp0 = $oTable2.rows
        $oTemp1 = $oTemp0.item(Int($aIndex[$i] / $iCols)).cells
        $oTemp2 = $oTemp1.item(Mod($aIndex[$i], $iCols)).getAttribute("style")
        $oTable2.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: " & _rndColor()
        Sleep(100); MsgBox(0,"Debug",$sTemp)
        $oTable2.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = $oTemp2
    For $x = 1 To 2
        For $i = 0 To UBound($aIndex) - 1
            $oTable1.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: " & _rndColor()
            $oTable1.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: #ffffff;"
EndFunc   ;==>_Goal

Func _rndColor()
    Return String("#" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & ";")
EndFunc   ;==>_rndColor

Func _GetHTML()
    Local $sHTML = _
            "<!DOCTYPE HTML>" & @CRLF & _
            "<html>" & @CRLF & _
            "<head>" & @CRLF & _
            "<meta http-equiv=""X-UA-Compatible"" content=""IE=edge"" />" & @CRLF & _
            "   <script type=""text/javascript"">" & @CRLF & _
            "       var JSglobal = (1,eval)(""this"");" & @CRLF & _
            "   </script>" & @CRLF & _
            "</head>" & @CRLF & _
            "<body>" & @CRLF & _
            "<h2>Who is who?</h2>" & @CRLF & _
            "<p>Drag&Drop names on the right scientist</p>" & @CRLF & _
            "<img src=""https://s29.postimg.org/4g264egmv/Scientists.jpg""" & @CRLF & _
            "height=""394"" width=""640""" & @CRLF & _
            "style=""position: absolute; left: 10px; top: 100px;"">" & @CRLF & _
            "" & @CRLF & _
            "<style>" & @CRLF & _
            ".target td {width: 100px; height: 160px; text-align: center; color: white; font-weight: bold; vertical-align: bottom; border: 0px solid grey;}" & @CRLF & _
            ".source td {width: 100px; height: 30px; text-align: center; border: 1px solid red;}" & @CRLF & _
            "</style>" & @CRLF & _
            "" & @CRLF & _
            "<table class=""target"" style=""position: absolute; left: 25px; top: 100px;"" id=""table2"">" & @CRLF & _
            "    <tr><td class=""Schrodinger""></td><td class=""Planck""></td><td class=""Pauli""></td><td class=""Einstein""></td><td class=""Chimp""></td><td class=""Dirac""></td></tr>" & @CRLF & _
            "    <tr><td class=""Heisenberg""></td><td class=""Born""></td><td class=""De_Broglie""></td><td class=""Bohr""></td><td class=""Sommerfeld""></td><td class=""empty""></td></tr>" & @CRLF & _
            "</table>" & @CRLF & _
            "" & @CRLF & _
            "<table class=""source"" style=""position: absolute; left: 10px; top: 504px;"" id=""table1"">" & @CRLF & _
            "    <tr><td ID=""td1""></td><td ID=""td2""></td><td ID=""td3""></td><td ID=""td4"" ></td><td ID=""td5"" ></td><td ID=""td6"" ></td></tr>" & @CRLF & _
            "    <tr><td ID=""td7""></td><td ID=""td8""></td><td ID=""td9""></td><td ID=""td10""></td><td ID=""td11""></td><td ID=""td12""></td></tr>" & @CRLF & _
            "</table>" & @CRLF & _
            "</body>" & @CRLF & _
    Return $sHTML
EndFunc   ;==>_GetHTML


Edited by Chimp
little correction on the red flash effect on error when dropping on wrong scientist
  • Like 3

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

Where is "Doctor Who" ? ;)


Signature beginning:   Wondering who uses AutoIT and what it can be used for ?
* GHAPI UDF - modest begining - comunication with GitHub REST API *
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for other useful stuff click the following button


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF *

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * 

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2018-03-17

Share this post

Link to post
Share on other sites

error: _ArrayShuffle(): undefined function. Got me to update my AutoIT!

Brilliant piece of work! Newb question about coding technique though: Why put mainline code in a function instead of just inline?


Func Example()


Share this post

Link to post
Share on other sites
19 hours ago, wysocki said:

Brilliant piece of work!

Thanks :)

19 hours ago, wysocki said:

Newb question about coding technique though: Why put mainline code in a function instead of just inline?


Func Example()


Is in this way to better separate the scope of Local and Global variables
.. for a better explanation have a look here: https://www.autoitscript.com/wiki/Best_coding_practices#Scopes_of_Variables


I've made a little variation in the script so to wait a ready state after a page refresh.

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

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

    • Chimp
      By Chimp
      An example on how to inject jQuery into a web page
      It can be useful to manage the page from AutoIt using jQuery.
      Idea from here: http://www.learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklet
      Suggestions and improvements are welcome
      #include <ie.au3> Example() Func Example() Local $oIE = _IECreate("www.google.com") Local $jQuery = _jQuerify($oIE) MsgBox(0, "Version", "jQuery version: " & $jQuery.fn.jquery) MsgBox(0, "Example", "click ok to exit." & @CRLF & "Google logo will fade out by jQuery...") $jQuery('#hplogo').fadeOut(3000) ; jQuery will fade out the google logo EndFunc ;==>Example ; #FUNCTION# ==================================================================================================================== ; Name ..........: _jQuerify ; Description ...: ; Syntax ........: _jQuerify(Byref $oIE) ; Parameters ....: $oIE - Object variable of an InternetExplorer.Application. ; Return values .: an object variable pointing to the jQuery library ; Author ........: Chimp ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _jQuerify(ByRef $oIE) Local $jsEval, $jQuery, $otherlib = False ; create a reference to the javascript eval() function $oIE.document.parentWindow.setTimeout('document.head.eval = eval', 0) Do Sleep(250) $jsEval = Execute('$oIE.Document.head.eval') Until IsObj($jsEval) ; if jQuery is not already loaded then load it If $jsEval("typeof jQuery=='undefined'") Then ; check if the '$' (dollar) name is already in use by other library If $jsEval("typeof $=='function'") Then $otherlib = True Local $oScript = $oIE.document.createElement('script'); $oScript.type = 'text/javascript' ; If you want to load jQuery from a disk file use the following statement ; where i.e. jquery-1.9.1.js is the file containing the jQuery source ; (or also use a string variable containing the whole jQuery listing) ;~ $oScript.TextContent = FileRead(@ScriptDir & "\jquery-1.9.1.js") ; <--- from a file ; If you want to download jQuery from the web use this statement $oScript.src = 'https://code.jquery.com/jquery-latest.min.js' ; <--- from an url $oIE.document.getElementsByTagName('head').item(0).appendChild($oScript) Do Sleep(250) Until $jsEval("typeof jQuery == 'function'") EndIf Do Sleep(250) $jQuery = $jsEval("jQuery") Until IsObj($jQuery) If $otherlib Then $jsEval('jQuery.noConflict();') Return $jQuery EndFunc ;==>_jQuerify  
    • XaelloNegative
      By XaelloNegative
      Hi there.
      Im having some kind of a coder block here, 
      <td class="treeview ctl00_CenterContent_objTreeView_2" style="white-space:nowrap;"> <input type="checkbox" name="ctl00_CenterContent_objTreeViewn1CheckBox" id="ctl00_CenterContent_objTreeViewn1CheckBox"> <span class="ctl00_CenterContent_objTreeView_0 treeview ctl00_CenterContent_objTreeView_1" id="ctl00_CenterContent_objTreeViewt1" style="border-style:none;font-size:1em;"> <i class="fa fa-file-code-o fa-fw"> </i> <span data-placement="bottom" data-toggle="tooltip" title="" data-original-title="Tool tip for said part">REFUNDS</span></span></td> this is a code directly from the website im working with. I was thinking of inserting a javascript that would get the "REFUNDS" part. Any ideas on how to do so?
      Any thoughts will be highly appreciated.
    • tarretarretarre
      By tarretarretarre
      Yep yep, this is pretty much an attempt to port the existing project's concept https://socket.io/ to AutoIt's Codebase. So i will not go in to so much detail.
      This is how the communication is done http://i.imgur.com/0mMfsBD.png Each client is isolated to the server http://i.imgur.com/rVO2LFb.png Features
      Easy API VarType Translation (Example: If the server sends an int, the client will receive an int and vice versa) Fully featured examples Data encryption (Using Autoit's UDF Crypt.au3) Limitations / Drawbacks
      It is not possible to Broadcast/Emit objects Only 1D-arrays are allowed to be Broadcasted/Emitted (2D arrays will probably never be supported) Changelog
      Version 1.5.0 (This update DOES NOT break scripts)
      Added AutoIt like docs under Docs\. The docs are generated so its a 1 to 1 reflection of the UDF headers. Print of documentation Added a production ready server example. Added a new method: _Io_DevDebug which will display useful information when debugging. Added a new method: _Io_SetMaxRecvPackageSize which defaults to whatever _Io_setRecvPackageSize is set to. Added a new method: _Io_setOnPrefix which defaults to _On_ Added a new default client & server event called flood. Flood occurs when exceeding the $__g_io_nMaxPacketSize. $__g_io_nMaxPacketSize is set by _Io_SetMaxRecvPackageSize Fixed the 16 parameter limit when sending data with _Io_Emit, _Io_Broadcast, _Io_BroadcastToAll and _Io_BroadcastToRoom. This works on the same premise that AutoIt's Call Does Fixed a TRUNCATION problem when receiving packages which could cause crashes! Fixed a programming error which caused $__g_ionPacketSize to reset to default 4096 if _Io_Connect or _Io_listenwere called after _Io_setRecvPackageSize Fixed _Io_setEventPreScript and _Io_setEventPostScript They didnt work. Lol. Changed how events are fired so the client cannot crash the server by sending the wrong number of parameters (This also allows for optional parameters on callbacks) Changed _Io_On. The second parameter $fCallback can now be set to null. Doing this, the function assumes that the callback is: _On_<eventName>.  
      Changelog History
      Api methods
      Please see the docs provided
      Default events
      Server events
      connection Client events
      banned Server and Client events
      disconnect flood View source on github
      Autoit-Socket-IO-1.0.0.zip (OLD!)
      Autoit-Socket-IO-1.1.0.zip (OLD)
      Autoit-Socket-IO-1.3.0.zip (OLD)
      Autoit-Socket-IO-1.4.0.zip (OLD)
      Autoit-Socket-IO-1.5.0.zip (NEWEST 2017-12-20)
    • Patryk
      By Patryk
      Dear Colleagues,
      I have no idea how to refer to style.display in my loop. There is a button like: 
      <input name="ctl00$bodyPlaceholder$btnFecharProcessamento" class="button" id="bodyPlaceholder_btnFecharProcessamento" style="display: none;" onclick="FecharJanelaProcessamento();return false;" type="submit" value="Fechar"> I want it to be clicked as soon as button's style change from style="display: none;" to  style= ="display: inline-block;" 
      This is what I got, but it's not working...
      Func GetButtons() $oButtons = _IEGetObjByName($oForm,"ctl00$bodyPlaceholder$btnFecharProcessamento",-1) $i = 0 While $i <> 1 For $oBtn In $oButtons If _IEFormElementGetValue($oBtn) = "Fechar" And $oBtn.document.style.display = "display: inline-block;" Then $i = 1 _IEAction($oBtn, "focus") _IEAction($oBtn, "click") ExitLoop EndIf Next WEnd EndFunc  
      I will really appreciate if you could help me with these loop!
    • Omnitica
      By Omnitica
      I'm new to the forums! Couldn't find any threads covering this issue. Sorry if I'm wrong.

      I'm having problems changing the text/value of a input box. The particular box doesn't have a name or id, just: class="jq_hotkeys_enabled form-control".
      This class appears multiple times throughout the source, so I don't think It's right to reference that object. 
      See image 1.
      However, I've managed to find a object with the name "ctl00$content$ctrl$ucServiceTime$rpServicetimes$ctl00$edtHiddenResourceHelper" which contains the value of the input box, and the id for the person in the dropdown/combobox left of it. (with "dummy-1" selected).
      See image 2.
      As you can see the value is 3982,4545     ( name , time )
      But when I try to change the value of it by doing:
      #include <IE.au3> Local $oIE = _IEAttach(WinGetHandle("[CLASS:IEFrame]"),"embedded") Local $oForm = _IEFormGetObjByName($oIE, "aspnetForm") Local $oInput = _IEFormElementGetObjByName($oForm, "ctl00$content$ctrl$ucServiceTime$rpServicetimes$ctl00$edtHiddenResourceHelper") _IEFormElementSetValue($oInput, "3982,1337") The box doesn't get its new value. I  can see in the source that it's changed though.
      See image 3.
      However, if I do: 
      #include <IE.au3> Local $oIE = _IEAttach(WinGetHandle("[CLASS:IEFrame]"),"embedded") Local $oForm = _IEFormGetObjByName($oIE, "aspnetForm") Local $oInput = _IEFormElementGetObjByName($oForm, "ctl00$content$ctrl$ucServiceTime$rpServicetimes$ctl00$edtHiddenResourceHelper") _IEFormElementSetValue($oInput, "3982,1337") $oIE.document.parentwindow.execScript("theForm.submit()") ; But it needs to reload the page The box gets its new value after the page reloads by the theForm.submit() function. 
      This is a bit unfortunate as I want the changes to happen instantly like when I type in the box with the keyboard... or select in the combobox.
      Maybe someone knows how I can do this? Looking forward to an answer! 
      Thanks in advance.
      Note: Unfortunately I can't provide with the real URL as it is constricted to employees in the company I work for, but let me know If I should provide anything else.


Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.