AutoHotkey Community

It is currently May 26th, 2012, 11:59 pm

All times are UTC [ DST ]




Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 1036 posts ]  Go to page Previous  1 ... 11, 12, 13, 14, 15, 16, 17 ... 70  Next
Author Message
 Post subject:
PostPosted: September 28th, 2009, 11:32 pm 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
Lexikos wrote:
Quote:
CO := Object(), CO.COMObj := param, CO.Base := COBase
I'd understand if you find it easier to follow this way, but note that the shorter method should also be marginally faster:
Code:
CO := Object("COMObj", param, "base", COBase)

Quote:
If InStr(func, "_")=1
return COMo(COM_Invoke(obj.COMObj, SubStr(func,2), prm0, prm1, prm2, prm3, prm4, prm5))

:lol: I already changed it in the script above while you were writing this post because of this (bug?): http://www.pasteall.org/8220/autoit/embedded
Why doesn't it call __Delete for obj1? CO is local and should get freed up automatically after function exits (so it shouldn't affect the Object's reference count etc). :?
Edit: I guess it's related to the limitations listed in the Objects documentation. If it is, n/m.

Lexikos wrote:
IIRC, the global variable COM_VT should be 9 if COM_Invoke's return value is an object. Using that, wrapping objects can be automatic, and reliable when a function may or may not return an object.

Thanks, that's definitely better than the current/ugly prefix method so now no need for @XX either :D -- edit: that worked really well! (updated examples and functions) Thanks again.

Edit:
Crashes AHK_L:
Code:
1 ? Object() : 0


Last edited by temp01 on October 1st, 2009, 6:58 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2009, 2:03 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
:D Thank you temp01! This is exactly the functionallity I was looking for:
Code:
COM_Init()
pwb := COMo("InternetExplorer.Application")
pwb.visible := "True"
pwb.Navigate2("www.google.com")
While(pwb.readystate <> 4)
   Sleep, 10
pwb.document.all.q.value := "AutoHotkey"
pwb.document.forms[0].submit()
While(pwb.busy)
   Sleep, 10
pwb.document.all.tags("a")[30].click()
pwb := "", COM_Term()
Return

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Last edited by jethrow on September 30th, 2009, 8:10 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2009, 3:53 am 
Offline

Joined: June 26th, 2006, 6:14 pm
Posts: 1379
Location: USA
temp01 and I was messing around and found out the var assignment is broken, it puts a null char at the end. i found it because a message box was truncated, and he had a simple way to reproduce it.

Code:
;author: temp01
COM_Init()
html := COMo(COM_CreateObject("htmlfile"))
html.write("<b>test</b>")
Msgbox % Strlen(html.all[0].innerText)
Msgbox % Strlen(var:=html.all[0].innerText)

html := "" ; free it!
COM_Term()

_________________
Image
ʞɔпɟ əɥʇ ʇɐɥʍ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2009, 4:11 am 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
All meta-functions are bugged:
Code:
obj := Object("base", Object("__Get", "GetVal", "__Set", "SetVal", "__Call", "Call"))

Msgbox % "Testing Getter:`n`n"
   . Strlen(obj.blah) "`n"
   . Strlen(var:=obj.blah) "`n"
   . obj.blah

Msgbox % "Testing Setter:`n`n"
   . Strlen(obj.blah:="xy") "`n"
   . Strlen(var:=obj.blah:="xy") "`n"
   . (obj.blah:="xy")
   
Msgbox % "Testing Call:`n`n"
   . Strlen(obj.xyz()) "`n"
   . Strlen(var:=obj.xyz()) "`n"
   . (obj.xyz())

GetVal(obj, name){
   Return "test"
}
SetVal(obj, name, val){
   return "setter"
}
Call(obj, func){
   return "objcall"
}


Edit:
Same bug?
Code:
Msgbox % SplitPath("C:\Windows\explorer.exe").FileName ; strange chars
Msgbox % SplitPath("C:\Windows\explorer.exe").Dir ; strange chars

Msgbox % var := SplitPath("C:\Windows\explorer.exe").FileName ; ok
Msgbox % var := SplitPath("C:\Windows\explorer.exe").Dir ; ok

SplitPath(InputVar){ ; [, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive]
   SplitPath, InputVar, fn, d, ext, name, drv
   Return Object("FileName", fn, "Dir", d, "Extension", ext, "NameNoExt", name, "Drive", drv)
}


Last edited by temp01 on September 29th, 2009, 8:28 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2009, 8:24 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
Here's a little wrapper that sets the default __call to call existing functions with the object's field as the first param.

... the code explains better than anything:
Code:
"".base.__Call := "Default_Call"

var := A_ScriptDir

MsgBox % var.StrLen()

MsgBox % var.SubStr(3, 8)

MsgBox % var.FileExist().InStr("D")

MsgBox % var.SubStr(var.RegExMatch("[^\\]*$"))

MsgBox % "AutoHotkey Help".WinExist()

MsgBox % "NumLock".GetKeyState("T")

ExitApp

Default_Call( p1, func, p2="vT_NoNe", p3="vT_NoNe", p4="vT_NoNe", p5="vT_NoNe", p6="vT_NoNe", p7="vT_NoNe" ) {
   a := 8, p := isFunc(func) - 1 ;required params
   toolTip % A_EventInfo
   while --a >= p
   {
      if (p%a% = "vT_NoNe")
         continue
      if a = 1
         return %func%(p1)
      if a = 2
         return %func%(p1, p2)
      if a = 3
         return %func%(p1, p2, p3)
      if a = 4
         return %func%(p1, p2, p3, p4)
      if a = 5
         return %func%(p1, p2, p3, p4, p5)
      if a = 6
         return %func%(p1, p2, p3, p4, p5, p6)
      if a = 7
         return %func%(p1, p2, p3, p4, p5, p6, p7)
   }
}

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2009, 9:57 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Very nice temp01 and infogulch, thanks for sharing :)

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 30th, 2009, 1:21 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
__Get/__Set doesn't support parameters? Anyway, better use this in case of __Set:
Code:
COMo_SetVal(obj, name, val){
   return COM_Invoke(obj.COMObj, name . "=", val)
}


I expected this come after implementation of Unicode, but now dot syntax is allowed, it appears more natural to me to implement COM into AHK's engine than making COM.ahk to accord with it. Looks like Lexikos was enjoying the time of JScript Object/Array, then the next may be the time of VBScript Variant/SafeArray.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 30th, 2009, 6:16 am 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
Sean wrote:
__Get/__Set doesn't support parameters?
Hmm, how, do you mean? You use __Call if you want to pass parameters: something.method(param1, param2)

Sean wrote:
Anyway, better use this in case of __Set:
Code:
COMo_SetVal(obj, name, val){
   return COM_Invoke(obj.COMObj, name . "=", val)
}

Thanks, changed.


Arrays!
Code:
; Array Lib
Array(p1="……", p2="……", p3="……", p4="……", p5="……", p6="……"){
   static ArrBase
   If !ArrBase
      ArrBase := Object("len", "Array_Length", "indexOf", "Array_indexOf", "join", "Array_Join"
      , "append", "Array_Append", "insert", "Array_Insert", "delete", "Array_Delete"
      , "sort", "Array_sort", "reverse", "Array_Reverse", "unique", "Array_Unique"
      , "extend", "Array_Extend", "copy", "Array_Copy", "pop", "Array_Pop")

   arr := Object("base", ArrBase)
   While (_:=p%A_Index%)!="……" && A_Index<=6
      arr[A_Index] := _
   Return arr
}

Array_indexOf(arr, val){
   Loop % arr.len()
      If(arr[A_Index]=val)
         Return A_Index
   Return 0
}
Array_Join(arr, sep="`n"){
   Loop, % arr.len()
      str .= arr[A_Index] sep
   StringTrimRight, str, str, % StrLen(sep)
   return str
}
Array_Copy(arr){
   Return Array().extend(arr)
}

Array_Append(arr, p1="……", p2="……", p3="……", p4="……", p5="……", p6="……"){
   Return arr.insert(arr.len()+1, p1, p2, p3, p4, p5, p6)
}
Array_Insert(arr, index, p1="……", p2="……", p3="……", p4="……", p5="……", p6="……"){
   While (_:=p%A_Index%)!="……" && A_Index<=6
      arr._Insert(index + (A_Index-1), _)
   Return arr
}
Array_Reverse(arr){
   arr2 := Array()
   Loop, % len:=arr.len()
      arr2[len-(A_Index-1)] := arr[A_Index]
   Return arr2
}
Array_Sort(arr, func="Array_CompareFunc"){
   n := arr.len(), swapped := true
   while swapped {
      swapped := false
      Loop, % n-1 {
         i := A_Index
         if %func%(arr[i], arr[i+1], 1) > 0 ; standard ahk syntax for sort callout functions
            arr.insert(i, arr[i+1]).delete(i+2), swapped := true
      }
      n--
   }
   Return arr
}
Array_Unique(arr, func="Array_CompareFunc"){   ; by infogulch
   i := 0
   while ++i < arr.len(), j := i + 1
      while j <= arr.len()
         if !%func%(arr[i], arr[j], i-j)
            arr.delete(j) ; j comes after
         else
            j++ ; only increment to next element if not removing the current one
   Return arr
}
Array_CompareFunc(a, b, c){
; this setup is compatible with the sort command's syntax
; if a > b return positive
; if a = b return false
; if a < b return negative
; c is element offset (a.pos - b.pos)
   return a > b ? 1 : a = b ? 0 : -1
}

Array_Extend(arr, p1="……", p2="……", p3="……", p4="……", p5="……", p6="……"){
   While (_:=p%A_Index%)!="……" && A_Index<=6
      If _.len
         Loop, % _.len()
            arr.append(_[A_Index])
      Else
         Loop, % %_%0
            arr.append(%_%%A_Index%)
   Return arr
}
Array_Pop(arr){
   Return arr.delete(arr.len())
}
Array_Delete(arr, p1="……", p2="……", p3="……", p4="……", p5="……", p6="……"){
   While (_:=p%A_Index%)!="……" && A_Index<=6
      arr._Remove(_)
   Return arr
}

Array_Length(arr){
   len := arr._MaxIndex()
   Return len="" ? 0 : len
}


Example:
Code:
arr := Array("b", "a", "c") ; create an array with 3 items

arr[2] := "a - new"         ; change 2nd item
arr[1] := "bac"             ; change 1st item

arr.append("new", "items")  ; add 2 more items
arr.insert(2, "xyz")        ; insert "xyz" before the 2nd item ("a - new")

Msgbox, % arr.join("`n")    ; join the array and show it in a msgbox
Msgbox, % arr.append("z").sort().reverse().join("`n")   ; append another item, sort, reverse, join

Loop, % arr.len()
   Msgbox, % arr[A_Index]


Thanks to infogulch for Array_Unique and for adding the callback option to Array_Sort :)


Last edited by temp01 on October 1st, 2009, 10:45 pm, edited 6 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 30th, 2009, 6:42 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
temp01 wrote:
Sean wrote:
__Get/__Set doesn't support parameters?
Hmm, how, do you mean? You use __Call if you want to pass parameters: something.method(param1, param2)
Yes, I noticed can use __Call for that, but doing it via __Call is somewhat pointless, with __Set, as it just neglect the clarity of this dot syntax. COM.ahk struggled to overcome the inherent ambiguity inside the script and almost succeeded, however not completely.
Code:
Dictionary.Item("key") := "value"


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 30th, 2009, 7:54 am 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
Sean wrote:
Yes, I noticed can use __Call for that, but doing it via __Call is somewhat pointless, with __Set, as it just neglect the clarity of this dot syntax. COM.ahk struggled to overcome the inherent ambiguity inside the script and almost succeeded, however not completely.
Code:
Dictionary.Item("key") := "value"

Ah, I see. Yes, you're right; that doesn't work with AHK_L/COMo. Dictionary.Item("key", "value") works.

Anyway, is it possible to use Dic.Keys() or Dic.Items() with this:
Code:
COM_Init()
Dic := COMo("Scripting.Dictionary")

Dic.Add("Key1", "Value1")
Dic.Add("Key2", "Value2")

If Dic.Exists("Key2") {
   Loop, % Dic.Count
      ; how would use Dic.Keys() or Dic.Items() :/
}

Dic := ""
COM_Term()

I guess they return a SafeArray but how would you use it with COM.ahk/COM_Invoke?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 30th, 2009, 8:48 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
temp01 wrote:
I guess they return a SafeArray but how would you use it with COM.ahk/COM_Invoke?
COM.ahk doesn't provide functions to retrieve the data from SafeArray, leave it to users as there are various ways to do it. My preferred way is to do manually in this case as Dic.Keys() and Dic.Items() return SafeArray of variants. BTW, you can use also enumerator Dic._NewEnum() and enumerate keys using COM_Enumerate().
Code:
psa := Dic.Keys()
pva := NumGet(psa+12)
Loop, % NumGet(psa+16)
   sKeys .= NumGet(pva+(A_Index-1)*16,0,"Ushort")=8 ? COM_Ansi4Unicode(NumGet(pva+A_Index*16-8)) "`n" : NumGet(pva+A_Index*16-8) "`n"
COM_SafeArrayDestroy(psa)
MsgBox % sKeys


Code:
penm := COM_Invoke(pdic, "_NewEnum")
While   COM_Enumerate(penm, sKey)=0
   sKeys .= sKey "`n"
COM_Release(penm)
MsgBox % sKeys


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 30th, 2009, 10:25 am 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
Sean wrote:
temp01 wrote:
I guess they return a SafeArray but how would you use it with COM.ahk/COM_Invoke?
COM.ahk doesn't provide functions to retrieve the data from SafeArray, leave it to users as there are various ways to do it. My preferred way is to do manually in this case as Dic.Keys() and Dic.Items() return SafeArray of variants. BTW, you can use also enumerator Dic._NewEnum() and enumerate keys using COM_Enumerate().

Thanks, COM_Enumerate works well :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 1st, 2009, 5:38 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
I found a bug with the return value setup of meta functions:

Edit: Clarified problem. It seems to be a problem with expression variable dereference. Maybe similar to: GuiControl + OnMessage = bad use of deref buffer? ?
Code:
MsgBox % "Call: " Test() ; this should look like:  "Call: return value"

Test() {
   ; obj is freed since it is not returned to the caller
   obj := Object( "name", A_ThisFunc " local var", "base", Object( "__delete", "ObjDelete" ) )
   return "return value"
}

ObjDelete( obj ) {
   ;a := "x" ; success
   ;a = % "x" ; success
   ;a := "" ; success
   ;a = %b% ; success
   a := A_AhkPath ;fail
   ;a := b ;fail
}

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 2nd, 2009, 8:22 am 
Offline

Joined: June 26th, 2006, 6:14 pm
Posts: 1379
Location: USA
how can i make this work?

Code:
e := object()
func(&e)
MsgBox % e.text
return


func(ObjAddress){
   ; some magic codes go here
   obj := ???  ObjAddress ???
   ;end magic codes
   if IsObj(obj)
      obj.text := "some text"
}

_________________
Image
ʞɔпɟ əɥʇ ʇɐɥʍ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 2nd, 2009, 3:58 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
@ahklerner
I think this could be possible using LowLevel functionality, but we do not know the structure of objects yet, you might need to wait until Lexikos releases LowLevel update.
Why do you want to do that by address?
Code:
e := object()
func(e)
MsgBox % e.text
return


func(Obj){
    obj.text := "some text"
}

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 1036 posts ]  Go to page Previous  1 ... 11, 12, 13, 14, 15, 16, 17 ... 70  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group