Jump to content

Index into an AutoItObject?


Recommended Posts

I want to assign to an AutoItObject property without hardcoding the property name.

In Javascript it would look like:

obj['propertyName']=103;

I can read access a property using Execute:

Global $ppt_val=Execute('$obj.propertyName')

But I cannot assign with:

Assign('obj.propertyName',103,4); doesnt work, nor...
Assign('$obj.propertyName',103,4)

Maybe AutoItObjects have a sooper-secret $obj.__set($name,$val) function?

I am looking for a workaround no matter how convoluted. Was thinking about maybe this might be feasible with a JScript COM helper, since I have built a AutoItObject ClassFactory anyhow. I would be able to create dynamic helper functions in JScript COM, that would stop me from writing:

Func Set__WinStyle($me,$name,$bool)
  If False Then
  ElseIf $name=='Border' Then
    $me.Border=$bool
  ElseIf $name=='Popup' Then
    $me.Popup=$bool
  ElseIf $name=='Caption' Then
    $me.Caption=$bool
;etc,etc,etc

JScript COM:

'?do=embed' frameborder='0' data-embedContent>>

Link to comment
Share on other sites

Here is how I pulled this off. First the COM lib:

; #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)}})()")
  If $VBScriptSupport = true Then $_Script.Run("set_vbscript", ObjCreate("ScriptControl"))
  Return $_Script
EndFunc

Then, in main:

Global $_ComObj_proxy
Global $_com
Global $_Js
JScriptInit()


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

Then when you create AutoItObjects, assign these as methods:

Func SetProperty__($me,$name,$val)
  $_Js.AIOSetProperty($me,$name,$val)
EndFunc
Func GetProperty__($me,$name)
  Local $v=Execute('$me.'&$name)
  Return $v
EndFunc

The assignment would look like:

$o=_AutoItObject_Create();
;blah,blah, add your methods and fields
;;And the Two new functions...
_AutoItObject_AddMethod($o,'SetProperty','SetProperty__',$ELSCOPE_PUBLIC)
_AutoItObject_AddMethod($o,'GetProperty','GetProperty__',$ELSCOPE_PUBLIC)

And your calls would look like:

$o.SetProperty('propertyName',$some_val)
Local $v=$o.GetProperty('propertyName')

Crazy to have to COM to a different language, but there you have it. :sorcerer:

Link to comment
Share on other sites

I should also make this clear that this works with PROPERTIES (and probably fields). AIO properties have this form:

_AutoItObject_AddProperty($o,"_Left",$ELSCOPE_PRIVATE,False); A private property backer (ie field), use as required
_AutoItObject_AddMethod($o,"Left","Left__ButtonStyle",True); True means public

; A property is really a function, needs $me and a second param with a default, 
; the code makes it so the default VALUE (ie False) is never used by checking @NumParams
;
Func Left__ButtonStyle($me,$value=False); ButtonStyle is the name of the class, I like to put it last, not first
  If @NumParams=2 Then ; we are assigning, hence default VALUE has been given, 
                       ; so we never see False unless it is given via $o.Left=False
    $me._Left=$value; Comment out this line for a readonly property, or put in some execute-on-assignment code
  Else ; we are being read
    Return $me._Left; return the backer, else put in some computational code that returns a value
  EndIf
EndFunc

;;; Usage
$o.Left=10    ;assign
$val=$o.Left ; read
Edited by MarkRobbins
Link to comment
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
 Share

×
×
  • Create New...