Jump to content
Sign in to follow this  
MarkRobbins

Real OOP with AutoIt? Meet JSAIO...

Recommended Posts

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

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

"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

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

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

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

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
 

 

 

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

 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

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

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

 

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

 

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

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By mdwerne
      Hello,
      Before Broadcom took over Symantec, I was able to use the following code as the base to scrape daily definition downloads from the web. Since the pages were moved over to the Broadcom web servers, I get a page full of what I believe may be JavaScript instead of the fully rendered page that lies behind it. Does anyone have any suggestions as to how I can read the full rendered webpage using AutoIt?
      #include <IE.au3> $oIE_DEFS = _IECreate("https://www.broadcom.com/support/security-center/definitions/download/detail?gid=sep14", 0, 0, 1, 1) $sString_DEFS = _IEBodyReadHTML($oIE_DEFS) MsgBox(0, "https://www.broadcom.com/support/security-center/definitions/download/detail?gid=sep14", $sString_DEFS) The above code will show the JavaScript, but if you go to the URL in a browser that has JavaScript enabled, you will see the fully rendered page that I would like to access. I hope my question makes sense, and I would appreciate any suggestions to get this working again.
      All the best,
      -Mike
    • By Colduction
      Hello again, i have a code that changes username to favorite, my problem is how to use ObjEvent() function to catch errors, i've red Help File and Forum's Topics but i can't understand too much😐

      Here is a code (I've copied this codes from a user of AutoIt Forum):
       
      $sOldUser = "Administrator" $sNewUser = "Admin" $oUser = ObjGet("WinNT://" & @ComputerName & "/" & $sOldUser & ",user") $oComputer = ObjGet("WinNT://" & @ComputerName) $oNewUser = $oComputer.MoveHere($oUser.ADsPath, $sNewUser) Thanks for your care, I'm new to AutoIt and days should be passed with my coding and practicing to don't bother you :)❤
    • By Chimp
      Making the integration between AutoIt and the BrowserControl easier may facilitate the development of interesting programs. Just think of all those (fantastic) libraries and frameworks available for javascript that could be integrated and exploited in an AutoIt program. For example, to graphically present the results of an AutoIt processing in the GUI, ... and many other possibilities. Providing the basic functions to implement this synergistic interaction is the purpose of this post (if for no other reason, just even to collect some tests done over time here and there, so as not to leave them scattered and easily find them in just one place)
      In this UDF there are only a few functions (or better if called wrappers), but I hope to add more as I go and, even better, to receive suggestions and advice on new features and techniques to improve and expand it.
      _WebBrowser_GUICtrlCreate Create an Internet Explorer 'Browser Control' _WebBrowser_SetHTML Set a new HTML listing in the BrowserControl _WebBrowser_CSS_Inject Creates into the html document a CSS node element with embedded the passed CSS _WebBrowser_JS_Inject Creates into the html document a javascript node element with embedded the passed javascript _WebBrowser_JS_Eval Evaluates a passed string as JavaScript code and executes it _WebBrowser_JS_setTimeout Calls a javascript function or executes a javascript code snippet [option after a specified delay] _WebBrowser_JS_ElementGetRef Retrieves a reference to an element suitable to be used from AutoIt _WebBrowser_ExecuteDotNotation Get a reference to an object's child member or the value of a property, by means of a dotted path _WebBrowser_BasicHTML Returns a basic html page listing (a little enhanced than about:blank) The three examples provided in the attached ziped file are a bit 'improvised' and do not take advantage of all the possibilities offered by the underlying javascript libraries used. They are just three "hello world" scripts to test the ABC of the interaction with the "BrowserControl".
      (ToDo: Interaction with javascript custom events)
      Bug reports, creative criticisms and suggestions (particularly regarding the interaction with javascript custom events) are welcome
      I hope you can have fun with the Browser Control
      BrowserControl.zip
    • 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=""https://i.imgur.com/STWql7w.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  
    • By Bilgus
      Trying to figure out how to do CallByName on AutoIt COM objects due to the lack of being able to set properties within an Execute() statement
      Several Ideas were Tried https://www.autoitscript.com/forum/topic/200129-set-object-properties-with-propertyname-and-value-taken-from-an-array/
      I think this is the best; Patching the vtable of IDispatch so we can intercept a Fake function call ($obj.Au3_CallByName)
      use it like this
      Local $oDictionary = ObjCreate("Scripting.Dictionary") ; EXAMPLE Au3_CallByname_Init() ; (you can optionally provide a classname here but we patch the main Idispatch interface so really no need) $Au3_CallByName = "Add" ; Method we want to call $oDictionary.Au3_CallByName("Test", "Value") Au3_CallByname_Init(False) ; (Not Strictly Needed unhooked on exit) NOTE:  Au3_CallByname_Init() doesn't have to be called at the top of the script, just call it before you need to call by name...
      Code + Example
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;Au3CallByName, Bilgus Global $Au3_CallByName = 0 Local $hKernel32 = DllOpen("Kernel32.dll") OnAutoItExitRegister(__CallByNameCleanup) Func __CallByNameCleanup() Au3_CallByName_Init(False) ;Unload DllClose($hKernel32) EndFunc ;==>__CallByNameCleanup ; Takes a pointer to the v-table in a class and replaces specified member Id in it to a new one. Func __HookVTableEntry($pVtable, $iVtableOffset, $pHook, ByRef $pOldRet) ;;https://www.autoitscript.com/forum/topic/107678-hooking-into-the-idispatch-interface/ Local Const $PAGE_READWRITE = 0x04 Local $tpVtable = DllStructCreate("ptr", $pVtable) Local $szPtr = DllStructGetSize($tpVtable) Local $pFirstEntry, $pEntry, $tEntry, $aCall, $flOldProtect, $bStatus ; Dereference the vtable pointer $pFirstEntry = DllStructGetData($tpVtable, 1) $pEntry = $pFirstEntry + ($iVtableOffset * $szPtr) ; Make the memory free for all. Yay! $aCall = DllCall($hKernel32, "int", "VirtualProtect", "ptr", $pEntry, "long", $szPtr, "dword", $PAGE_READWRITE, "dword*", 0) If @error Or Not $aCall[0] Then ConsoleWriteError("Error: Failed To hook vTable" & @CRLF) Return False EndIf $flOldProtect = $aCall[4] $tEntry = DllStructCreate("ptr", $pEntry) $pOldRet = DllStructGetData($tEntry, 1) If $pOldRet <> $pHook Then DllStructSetData($tEntry, 1, $pHook) $bStatus = True Else ;Already Hooked ConsoleWriteError("Error: vTable is already hooked" & @CRLF) $bStatus = False EndIf ;put the memory protect back how we found it DllCall($hKernel32, "int", "VirtualProtect", "ptr", $pEntry, "long", $szPtr, "dword", $flOldProtect, "dword*", 0) Return $bStatus EndFunc ;==>__HookVTableEntry ; Everytime autoit wants to call a method, get or set a property in a object it needs to go to ; IDispatch::GetIDsFromNames. This is our version of that function, note that by defining this ourselves ; we can fool autoit to believe that the object supports a lot of different properties/methods. Func __IDispatch_GetIDsFromNames($pSelf, $riid, $rgszNames, $cNames, $lcid, $rgDispId) Local Const $CSTR_EQUAL = 0x02 Local Const $LOCALE_SYSTEM_DEFAULT = 0x800 Local Const $DISP_E_UNKNOWNNAME = 0x80020006 Local Static $pGIFN = __Pointer_GetIDsFromNames() Local Static $tpMember = DllStructCreate("ptr") If $Au3_CallByName Then Local $hRes, $aCall, $tMember ;autoit only asks for one member $aCall = DllCall($hKernel32, 'int', 'CompareStringW', 'dword', $LOCALE_SYSTEM_DEFAULT, 'dword', 0, 'wstr', "Au3_CallByName", 'int', -1, _ 'struct*', DllStructGetData(DllStructCreate("ptr[" & $cNames & "]", $rgszNames), 1, 1), 'int', -1) If Not @error And $aCall[0] = $CSTR_EQUAL Then ;ConsoleWrite("CallByName: " & $Au3_CallByName & @CRLF) $tMember = DllStructCreate("wchar[" & StringLen($Au3_CallByName) + 1 & "]") DllStructSetData($tMember, 1, $Au3_CallByName) DllStructSetData($tpMember, 1, DllStructGetPtr($tMember)) $rgszNames = $tpMember $Au3_CallByName = 0 EndIf EndIf ;Call the original GetIDsFromNames $hRes = DllCallAddress("LRESULT", $pGIFN, "ptr", $pSelf, "ptr", $riid, _ "struct*", $rgszNames, "dword", $cNames, "dword", $lcid, "ptr", $rgDispId) If @error Then ConsoleWrite("Error: GetIDsFromNames: " & @error & @CRLF) Return $DISP_E_UNKNOWNNAME EndIf Return $hRes[0] EndFunc ;==>__IDispatch_GetIDsFromNames Func __Pointer_GetIDsFromNames($ptr = 0) Local Static $pOldGIFN = $ptr If $ptr <> 0 Then $pOldGIFN = $ptr Return $pOldGIFN EndFunc ;==>__Pointer_GetIDsFromNames Func Au3_CallByName_Init($bHook = True, $classname = "shell.application") Local Const $iOffset_GetIDsFromNames = 5 Local Static $IDispatch_GetIDsFromNames_Callback = 0 Local $oObject, $pObject, $pHook, $pOldGIFN If $bHook Then If $IDispatch_GetIDsFromNames_Callback = 0 Then $IDispatch_GetIDsFromNames_Callback = DllCallbackRegister("__IDispatch_GetIDsFromNames", "LRESULT", "ptr;ptr;ptr;dword;dword;ptr") EndIf $pHook = DllCallbackGetPtr($IDispatch_GetIDsFromNames_Callback) Else $pHook = __Pointer_GetIDsFromNames() If $pHook <= 0 Then Return ;Already Unloaded EndIf $oObject = ObjCreate($classname) $pObject = DllStructSetData(DllStructCreate("ptr"), 1, $oObject) If __HookVTableEntry($pObject, $iOffset_GetIDsFromNames, $pHook, $pOldGIFN) Then __Pointer_GetIDsFromNames($pOldGIFN) ;Save the original pointer to GetIDsFromNames If Not $bHook Then DllCallbackFree($IDispatch_GetIDsFromNames_Callback) $IDispatch_GetIDsFromNames_Callback = 0 EndIf Else ;Error EndIf $oObject = 0 EndFunc ;==>Au3_CallByName_Init ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;TESTS; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Au3_CallByName_Init() #include <ie.au3> Global $oRegistrationInfo = _IECreate() Global $aRegistrationInfo[] = ['Left=10', 'Top= 10', 'Width=450', 'Height=600'] Global $oObject = $oRegistrationInfo Local $oDictionary = ObjCreate("Scripting.Dictionary") Local $oDictionary2 = ObjCreate("Scripting.Dictionary") ;Au3_CallByName_Init($oObject) __TS_TaskPropertiesSet($oObject, $aRegistrationInfo) MsgBox(0, "Info", "Press OK to exit") $oRegistrationInfo.quit $oRegistrationInfo = 0 $oObject = 0 Sleep(1000) For $i = 1 To 10 $Au3_CallByName = "Add" $oDictionary.Au3_CallByName("test1:" & $i, "Dictionary Item: " & $i) Next $Au3_CallByName = "keys" For $sKey In $oDictionary.Au3_CallByName() For $j = 0 To 1 $Au3_CallByName = ($j = 0) ? "Item" : "Exists" ConsoleWrite($sKey & " -> " & $oDictionary.Au3_CallByName($sKey) & @CRLF) Next Next Au3_CallByName_Init(False) ;Unload Au3_CallByName_Init() Local $aRegistrationInfo[] = ['Left=1000', 'Width=450'] ConsoleWrite(@CRLF & "NEW IE" & @CRLF & @CRLF) $oRegistrationInfo = _IECreate() __TS_TaskPropertiesSet($oRegistrationInfo, $aRegistrationInfo) MsgBox(0, "Info", "Press OK to exit") $oRegistrationInfo.quit For $i = 1 To 10 $Au3_CallByName = "Add" $oDictionary2.Au3_CallByName("test2:" & $i, "Dictionary Item: " & $i) Next $Au3_CallByName = "keys" For $sKey In $oDictionary2.Au3_CallByName() For $j = 0 To 1 $Au3_CallByName = ($j = 0) ? "Item" : "Exists" ConsoleWrite($sKey & " -> " & $oDictionary2.Au3_CallByName($sKey) & @CRLF) Next Next Au3_CallByName_Init(False) ;Unload (Not Strictly Needed, Done on Script Close) Func __TS_TaskPropertiesSet(ByRef $oObject, $aProperties) Local $aTemp If IsArray($aProperties) Then For $i = 0 To UBound($aProperties) - 1 $aTemp = StringSplit($aProperties[$i], "=", 2) ; 2 -> $STR_NOCOUNT) If @error Then ContinueLoop ConsoleWrite("Command: $oObject." & $aTemp[0] & " = " & $aTemp[1] & @CRLF) $Au3_CallByName = $aTemp[0] $oObject.Au3_CallByName = $aTemp[1] ConsoleWrite("Result : " & Hex(@error) & @CRLF) ; If @error Then Return SetError(1, @error, 0) Next EndIf EndFunc ;==>__TS_TaskPropertiesSet  
×
×
  • Create New...