Jump to content
Sign in to follow this  
MarkRobbins

Real OOP with AutoIt? Meet JSAIO...

Recommended Posts

MarkRobbins

I've been thinking about this for the last couple of weeks, and I've finally got around to putting together a proof of concept.

As far as OOP goes, Javascript is a pretty damn good language -- very flexible, but lets look at some code. Here is a two button form for AutoIt written in Javascript.

var $=this;
var hgui;
this.MsgHandler_=function (m){
  if (m==$.AutoIt.GUI_EVENT_CLOSE) {
    $.AutoIt.GUIDelete(hgui);
    return true;
  }else if (m==button1) {
    $.AutoIt.Run("notepad.exe");
  }else if (m==button2) {
    alert('Thanks from a javascript alert box!');
  }
  return false;
}
var button1,button2;
function Example1(){
  var msg;
  hgui=$.AutoIt.GUICreate("My Gui",400,500);
  button1=$.AutoIt.GUICreateButton("Run Notepad",10,10,200,30);
  button2=$.AutoIt.GUICreateButton("Press Me",10,40,200,30);
  $.AutoIt.GUISetState($.AutoIt.SW_SHOW,hgui);
}
Example1();

This code would reside in an external file and be called by AutoIt.

I've created a framework in AutoIt using AutoItObject that is just big enough to make this code work.

Basically I am creating an AutoItObject, tacking on some core AutoIt functions and constants, and sending it off to play in Javascript land. There is much more to be tacked on.

Other than this AutoItObject being a proxy for AutoIt functionality, there is a Javascript COM object into which the javascript file is loaded, and a message loop that calls back into the javascript.

The framework is 300 lines of code.

Before I extend this, I want to know if AutoIt ALREADY has a COM object I that I can use like this. But I am thinking that even if it does, this hand-coded way would be better because you can make the calls pass objects instead of parameters.

Here is the framework:

#include <AutoItObject.au3>
#include <GUIConstants.au3>


Global $thisfile=@ScriptFullPath;
Global $logg=$thisfile&".log.txt";

Global $jsfile=$thisfile&".js";
;e C:\batch\borg\TestJsaio.au3.js

;fret not, you do not need, will be a no-op if not exist
Global Const $snarl="C:\batch\Snarl_CMD.exe";

; need script exit for AIO shutdown
OnAutoItExitRegister("EvtScriptExit")
_AutoItObject_StartUp()

; error handler
Global $oError
$oError = ObjEvent("AutoIt.Error", "_ErrFunc")

; JScript Com globals
Global $_ComObj_proxy
Global $_com
Global $_Js
JScriptInit()
;;;;;;;;;;;;;;;;;;;;;;;;;;done inits

;;;;;;;;;;; begin framework

; set up a mini framework of AutoIt Functions/constants and stick them on an object
Global $AutoItForCom=_AutoItObject_Create();
;_AutoItObject_AddMethod(ByRef $oObject, $sName, $sAutoItFunc, $fPrivate = False)
_AutoItObject_AddMethod($AutoItForCom,"GUICreate","GUICreate_AI")
_AutoItObject_AddMethod($AutoItForCom,"GUISetState","GUISetState_AI")
_AutoItObject_AddMethod($AutoItForCom,"GUIGetMsg","GUIGetMsg_AI")
_AutoItObject_AddMethod($AutoItForCom,"GUIDelete","GUIDelete_AI")
_AutoItObject_AddMethod($AutoItForCom,"MsgBox","MsgBox_AI")
_AutoItObject_AddMethod($AutoItForCom,"GuiCreateButton","GuiCreateButton_AI")
_AutoItObject_AddMethod($AutoItForCom,"Run","Run_AI")
;_AutoItObject_AddProperty(ByRef $oObject, $sName, $iFlags = $ELSCOPE_PUBLIC, $vData = "")
_AutoItObject_AddProperty($AutoItForCom, "SW_SHOW", $ELSCOPE_PUBLIC+$ELSCOPE_READONLY, @SW_SHOW)
_AutoItObject_AddProperty($AutoItForCom, "GUI_EVENT_CLOSE", $ELSCOPE_PUBLIC+$ELSCOPE_READONLY, $GUI_EVENT_CLOSE)


;;; here are the tie-ins that the object will call
Func GUICreate_AI($me,$title,$width,$height)
  #forceref $me
  ;GUICreate ( "title" [, width [, height [, left [, top [, style [, exStyle [, parent]]]]]]] )
  Local $rv=GUICreate($title,$width,$height)
  Return $rv
EndFunc
Func GUISetState_AI($me,$flag,$hwnd)
  #forceref $me
  ;GUISetState ( [flag [, winhandle]] )
  Local $rv=GUISetState($flag,HWnd($hwnd));need to covert Int32
  Return $rv
EndFunc
Func GUIGetMsg_AI($me,$advanced)
  #forceref $me
  Local $rv= GUIGetMsg ($advanced)
  Return $rv
EndFunc

Func GUIDelete_AI($me,$winhandle)
  #forceref $me
  Local $rv=GUIDelete($winhandle)
  Return $rv
EndFunc

Func MsgBox_AI($me,$flag,$title,$text)
  #forceref $me
  ;MsgBox ( flag, "title", "text" [, timeout [, hwnd]] )
  Local $rv=MsgBox($flag,$title,$text)
  Return $rv
EndFunc

Func GUICreateButton_AI($me,$text,$left,$top,$width=Default,$height=Default,$style=Default,$exstyle=Default)
  #forceref $me
  ;GUICtrlCreateButton ( "text", left, top [, width [, height [, style [, exStyle]]]] )
  Local $rv=GUICtrlCreateButton ( $text, $left, $top, $width, $height, $style, $exstyle)
  Return $rv
EndFunc

Func Run_AI($me,$program,$wkdir=Default,$show_flag=Default,$opt_flag=Default)
  #forceref $me
  ;Msg2("run",$program)
  Local $rv;
  If False Then
  ElseIf @NumParams==2 Then
    $rv=Run($program)
  ElseIf @NumParams==3 Then
    $rv=Run($program,$wkdir)
  ElseIf @NumParams==4 Then
    $rv=Run($program,$wkdir,$show_flag)
  ElseIf @NumParams==5 Then
    $rv=Run($program,$wkdir,$show_flag,$opt_flag)
  EndIf
  ;Run ( "program" [, "workingdir" [, show_flag [, opt_flag]]] )
  ;Local $rv=Run($program,$wkdir,$show_flag,$opt_flag)
  Return $rv
EndFunc
;;;;;;;;;;;;;;;; end of tie-ins

;;;;;;;;;; setup JScript COM obj
Global $jso=NewComObj()

; import our AutoIt Proxy into the jso
$jso.set("AutoIt", $AutoItForCom)

; read our javascript file
Global $ftext=FileRead($jsfile)

; set the file text up as a Main function
$jso.set_function("Main", "", $ftext)

; need to run our message loop in autoit code, but pass it back to JS land here
$jso.set_function("MsgHandler", "m", "return eval('this.MsgHandler_(m)');")

; hold on to your britches...
; this call will run through the js file and the file must do a setup and have a callback MsgHandler_
$jso.Main()

;; Message Loop
Local $end_if_true
Local $m
  While True
    $m=GUIGetMsg(0)
    $end_if_true=$jso.MsgHandler($m)
    ;Msg($end_if_true);
    If $end_if_true Then
      ExitLoop
    EndIf
  WEnd
Exit

;; the only thing worth looking at below this point is the _ComObj_init and friends
;;;;;;;;;;;;;;;functions
Func EvtScriptExit()
  ;Msg("EvtScriptExit")
  _AutoItObject_Shutdown()
  ;_logline('EvtScriptExit')
  ;If IsObj($MidiMgr) Then
  ;  $MidiMgr.Terminate()
  ;EndIf
EndFunc

Func Msg($s)
  MsgBox(0,$thisfile,$s)
EndFunc
Func Msg2($t,$s)
  MsgBox(0,$t,$s)
EndFunc


Func logclear()
  FileDelete($logg)
EndFunc

Func _logline($line)
  logline($line)
EndFunc

Func logline($line)
  Local $fh1=FileOpen($logg,1);
  If $fh1<>-1 Then
    FileWriteLine($fh1,$line)
    FileClose($fh1)
  EndIf
EndFunc

Func logsnarl($line)
  logerr($line)
  snarl(10,'Fatal Error',$line)
EndFunc

Func snarl($i,$t,$s)
  If Not FileExists($snarl) Then
    Return
  EndIf
  $s1=StringReplace($s,'"',"'")
  $t1=StringReplace($t,'"',"'")
  $cmd=$snarl&' snShowMessage '&$i&' "'&$t1&'" "'&$s1&'"';
  Run($cmd)
EndFunc

;;;;js utils
; #FUNCTION# ==================================================================
; Name      : _ComObj_init
; Description  : Creates MS Windows Script control and deploy it as proxy for
;               AutoIt COM object binding.
; Syntax      : _ComObj_init([$VBScriptSupport = false])
; Parameter : $VBScriptSupport
;               By default JScript doesn't have alert() function, it is provided
;               by browser's window object.
;               We can emulate this using VBScript's MsgBox function, which is
;               performance hog because we need another ScriptControl instance.
;               Other advantage is to be able to execute other VBScript's methods
;               within function via vb.Eval() method.
;               This feature is disabled by default.
; =============================================================================
Func _ComObj_init ($VBScriptSupport = false)
  Local $_Script
  $_Script = ObjCreate("ScriptControl")
  $_Script.Language = "JScript"
  $_Script.Timeout = 60000
  ;$_Script.AddCode("var $=this,arrays=[],vb;function set_vbscript($) {vb=$;vb.Language='VBScript';vb.AllowUI=true;}function alert(s){if(vb)vb.Eval('MsgBox(Unescape(""'+s+'""), 0, ""Autoit"")')}function get_proxy(){return $}function new_object($){$=new Function('return{'+$+'}')();$.set=function(k, v){$[k]=v};$.unset=function(k){delete $[k]};$.set_object=function(k,$){this.set(k,new_object($))};$.set_array=function(){var v=[];for(var i=0;i<arguments.length;i++)v[i]=arguments[i];$.set(v.shift(),new_array.apply(this,v))};$.set_function=function(k,p,$){this.set(k,new_function(p,$))};return $}function new_array(){var v=[];for(var i=0;i<arguments.length;i++)v[i]=arguments[i];return v}function array_get($,k){return $[k]}function array_set($,k,v){return $[k]=v}var new_function=(function(){function F(r) {return Function.apply(this,r)}F.prototype = Function.prototype;return function(p,$){p=p.split(/\s*,\s*/);p.push($);return new F(p)}})()")
  ;a[a.length]=i;
  ;function new_array(){var v=[];for(var i=0;i<arguments.length;i++)v[i]=arguments[i];return v}
  Local $more= _
  "$.get=function(k){return $[k]};" & _
  "$.has=function(n){" & _
  "  for (var i in this){" & _
  "    if (i!=n){" & _
  "      continue;" & _
  "    }" & _
  "    if (!this.hasOwnProperty(i)){" & _
  "      continue;" & _
  "    }" & _
  "    if (typeof(this[i])=='function'){" & _
  "      continue;" & _
  "    }" & _
  "    return true;" & _
  "  };" & _
  "  return false;" & _
  "};" & _
  "$.keys=function(){" & _
  "  var a=[];" & _
  "  for (var i in this){" & _
  "    if (this.hasOwnProperty(i)){" & _
  "      if (typeof(this[i])!='function'){" & _
  "        a[a.length]=i;" & _
  "      }" & _
  "    }" & _
  "  };" & _
  "  return a;" & _
  "};" & _
  "$.set2=function(){" & _
  "  for(var x=0;x<arguments.length-1;x+=2){" & _
  "    this[arguments[x]]=arguments[x+1]" & _
  "  }" & _
  "};" & _
  "Array.prototype.item=function(n){" & _
  "  return this[n];" & _
  "};" & _
  "Array.prototype.has=function(v){" & _
  "  for(x=0;x<this.length;x++){" & _
  "    if(this[x]==v){return true;}" & _
  "  }" & _
  "  return false;" & _
  "};" & _
  "Array.prototype.asString=function(d){" & _
  "  var s='';" & _
  "  for(x=0;x<this.length;x++){" & _
  "    if(s==''){s=this[x];}else{s+=d+this[x];}" & _
  "  }" & _
  "  return s;" & _
  "};"
  $_Script.AddCode("var $=this,arrays=[],vb;function set_vbscript($) {vb=$;vb.Language='VBScript';vb.AllowUI=true;}function alert(s){if(vb)vb.Eval('MsgBox(Unescape(""'+s+'""), 0, ""Autoit"")')}function get_proxy(){return $}function new_object($){$=new Function('return{'+$+'}')();$.set=function(k, v){$[k]=v};"&$more&"$.unset=function(k){delete $[k]};$.set_object=function(k,$){this.set(k,new_object($))};$.set_array=function(){var v=[];for(var i=0;i<arguments.length;i++)v[i]=arguments[i];$.set(v.shift(),new_array.apply(this,v))};$.set_function=function(k,p,$){this.set(k,new_function(p,$))};return $}function new_array(){var v=[];for(var i=0;i<arguments.length;i++)v[i]=arguments[i];return v}function array_get($,k){return $[k]}function array_set($,k,v){return $[k]=v}var new_function=(function(){function F(r) {return Function.apply(this,r)}F.prototype = Function.prototype;return function(p,$){p=p.split(/\s*,\s*/);p.push($);return new F(p)}})()")
  If $VBScriptSupport = true Then $_Script.Run("set_vbscript", ObjCreate("ScriptControl"))
  Return $_Script
EndFunc
; =============================================================================

Func NewComObj()
  Local $com
  While True
    $com=$_com.new_object("")
    Sleep(30)
    If IsObj($com) Then
      ExitLoop
    EndIf
  WEnd
  Sleep(30)
  Return $com
EndFunc

Func JScriptInit()
  $_ComObj_proxy = _ComObj_init(true)
  $_com = $_ComObj_proxy.Run("get_proxy")
  $_Js = $_com.new_object("")
  $_Js.set_function("AIOSetProperty","o,n,v","o[n]=v;")
EndFunc

Func JS_SetProp()
  $_Js = $_com.new_object("")
  $_Js.set_function("AIOSetProperty","o,n,v","o[n]=v;")
  Return $_Js;
EndFunc

My main questions are...

  1. Why doesn't this already exist, and where is it? and...
  2. Why doesn't this already exist -- what wall am I headed for?

:bike::nuke::ermm:>_<

Edited by MarkRobbins

Share this post


Link to post
Share on other sites
MarkRobbins

What are all of the concepts that a language needs to be considered object oriented?

 

While you can 'do' OOP in any language, it can be very painful without support. When you think about it, OOP is about making miniature programs, self-contained and (as much as possible) unaware of the outside world.

Many OOP languages are strongly typed, to prevent you from sticking square pegs in round holes, and catching those mistakes at compile time.

Javascript is 'duck typed', meaning its objects are fluid and it is up to the programmer to decide if a particular object 'quacks like a duck'.

This is done by inspecting the object to see if it has a particular property or interface.

The main thing an OOP language must support is heritability, Javascript does a reasonable job of this but it does fall short in some sense, you have to boilerplate a lot of the heritability mechanism yourself.

Bright points of Javascript are:

  • Functions are objects, can be passed
  • It has a cool binding mechanism, where functions declared within functions can access variables within the enclosing scope. Its hard to explain, but once you get it, its very useful
  • Objects are dynamic, and act like hash tables
  • It has a very powerful Eval()
  • Objects can be made up on the fly, no formal declarations or 'class makers' needed
  • It has reflection, you can iterate through an object
  • Its the most popular scripting language in the world

Compared to AutoIt, Javascript will:

  • Get rid of the Globals nightmare, probably possible to write a very complex program with just a single global
  • Allow Case Sensitive identifiers (which some will hate)
  • Get rid of $ on identifiers (which I will LOVE)
  • Provide potential code libraries to be used from the web (typecastjs.org), though many of these are web based, they could be ported
  • Get rid of the parameter nightmare, just pass objects
  • Dynamically create functions, objects and 'code' with Eval()
  • Offer Easy Timers - SetInterval, SetTimeout
  • Provides an easy, well established plugin-mechanism
  • Base types (Number,String,Object,Array,Date,Bool) can be extended

 

For a great lecture on Js ...

Share this post


Link to post
Share on other sites
jaberwacky

"Functions are objects, can be passed"

"Get rid of $ on identifiers (which I will LOVE)" 

I'm hoping that a later version of AutoIt will provide this.

"It has a cool binding mechanism, where functions declared within functions can access variables within the enclosing scope. Its hard to explain, but once you get it, its very useful"

I think those are called closures.

OK, so basically, not real oop in autoit but rather java oop in autoit?

Edited by jaberwocky6669

Share this post


Link to post
Share on other sites
Mat

Javascript is the most popular scripting language in the world? Most used perhaps, but only because its the only choice for client side web apps. Doesn't mean its a good language.

Share this post


Link to post
Share on other sites
MarkRobbins

OK, so basically, not real oop in autoit but rather java oop in autoit?

 

Some would claim that java is TOO oop-y. Execution in the Kingdom of Nouns

Javascript!=Java

Its a common misconception that Js is not real oop, its just not classical oop ala C++ and the like.

Share this post


Link to post
Share on other sites
MarkRobbins

Javascript is the most popular scripting language in the world? Most used perhaps, but only because its the only choice for client side web apps. Doesn't mean its a good language.

<script type="text/vbscript">

Do you know of a better language for scripting? I mean language in terms of language features, not libraries.

I think its a good language, though it does have some flaws. For a not-good language, one would have a hard time explaining the rise of Js on the server side.

Share this post


Link to post
Share on other sites
LateArrival

Forgive me for being somewhat critical but I struggle to see how shoehorning another language into autoit is a good idea.

I would much prefer Autoit or AutoitObject to evolve to be a fully fledged OOP language rather than masquerade it to something that it is not. I love autoit for its directness and simplicity in achieving tasks that would otherwise take you a lot of time to get through in another language.

At the same time my 10-20,000 lines of structured code (not anymore) can use the oop treatment.

So I would ideally prefer for Autoit or AIO to evolve to provide better OOP plumbing (i.e. events etc.) stuff you find in C# and .NET (there you go I said it). If found myself building similar “frameworks” that look like this:

#include 'System.au3'

#include 'System.Collections.au3'

#include 'System.ComponentModel.au3'

#include 'System.Diagnostics.au3'

#include 'System.Data.au3'

#include 'System.Messaging.au3'

#include 'System.Drawing.au3'

#include 'System.IO.au3'

#include 'System.Windows.au3'

#include 'System.Windows.Automation.au3'

#include 'System.Windows.Controls.au3'

#include 'System.Windows.Forms.au3'

#include 'System.Windows.Input.au3'

You can guess what’s in there and what they are supposed to do but I say “frameworks” because in reality it’s a mickey mouse attempt to dress up win api or au3 functions so that they behave like .net. It worked for a while but before too long you run into all sort of other issues.

Having been through this loop I really think it’s a waste of time. There is language that does this already. Its called C# and it runs on a framework that dos all this already and its called .NET and you can buy some thing like DevExpress or similar to sex it up.  

Autoit is still great. Just a few days ago it helped me sort through  150,000 images and save the day for a pretty major retailer all from code found in the help files. Thank you very much. I love Autoit but I am gonna have to give up trying to make it look and work like .NET J

Edited by LateArrival

Share this post


Link to post
Share on other sites
Mat

Apparently the Node.js creator chose javascript because it had no io conventions so he could come up with his funky event based system, that made it so popular. Outside of web development, does javascript have many uses?

Python and ruby have pretty large feature sets. They are both used far more often than javascript for server side programming (and not because they've been around for longer like php). Python I know has most (if not all) the features listed above are there, and there are plenty more as well.

Personally I'd say lots of language features doesn't make a good language, and neither does being flexible. To me, a good language is something like C#, where if you gave 2 C# programmers the same task, their code would look very similar (and not because they are restricted by the language).

Edit: I hope I'm not sounding too cynical about your project. Nothing personal, I just don't like javascript. Probably because I was forced to use it in a couple of web development projects.

Edited by Mat

Share this post


Link to post
Share on other sites
MarkRobbins

Forgive me for being somewhat critical but I struggle to see how shoehorning another language into autoit is a good idea.

 

I think of it this way. On the language front, AutoIt is lacking, but on the library front it is pretty good. Somone at Netscape once remarked that Windows was just a bag of iffy drivers... which at the time, was kinda fair for an insult. So if we look at AutoIt and see it as a so-so language that has a nice bunch of calls... and those calls can be pretty easily clipped onto a COM object -- why would you stay in the language?

Your point about DotNet is well taken, but not even C# is Javascript. Its all about target size, do you want an elephant gun or a shotgun. Javascript gives informality and quick prototyping. I guess my point is that heavier armor has its cost.

To be fair, the objections that come to my mind would be the continuity and coding split, and the question of debugging. I guess my question for you is, why do you do AutoIt and not DotNet? Whats wrong with the best of both worlds?

That is, if it can be done. This is just a probe, I really didn't expect so much poo-pooing. Did AutoItObject receive that reception?

Share this post


Link to post
Share on other sites
MarkRobbins
 

 

 

Outside of web development, does javascript have many uses?

ECMAScript is basis for ActionScript, which is Flex and Flash, both are not confined to the web and are used to create rich GUI desktop apps.

 

I'd say lots of language features doesn't make a good language, and neither does being flexible

Javascript has many, many flaws. But something has to be said about a language that is so flexible that its mistakes can be rectified ad-hoc.

 

if you gave 2 C# programmers the same task, their code would look very similar

 

Good thing for a production environment for sure.

I think your comments were pretty restrained for someone who dislikes javascript. I will ask the same question to you -- why not just develop in C# instead of AutoIt? I don't want to sound snarky, but shouldn't we all have a good answer to that? There must be a reason, and wouldn't that reason be better off in a language that supports OO?

 

Share this post


Link to post
Share on other sites
LateArrival

 Its all about target size, do you want an elephant gun or a shotgun. I guess my point is that heavier armor has its cost.

 

I guess in my case I need an elephant with a machine gun!

A lot of the low level stuff like handling windows, controls, trays, ini files - if you care for that - or hotkeys are not very accessible in WPF or are very counter-intuitive to work with.Do-able but a royal pain. On the other hand, wiring sophisticated GUIs together in AI is also doable but also a royal pain. I mean who wants to register WM_something to handle control events in 2013.

So there is no happy medium as I see it. Enough people have build some of the 'missing' features in WPF over the years so rather than trying to turn AI into something it is not perhaps the best course of action is to invest time in building up the features one needs in C#/WPF (or similar). I could be wrong but attempting to do the opposite  may be quite a huge task and there are always lots of people with varying needs and you can never keep everybody happy.

To be honest it would be too much for me to presume what is right or not for AI since I am new here and I have very healthy respect for anybody who can produce a language and run it successfully over many years. Anyway wasn't poo poing your idea but I just come to think that AI is a pretty good script language to automate windows applications. That is it I think...The rest is just mismanaged or unrealistic expectations (on my part at least).

Share this post


Link to post
Share on other sites
Mat

why not just develop in C# instead of AutoIt? I don't want to sound snarky, but shouldn't we all have a good answer to that? There must be a reason, and wouldn't that reason be better off in a language that supports OO?

I do. I do hardly any AutoIt scripting any more, apart from for very small desktop apps and utilities. For GUI programming, I could still write a GUI in AutoIt from scratch faster than I can do it in visual studio with the designer (and certainly a lot faster than I could do it in C# source code). AutoIt I could write a few hundred lines of script in notepad on someone elses pc, run it with a single standalone executable, and it will work first time (well... most of the time anyway). 

For me, C#, C++, AutoIt and python cover all my needs. None of them are perfect, I don't think a one-language-fits-all solution is possible.

But anyway. Don't let my grumbling stand in your way. Language development is great fun, its something I've had an interest in for years.

Share this post


Link to post
Share on other sites
LateArrival

To Mat 

Btw if I got this right do you take:

 

43 38 48 31 30 4e 34 4f 32 with 43 31 32 48 32 32 4F 31 31 or without?

Share this post


Link to post
Share on other sites
MarkRobbins

I've done some timing tests.

The message loop has to reside in AI and call into JSCOM using an eval.

1000 such calls take 626ms

Direct calls, without eval, into JSCOM

1000 such calls take 728ms (it is weird that eval is faster)

Calling an empty function on the AutoIt AutoItObject (calling out to autoit)

1000 such calls take 69ms

For direct speed comparisons of the languages...

100k loops of addition x=x+1 in AI take 174ms, in JSCOM take 12ms - 1450% faster

10k loops of string concatenation s=s&' '  in AI take 97ms, in JSCOM take 7ms - 1385% faster

100k loops of calling an empty function in AI take 559ms, in JSCOM take 64ms - 873% faster

 

Share this post


Link to post
Share on other sites
BrewManNH

 

I've done some timing tests.

 

 

For direct speed comparisons of the languages...

100k loops of addition x=x+1 in AI take 174ms, in JSCOM take 12ms - 1450% faster

10k loops of string concatenation s=s&' '  in AI take 97ms, in JSCOM take 7ms - 1385% faster

100k loops of calling an empty function in AI take 559ms, in JSCOM take 64ms - 873% faster

 

Not sure how you did the timing tests, but for me 100K "x += 1" gives me 44ms, string concatenation $s &= " " gives me 60ms, and calling an empty function 100K times gives me 104ms, using beta 3.3.9.12. In 3.3.8.1 I get 27ms, 64ms, and 68ms respectively. All things considered, the speed difference isn't all that bad, considering interpreted languages and all.

 


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
MarkRobbins

 

Not sure how you did the timing tests, but for me 100K "x += 1" gives me 44ms, string concatenation $s &= " " gives me 60ms, and calling an empty function 100K times gives me 104ms, using beta 3.3.9.12. In 3.3.8.1 I get 27ms, 64ms, and 68ms respectively. All things considered, the speed difference isn't all that bad, considering interpreted languages and all.

 

 

 

I don't know how you can say that about the speed diff, they are both interpreted. On my planet any difference over 2x is quite considerable. The addition loop executes in 0.06 the time, Concat 0.07, and empty fn in 0.1  -- those are huge.

 

Here are the AI Tests

;loop additions
#cs
$time=TimerInit()
Global $end=100*1000
Global $x,$y=1
For $x=1 To $end
  $y=$y+1
Next
Global $t1
$t1=TimerDiff($time);174
Msg($t1)
Exit
#ce

;loop concat
#cs
$time=TimerInit()
Global $end=10*1000
Global $x,$y=''
For $x=1 To $end
  $y=$y&'x'
Next
Global $t1
$t1=TimerDiff($time);97
Msg($t1)
Exit
#ce

;loop empty fn
#cs
Func EmptyFn($x)
EndFunc
$time=TimerInit()
Global $end=100*1000
Global $x,$y=''
For $x=1 To $end
  EmptyFn(0)
Next
Global $t1
$t1=TimerDiff($time);559
Msg($t1)
Exit
#ce

Intel Xeon E5 2620

Share this post


Link to post
Share on other sites
Mat

To Mat 

Btw if I got this right do you take:

 

43 38 48 31 30 4e 34 4f 32 with 43 31 32 48 32 32 4F 31 31 or without?

Nope. I don't like them sweet. I like them hot and black :)

Share this post


Link to post
Share on other sites
MarkRobbins

Eval is not good.

 

It is the js eval I have to use if I calling into JSCOM with the msg loop, otherwise it hangs...

$jso.set_function("MsgHandler", "m", "return eval('this.MsgHandler_(m)');")

So the call looks like

Local $end_if_true
Local $m
  While True
    $m=GUIGetMsg(0)
    $end_if_true=$jso.MsgHandler($m)
    ;Msg($end_if_true);
    If $end_if_true Then
      ExitLoop
    EndIf
  WEnd
Exit

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
Sign in to follow this  

  • Similar Content

    • Chimp
      By Chimp
      The DOM allows to do anything with elements and their contents, but first we need to reach the corresponding DOM object, get it into a variable, and then we are able to modify it. *
      Well, this little tool (although it is not very nice aesthetically) allows you to get visually a "selector" usable to reference DOM objects.
      Once you have the "selector" of an element you can pass it to the javascript querySelector() function that will return a reference to that element.
      To use this tool you have to:
      1) open the web page you want to inspect into IE browser
      2) run this script (if it find more instances of IE running, it allows you to chose one)
      3) move the mouse over the browser. The "selector" of the element below the pointer is catched automatically while hovering. To copy the selector in the clipboard just right click on the element.
      As you can see, while hovering, the element pointed by the mouse is highlighted with a thin red dotted frame to allow you to better "take aim"
      when the selector is copied to the clipboard a little acoustic signal is emitted as a confirm, then you can paste it in your listing where you need it.
      I hope it can come in handy and save you time when you need to automate a site .... have fun (debugged on Sept. 30 2018)
      #include <IE.au3> #include <GUIConstantsEx.au3> #include <GuiListBox.au3> #include <WindowsConstants.au3> #include <Misc.au3> ; for _IsPressed (23 END key) Global $hDLL = DllOpen("user32.dll") ; following global variables are automatically updated by events from the browser ; ------------------------------------------------------------------------------------- Global $g_iMouseX, $g_iMouseY ; coordinates of the mouse while mooving over the browser Global $bCopySelector = False ; becomes True when you right click on wanted element ; ------------------------------------------------------------------------------------- Global $oIE = _Get_IE() ; get IE instance to inspect If IsObj($oIE) Then $hIE = _IEPropertyGet($oIE, "hwnd") WinActivate($hIE) _InspectElements() EndIf DllClose($hDLL) Exit Func _InspectElements() ; it uses the global variable $oIE as source ; --- set IE to interact with AutoIt --- Local $oDocument Do ; wait for document Sleep(250) $oDocument = $oIE.document Until IsObj($oDocument) Local $oWindow = $oDocument.ParentWindow ; create a reference to the javascript eval method ; in the body section of the dovument $oWindow.setTimeout("document.body.JSeval = eval; ", 0) ; attach the $JSeval variable to the javascript eval method Local $JSeval Do $JSeval = Execute('$oIE.Document.body.JSeval') Until IsObj($JSeval) ; --------------------------------------------- ; Inject Javascript functions/elements to $oIE ; --------------------------------------------- ; Get the DOM path of an element (a CSS selector) ; ----------------------------------------------- ; This javascript function returns the CSS selector of the passed element. ; You can then use the returned path to get a reference to the pointed ; element by the QuerySelector() javascript function ; function copied from the following link: ; https://stackoverflow.com/questions/5728558/get-the-dom-path-of-the-clicked-a ; see answer by "Aleksandar Totic" (thanks to him) Local $sJScript = "" & _ " function getDomPath(el) {" & _ " if (!el) {" & _ " return;" & _ " }" & _ " var stack = [];" & _ " var isShadow = false;" & _ " while (el.parentNode != null) {" & _ " var sibCount = 0;" & _ " var sibIndex = 0;" & _ " for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {" & _ " var sib = el.parentNode.childNodes[i];" & _ " if ( sib.nodeName == el.nodeName ) {" & _ " if ( sib === el ) {" & _ " sibIndex = sibCount;" & _ " }" & _ " sibCount++;" & _ " }" & _ " }" & _ " var nodeName = el.nodeName.toLowerCase();" & _ " if (isShadow) {" & _ " nodeName += ""::shadow"";" & _ " isShadow = false;" & _ " }" & _ " if ( sibCount > 1 ) {" & _ " stack.unshift(nodeName + ':nth-of-type(' + (sibIndex + 1) + ')');" & _ " } else {" & _ " stack.unshift(nodeName);" & _ " }" & _ " el = el.parentNode;" & _ " if (el.nodeType === 11) {" & _ " isShadow = true;" & _ " el = el.host;" & _ " }" & _ " }" & _ " stack.splice(0,1);" & _ " return stack.join(' > ');" & _ " }" ; more infos here: https://www.kirupa.com/html5/finding_elements_dom_using_querySelector.htm ; Inject the above javascript function contained in the $sJScript variable into the document _JS_Inject($oIE, $sJScript) Local $_getDomPath ; a reference to call above function from AutoIt Do Sleep(250) $_getDomPath = $jsEval("getDomPath") Until IsObj($_getDomPath) ; ; ------------------- ; hook some IE events ; ------------------- Local $oEventObjects[2], $oEventsSource $oEventsSource = $oIE.document.documentElement ; element we want catch events from ; https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa769636(v=vs.85) $oEventObjects[0] = ObjEvent($oEventsSource, "_HTMLElementEvents2_", "HTMLElementEvents2") ; https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa768283(v%3dvs.85) $oEventObjects[1] = ObjEvent($oIE, "_IEEvent_", "DWebBrowserEvents2") ; open a GUI where to show some element's properties ; -------------------------------------------------- Local $hGUIMain = GUICreate("Info", 500, 140, -1, -1, -1, $WS_EX_TOPMOST) Local $hProperties = GUICtrlCreateEdit("", 0, 0, 500, 140) GUICtrlSetFont(-1, 9, -1, -1, "Courier New") GUISetState() ;Show GUI ; -------------------------------------------------- ; --------- ; Main loop ; --------- Local $iMouseX, $iMouseY, $oElement, $oNewElement, $sSelector Local $oGotElement, $sElementInfos Local $sSaved_StyleOutline, $sSaved_StyleOutline2 ; Loop until the user exits. While IsObj($oIE) Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop ; ---> end EndSwitch If ($g_iMouseX <> $iMouseX) Or ($g_iMouseY <> $iMouseY) Then $iMouseX = $g_iMouseX $iMouseY = $g_iMouseY ; $oElement = $oIE.document.elementFromPoint($iMouseX, $iMouseY) ; <-- this way is slower $oNewElement = $JSeval('document.elementFromPoint(' & $iMouseX & ',' & $iMouseY & ');') If $oNewElement <> $oElement Then If IsObj($oElement) Then $oElement.style.outline = $sSaved_StyleOutline $oElement = $oNewElement ; $bSelfie = False ; $iSelf_Timer = TimerInit() $sSaved_StyleOutline = $oElement.style.outline ; save new element's original outline style $sSelector = $_getDomPath($oElement) ; get CSS path If $sSelector <> "" Then ; We could use the $oNewElement, but just to proof that $sSelector is OK ; we get again a reference to the new pointed element using it's $sSelector $oGotElement = $JSeval('document.querySelector("' & $sSelector & '");') ; <-- how to use a selector $oGotElement.style.outline = "1px dashed red" ; mark new pointed element ; https://css-tricks.com/ $sElementInfos = "" & _ "nodeName: " & $oGotElement.nodeName & @CRLF & _ "id: " & $oGotElement.getAttribute('id') & @CRLF & _ "class: " & $oGotElement.getAttribute('class') & @CRLF & _ "type: " & $oGotElement.getAttribute('type') & @CRLF & _ "---------" & @CRLF & _ $sSelector ControlSetText($hGUIMain, "", $hProperties, $sElementInfos) EndIf EndIf EndIf ; $bCopySelector is setted to True by the right-click event on an element, ; see Volatile Func _HTMLElementEvents2_onContextmenu($oEvent) near script bottom If $bCopySelector And ($sSelector <> "") Then ; And (TimerDiff($iSelf_Timer) > $bSelfie_Delay) Then ; $sSaved_StyleOutline2 = $oGotElement.style.outline $oGotElement.style.outline = "5px dotted #ff0066" ; mark copied element ClipPut($sSelector) $sElementInfos &= @CRLF & "selector copied to ClipBoard" ControlSetText($hGUIMain, "", $hProperties, $sElementInfos) Beep(2000, 50) $bCopySelector = False Sleep(250) $oGotElement.style.outline = $sSaved_StyleOutline2 ; ToolTip('') EndIf If _IsPressed("23", $hDLL) Then ; END key pressed If IsObj($oElement) Then $oElement.style.outline = $sSaved_StyleOutline WinActivate($hGUIMain) ; WinSetState($hGUIMain, "", @SW_SHOW) $aWin = WinGetPos($hGUIMain) MouseMove($aWin[0] + $aWin[2] / 2, $aWin[1] + $aWin[3] / 2, 0) EndIf WEnd ; the end ; ------------------------------------------ For $i = 0 To UBound($oEventObjects) - 1 ; Tell IE we don't want to receive events. $oEventObjects[$i] .Stop $oEventObjects[$i] = 0 Next $oIE = 0 ; Remove IE from memory GUIDelete($hGUIMain) ; Remove GUI ; ------------------------------------------ EndFunc ;==>_InspectElements Func _Get_IE() ; Example 5 from the _IEAttach help ; Create an array of object references to all current browser instances ; The first array element will contain the number of instances found Local $aIE[1] $aIE[0] = 0 Local $i = 1, $oIEx While 1 $oIEx = _IEAttach("", "instance", $i) If @error = $_IEStatus_NoMatch Then ExitLoop ReDim $aIE[$i + 1] $aIE[$i] = $oIEx $aIE[0] = $i $i += 1 WEnd If $aIE[0] > 0 Then If $aIE[0] = 1 Then Return $aIE[1] ; only one IE is running, return this then ; ; Create a little list box to choose the IE instance from Local $hChoose_IE = GUICreate("IE Instances", 600, 350) Local $Label1 = GUICtrlCreateLabel($aIE[0] & " running Instances of IE browser found, click the one you want to attach to then click on 'ok'", 5, 5, 590, 20) Local $List1 = GUICtrlCreateList("", 5, 30, 590, 300, BitOR($LBS_STANDARD, $LBS_EXTENDEDSEL)) Local $hButton_choosed = GUICtrlCreateButton("OK", 5, 325, 590, 20) For $i = 1 To $aIE[0] GUICtrlSetData($List1, $i & ") " & _IEPropertyGet($aIE[$i], "locationurl")) Next GUISetState(@SW_SHOW) While 1 ; wait for a selection Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete($hChoose_IE) Return False Case $hButton_choosed $aSelected = _GUICtrlListBox_GetSelItems($List1) If $aSelected[0] Then GUIDelete($hChoose_IE) Return $aIE[$aSelected[1] + 1] Else MsgBox(0, "Info", "Please select an item") EndIf EndSwitch WEnd Else MsgBox(0, 'error', "Sorry" & @CRLF & @CRLF & "no running IE instances found") EndIf EndFunc ;==>_Get_IE ; this function creates a javascript script into the html document ; of the passed $oIE object using the createElement method. Func _JS_Inject($oIE, $sJScript, $bIsUrl = False) ; ; get a reference to the document object Local $objDocument = $oIE.document ; Local $oScript = $objDocument.createElement('script') ; $oScript.type = 'text/javascript' If $bIsUrl Then $oScript.src = $sJScript ; works if $sJScript is a link to a js listing (url) Else ; (https://stackoverflow.com/questions/35213147/difference-between-text-content-vs-inner-text) ; $oScript.innerText = $sJScript $oScript.TextContent = $sJScript ; works if $sJScript contains the listing itself EndIf ; $objDocument.getElementsByTagName('head').item(0).appendChild($oScript) ; $objDocument.getElementsByTagName('head').item(0).removeChild($oScript); ; EndFunc ;==>_JS_Inject ; ------------------------------------------------------------------- ; following function(s) are called by registered $oIE elements events ; ------------------------------------------------------------------- ; ; The function automatically fired by an event ; will receive as parameter an Event Obj. ; This obj has properties related to ; the object that fired the event. ; See following link: ; https://msdn.microsoft.com/en-us/library/aa703876(v=vs.85).aspx ; function called by the mousemove event ; we use this to update 2 global variables: Volatile Func _HTMLElementEvents2_onMousemove($oEvent) $g_iMouseX = $oEvent.clientX $g_iMouseY = $oEvent.clientY EndFunc ;==>_HTMLElementEvents2_onMousemove ; function called by the contextmenu event ; we use this to update 1 global variable ; and we also neutralize this event: Volatile Func _HTMLElementEvents2_onContextmenu($oEvent) $oEvent.cancelBubble = True ; event propagation cancelled $oEvent.returnValue = False ; prevent default behaviour $bCopySelector = True ; when True, selector will be copied to clipboard in main loop EndFunc ;==>_HTMLElementEvents2_onContextmenu ; https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa768280%28v%3dvs.85%29 Func _IEEvent_BeforeNavigate2($oIEpDisp, $sIEURL, $iIEFlags, $sIETargetFrameName, $sIEPostData, $iIEHeaders, $bIECancel) ;ConsoleWrite("Debug: navigate away cancelled." & @CRLF) ; https://stackoverflow.com/questions/6526876/how-to-cancel-or-dispose-current-navigation-at-webbrowser-element $oIE.stop EndFunc ;==>_IEEvent_BeforeNavigate2 Here is a simple example on how a "selector" can be used in AutoIt.
      suppose we want automate the login to the AutoIt site with our username and password.
      I've already prepared a very simple "template" where are missing some important parts without which the script can't work. Missing parts are the references to the elements of the AutoIt web page that we have to manage by our script.
      well, here is where the tool I have just posted here above comes to our help.
      follow this steps:
      1) in IE open the AutoIt site at the forum page (https://www.autoitscript.com/forum/)
      2) run the above tool (select the IE instance and/or bring it to front if needed)
      3) when the script is "ready", move the mouse over the "Existing user? Sign In" string and right click the mouse button. Doing so the "selector" of that element is copied to the clipboard. Now we can paste it in our AutoLogIt.au3 script as value of the $sSignIn variable.
      4) now click on the "Existing user? Sign In"  to open the "Sig In" session from where we will copy selectors of each of the 2 input box Username and Password, in the same way as we have already done in step 3, and paste those selectors to the $sInputUserId and $sInputPasswd variables respectively.
      5) do the same for the "Sign In" Button and paste it's selector to the $sSignInButn variable
      6) of course also fill the $sMyUserId and $sMyPasswd variables with your data.
      That's It. Run the AutoLogIt script and it should Log you on automatically to the forum.
      AutoLogIt.au3
      #include <ie.au3> $sMyUserId = "" ; <-- your userid here $sMyPasswd = "" ; <-- your password here ; set selectors here $sSignIn = "" ; <-- SigIn element selector here $sInputUserId = "" ; <-- UserId input selector here $sInputPasswd = "" ; <-- Password input selector here $sSignInButn = "" ; <-- Sig In button selector here $oIE = _IECreate("https://www.autoitscript.com/forum/") ; here is how to use the QuerySelector javascript function $hDOM_Element = $oIE.document.QuerySelector($sSignIn) ; get the "sign in" link element ; perform a click action on the above element $hDOM_Element.click() ; or _IEAction($hDOM_Element, "click") as well ; fill the username input $hDOM_Element = $oIE.document.QuerySelector($sInputUserId) $hDOM_Element.value = $sMyUserId ; fill the password input $hDOM_Element = $oIE.document.QuerySelector($sInputPasswd) $hDOM_Element.value = $sMyPasswd ; .... or also using the dot notation directly .... $oIE.document.QuerySelector($sSignInButn).click() Sleep(5000) ; this should logout $sMenu = "body > div:nth-of-type(2) > header > div > ul > li:nth-of-type(6) > a:nth-of-type(2)" $oIE.document.QuerySelector($sMenu).click() $sLogOut = "body > ul > li:nth-of-type(9) > a" $oIE.document.QuerySelector($sLogOut).click()  
    • Chimp
      By Chimp
      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 Example() Exit 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 Sleep(100) WEnd ; 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) Sleep(100) WEnd While Not (String($oIE.document.readyState) = "complete" Or $oIE.document.readyState = 4) Sleep(100) WEnd $oIE.document.Write(_GetHTML()) ; inject lising directly to the HTML document: $oIE.document.close() ; close the write stream $oIE.document.execCommand("Refresh") While Not String($oIE.readyState) = 'complete' ; wait for readyState after a refresh Sleep(100) WEnd ; 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 ExitLoop EndSwitch If $iCorrect = $iGoal Then _Goal() _Randomize($aScientists, $oTable1) $iCorrect = 0 EndIf WEnd ; the end For $i = 0 To UBound($aoEventObject) - 1 $aoEventObject[$i] .stop Next $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) $ohJS.event.preventDefault() EndFunc ;==>IEEvent_onDragOver Volatile Func IEEvent_onDrop($oEvent) $ohJS.event.preventDefault() 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 Else For $i = 1 To 3 $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #ff0000;" Sleep(125) $oDocument.getElementById($sDroping).setAttribute("style") = "background-color: #ffffff;" Sleep(125) Next EndIf EndIf $sDroping = "" EndIf 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 _ArrayShuffle($aScientists) 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] <> "" Next Next EndFunc ;==>_Randomize Func _Goal() Local $oTable1 = $ohJS.table1 ; names Local $oTable2 = $ohJS.table2 ; photos Local $iRows = ($oTable1.rows.length) Sleep(250) 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 Next _ArrayShuffle($aIndex) 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 Next 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() Sleep(100) $oTable1.rows.item(Int($aIndex[$i] / $iCols)).cells.item(Mod($aIndex[$i], $iCols)).setAttribute("style") = "background-color: #ffffff;" Next Next 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=""http://oi66.tinypic.com/2q0lue9.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 & _ "</html>" Return $sHTML EndFunc ;==>_GetHTML  
    • Bilgus
      By Bilgus
      ; NetFirewallPolicy2 COM UDF Library for AutoIt3
      ; AutoIt Version : 3.3.14.5
      ; Description ...: Windows Firewall Policy2 Interface, Provides access to the firewall policy for Windows Vista+
      Including Test Script 
      _NetFw_Get_CurrentProfileTypes                           Retrieves the currently active firewall profile(s) _NetFw_Get_FirewallEnabled                               Indicates whether a firewall is enabled locally _NetFw_Put_FirewallEnabled                               Specifies whether a firewall is enabled locally _NetFw_Get_ExcludedInterfaces                            Indicates a list of interfaces on which firewall settings are excluded _NetFw_Put_ExcludedInterfaces                            Specifies a list of interfaces on which firewall settings are excluded _NetFw_Get_BlockAllInboundTraffic                        Indicates whether the firewall should not allow inbound traffic _NetFw_Put_BlockAllInboundTraffic                        Specifies whether the firewall should not allow inbound traffic _NetFw_Get_NotificationsDisabled                         Indicates whether interactive firewall notifications are disabled _NetFw_Put_NotificationsDisabled                         Specifies whether interactive firewall notifications are disabled _NetFw_Get_UnicastResponsesToMulticastBroadcastDisabled  Indicates whether the firewall should not allow unicast responses to multicast and broadcast traffic _NetFw_Put_UnicastResponsesToMulticastBroadcastDisabled  Specifies whether the firewall should not allow unicast responses to multicast and broadcast traffic _NetFw_Get_Rules                                         Retrieves the interface to collection of firewall rules _NetFw_Get_ServiceRestriction                            Retrieves the interface used to access the Windows Service Hardening store _NetFw_EnableRuleGroup                                   Enables or disables a specified group of firewall rules _NetFw_IsRuleGroupEnabled                                Determines whether a specified group of firewall rules are enabled or disabled for the current profile _NetFw_RestoreLocalFirewallDefaults                      Restores the local firewall configuration to its default state _NetFw_Get_DefaultInboundAction                          Indicates the default action for inbound traffic _NetFw_Put_DefaultInboundAction                          Specifies the default action for inbound traffic _NetFw_Get_DefaultOutboundAction                         Indicates the default action for outbound traffic _NetFw_Put_DefaultOutboundAction                         Specifies the default action for outbound traffic _NetFw_Get_IsRuleGroupCurrentlyEnabled                   Determines whether a specified group of firewall rules are enabled or disabled for the current profile _NetFw_Get_LocalPolicyModifyState                        Determines if adding or setting a rule or group of rules will take effect in the current firewall profile  
      UDF:
      Test Script:
       
    • Seminko
      By Seminko
      Is there a way to grab non-hardcoded but rather javascript generated data from a webpage?
      Tried a get request as well as _IEBodyReadHTML but both seem to grab the code without the javascript generated data.
      $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("GET", "link", False) $oHTTP.Send() $oReceived = $oHTTP.ResponseText $oStatusCode = $oHTTP.Status Global $DataArray[10][5] If $oStatusCode <> 200 Then Exit MsgBox(1, "Error", "Status Code <> 200") EndIf FileWrite(@ScriptDir & "\output.txt", $oReceived) ; //////// #include <IE.au3> Local $FullLink = "link" Local $oIE = _IECreate($FullLink, 0, 0) _IELoadWait($oIE) Local $sText = _IEBodyReadHTML($oIE) FileWrite(@ScriptDir & "\output.txt", $sText)  
    • rcmaehl
      By rcmaehl
      Hi all,
      I've recently be kinda forced into trying to learn OOP within AutoIt. I'm trying to convert XML into objects I guess instead of trying to parse it into arrays within arrays. An example is below:
      <User> <roles> <role>Agent</role> <role>Supervisor</role> </roles> </user>  
      How can I convert this? Would <roles> be $User.Roles? If so would the children be $User.Roles.Role.Agent and $User.Roles.Role.Supervisor?  If not, how do I reference each Object?
        Any assistance would be appreciated. I tried to understand XML.au3 but I'm so confused trying to wrap my head around this.
×