├── Tests ├── README.md ├── Unit │ ├── Constraint │ │ ├── IsNull.au3 │ │ ├── IsTrue.au3 │ │ ├── IsFalse.au3 │ │ ├── IsEqual.au3 │ │ ├── IsType.au3 │ │ ├── IsIdentical.au3 │ │ ├── Constraint.au3 │ │ └── LogicalNot.au3 │ └── assert.au3 ├── Extendable class.au3 ├── helpers.au3 ├── Exporter │ └── Exporter.au3 ├── Collection class.au3 ├── Test.au3 └── Dev.au3 ├── CONTRIBUTING.md ├── Examples ├── 05 - Advanced - ROT.vbs ├── 03 - Basic - Usage in other objects.au3 ├── 01 - Basic - Properties.au3 ├── 05 - Advanced - ROT.au3 ├── 02 - Basic - Accessors.au3 └── 04 - Advanced - Practical example.au3 ├── LICENSE ├── AutoItObject_Internal_Example.au3 ├── README.md ├── AutoItObject_Internal_ROT.au3 ├── docs └── index.md ├── CHANGELOG.md └── AutoItObject_Internal.au3 /Tests/README.md: -------------------------------------------------------------------------------- 1 | **Unit** and **Exporter** folders are a attempt to dublicate parts of PHPUnit, but as functions only, as testing the object library with itself seems like a bad idea. -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Using the issue tracker 4 | 5 | The issue tracker on GitHub is the preferred channel for bug reports and feature requests. 6 | 7 | ## Pull requests 8 | 9 | -------------------------------------------------------------------------------- /Tests/Unit/Constraint/IsNull.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | 3 | Func Au3UnitConstraintIsNull_Matches($other) 4 | return $other == Null 5 | EndFunc 6 | 7 | Func Au3UnitConstraintIsNull_ToString($other) 8 | Return "is null" 9 | EndFunc -------------------------------------------------------------------------------- /Tests/Unit/Constraint/IsTrue.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | 3 | Func Au3UnitConstraintIsTrue_Matches($other, $a) 4 | Return $other==True 5 | EndFunc 6 | 7 | Func Au3UnitConstraintIsTrue_ToString($value) 8 | Return "is true" 9 | EndFunc -------------------------------------------------------------------------------- /Tests/Unit/Constraint/IsFalse.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | 3 | Func Au3UnitConstraintIsFalse_Matches($other, $a) 4 | Return $other==False 5 | EndFunc 6 | 7 | Func Au3UnitConstraintIsFalse_ToString($value) 8 | Return "is false" 9 | EndFunc -------------------------------------------------------------------------------- /Examples/05 - Advanced - ROT.vbs: -------------------------------------------------------------------------------- 1 | Dim objXL 2 | On Error Resume Next 3 | Set objXL = GetObject("AutoIt3.COM.Test") 4 | If IsObject(objXL) Then 5 | MsgBox objXL.name, 0, "Success" 6 | Else 7 | MsgBox "Error: Object could not be found.", 48, "Failure" 8 | End If 9 | Set objXL = Nothing 10 | -------------------------------------------------------------------------------- /Tests/Unit/Constraint/IsEqual.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | ;https://github.com/sebastianbergmann/phpunit/blob/master/src/Framework/Constraint/IsEqual.php 3 | ;shallow implementation 4 | 5 | Func Au3UnitConstraintIsEqual_Matches($other, $exspected) 6 | Return $exspected == $other 7 | EndFunc 8 | 9 | Func Au3UnitConstraintIsEqual_ToString($a) 10 | Return StringFormat("is equal to %s", $a) 11 | EndFunc -------------------------------------------------------------------------------- /Tests/Unit/Constraint/IsType.au3: -------------------------------------------------------------------------------- 1 | Func Au3UnitConstraintIsType_ToString($value) 2 | Return StringFormat('is of type "%s"', $value) 3 | EndFunc 4 | 5 | Func Au3UnitConstraintIsType_FailureDescription($constraint, $other, $exspected) 6 | Local $toString = Call("Au3UnitConstraint" & $constraint & "_ToString", $other) 7 | If @error = 0xDEAD And @extended = 0xBEEF Then $toString = Call("Au3UnitConstraintConstraint_ToString", $other) 8 | Return Au3ExporterExporter_Export($exspected) & " " & $toString 9 | EndFunc 10 | 11 | Func Au3UnitConstraintIsType_Matches($other, $value) 12 | Return VarGetType($value) == $other 13 | EndFunc -------------------------------------------------------------------------------- /Tests/Extendable class.au3: -------------------------------------------------------------------------------- 1 | #include "..\AutoItObject_Internal.au3" 2 | 3 | Func Class($extension=Null) 4 | Local Static $extensions[0] 5 | 6 | If @NumParams = 0 Then 7 | Local $class = IDispatch() 8 | For $extension In $extensions 9 | Call($extension, $class) 10 | Next 11 | $class.__lock() 12 | Return $class 13 | Else 14 | Local $count = UBound($extensions) 15 | ReDim $extensions[$count+1] 16 | $extensions[$count] = $extension 17 | EndIf 18 | EndFunc 19 | 20 | Func ClassExtension01($class) 21 | $class.a = "test1" 22 | $class.b = "test2" 23 | $class.c = 200 24 | EndFunc 25 | 26 | Class(ClassExtension01) 27 | $class = Class() 28 | MsgBox(0, "", $class.a) -------------------------------------------------------------------------------- /Examples/03 - Basic - Usage in other objects.au3: -------------------------------------------------------------------------------- 1 | #cs ---------------------------------------------------------------------------- 2 | 3 | AutoIt Version: 3.3.14.2 4 | Author: genius257 5 | 6 | #ce ---------------------------------------------------------------------------- 7 | #include "..\AutoItObject_Internal.au3" 8 | 9 | $IDispatch = IDispatch() 10 | $IDispatch.__defineGetter("a", _MsgBox) 11 | 12 | $oSC = ObjCreate("ScriptControl") 13 | $oSC.language = "JScript" 14 | 15 | #AutoIt3Wrapper_Run_Au3Check=N;need this line for now 16 | ($oSC.Eval("Function('e','return e.a;')"))($IDispatch);AutoIt calls JavaScript Function that invokes property a's getter 17 | 18 | Func _MsgBox() 19 | Return MsgBox(0, "_MsgBox", "test") 20 | EndFunc -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 genius257 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Examples/01 - Basic - Properties.au3: -------------------------------------------------------------------------------- 1 | #cs ---------------------------------------------------------------------------- 2 | 3 | AutoIt Version: 3.3.14.2 4 | Author: genius257 5 | 6 | #ce ---------------------------------------------------------------------------- 7 | 8 | #include "..\AutoItObject_Internal.au3" 9 | 10 | $oIDispatch = IDispatch() 11 | 12 | $oIDispatch.a = "a" 13 | $oIDispatch.A = "A" 14 | MsgBox(0, @ScriptName, "Properties are case sensetive"&@CRLF&"$oIDispatch.a: "&$oIDispatch.a&@CRLF&"$oIDispatch.A: "&$oIDispatch.A) 15 | $oIDispatch.__unset("a") 16 | $oIDispatch.__unset("A") 17 | 18 | Global $aArray = [1,2,3] 19 | $oIDispatch.array = $aArray 20 | 21 | $oIDispatch.binary = Binary(123) 22 | 23 | $oIDispatch.bool = True 24 | 25 | $oIDispatch.dllStruct = DllStructCreate("BYTE") 26 | 27 | $oIDispatch.function = MsgBox 28 | 29 | $oIDispatch.float = 12.3 30 | 31 | $oIDispatch.int = 123 32 | 33 | $oIDispatch.keyword = Default 34 | 35 | $oIDispatch.object = ObjCreate("ScriptControl") 36 | 37 | $oIDispatch.pointer = ptr(123);ptr is converted to int. Not much i can do about that. 38 | 39 | $oIDispatch.string = "123" 40 | 41 | For $key In $oIDispatch.__keys 42 | ConsoleWrite("$oIDispatch."&$key&" : "&VarGetType(Execute("$oIDispatch."&$key))&@CRLF) 43 | Next -------------------------------------------------------------------------------- /Tests/helpers.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | #include 3 | ;~ Func IDispatch_ 4 | 5 | ;http://php.net/manual/en/function.str-replace.php 6 | Func PHP_str_replace($search, $replace, $subject) 7 | Local $replacements = 0, $i, $j 8 | Local $Tsearch = IsArray($search) 9 | $search = ArrayWrap($search) 10 | Local $Treplace = IsArray($replace) 11 | $replace = ArrayWrap($replace) 12 | 13 | If (Not $Tsearch) And $Treplace Then Dim $replace = ["Array"] 14 | If $Tsearch And (Not $Treplace) Then 15 | ReDim $replace[UBound($search)] 16 | For $i=1 To UBound($replace)-1 17 | $replace[$i]=$replace[0] 18 | Next 19 | EndIf 20 | If UBound($search) > UBound($replace) Then 21 | Local $Ireplace = UBound($replace) 22 | ReDim $replace[UBound($search)] 23 | For $i=$Ireplace To UBound($replace)-1 24 | $replace[$i] = "" 25 | Next 26 | EndIf 27 | 28 | Local $Tsubject = IsArray($subject) 29 | $subject = ArrayWrap($subject) 30 | For $i=0 To UBound($subject)-1 31 | If Not IsString($subject[$i]) Then Return SetError(1, $replacements, $Tsubject?$subject:$subject[0]) 32 | For $j=0 To UBound($search)-1 33 | $subject[$i] = StringReplace($subject[$i], $search[$j], $replace[$j], 0, $STR_CASESENSE) 34 | $replacements+=@extended 35 | If @error<>0 Then Return SetError(@error, $replacements, $Tsubject?$subject:$subject[0]) 36 | Next 37 | Next 38 | 39 | Return SetError(0, $replacements, $Tsubject?$subject:$subject[0]) 40 | EndFunc 41 | 42 | Func ArrayWrap($value) 43 | If IsArray($value) Then Return $value 44 | Local $return = [$value] 45 | Return $return 46 | EndFunc -------------------------------------------------------------------------------- /AutoItObject_Internal_Example.au3: -------------------------------------------------------------------------------- 1 | #include "AutoItObject_Internal.au3" 2 | 3 | ;~ #AutoIt3Wrapper_UseX64=Y 4 | ;~ #AutoIt3Wrapper_Run_Au3Check=N 5 | 6 | $AutoItError = ObjEvent("AutoIt.Error", "ErrFunc") ; Install a custom error handler 7 | 8 | Func ErrFunc($oError) 9 | ConsoleWrite("!>COM Error !"&@CRLF&"!>"&@TAB&"Number: "&Hex($oError.Number,8)&@CRLF&"!>"&@TAB&"Windescription: "&StringRegExpReplace($oError.windescription,"\R$","")&@CRLF&"!>"&@TAB&"Source: "&$oError.source&@CRLF&"!>"&@TAB&"Description: "&$oError.description&@CRLF&"!>"&@TAB&"Helpfile: "&$oError.helpfile&@CRLF&"!>"&@TAB&"Helpcontext: "&$oError.helpcontext&@CRLF&"!>"&@TAB&"Lastdllerror: "&$oError.lastdllerror&@CRLF&"!>"&@TAB&"Scriptline: "&$oError.scriptline&@CRLF) 10 | EndFunc ;==>ErrFunc 11 | 12 | $oItem = IDispatch() 13 | 14 | $oItem.a = "a" 15 | $oItem.b = "b" 16 | $oItem.c = "c" 17 | $oItem.z = "z" 18 | 19 | $oItem.__unset("z") 20 | 21 | $oItem.__defineGetter('a',Getter) 22 | $oItem.__defineSetter('a',Setter) 23 | 24 | $oItem.ab = $oItem.a&$oItem.b 25 | $oItem.abc = $oItem.a&$oItem.b&$oItem.c 26 | $oItem.abc = $oItem.abc&$oItem.abc 27 | 28 | $oItem.f = Test 29 | Execute("($oItem.f)('a')");we use execute, due to Au3Check bug. For more, see: https://www.autoitscript.com/trac/autoit/ticket/3560 30 | MsgBox(0, "", "a: "&$oItem.a&@CRLF&"b: "&$oItem.b&@CRLF&"c: "&$oItem.c&@CRLF&"ab: "&$oItem.ab&@CRLF&"abc: "&$oItem.abc) 31 | $oItem.f = MsgBox 32 | Call($oItem.f,0,"","test") 33 | 34 | $oItem.__freeze();locking the object 35 | 36 | $oItem.z = "z"; this will fail because of lock, see console. Also @error is set to non zero 37 | 38 | Func Test($string) 39 | MsgBox(0, "UserFunction: Test", $string) 40 | EndFunc 41 | 42 | Func Getter($oThis) 43 | Return $oThis.val&$oThis.parent.b 44 | EndFunc 45 | 46 | Func Setter($oThis) 47 | $oThis.val=$oThis.ret 48 | EndFunc 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AutoItObject Internal 2 | Provides easy object creation via IDispatch interface. 3 | 4 | **Example** 5 | ```AutoIt 6 | #include "AutoItObject_Internal.au3" 7 | $myCar = IDispatch() 8 | $myCar.make = 'Ford' 9 | $myCar.model = 'Mustang' 10 | $myCar.year = 1969 11 | $myCar.__defineGetter('DisplayCar', DisplayCar) 12 | 13 | Func DisplayCar($oThis) 14 | Return 'A Beautiful ' & $oThis.parent.year & ' ' & $oThis.parent.make & ' ' & $oThis.parent.model 15 | EndFunc 16 | 17 | MsgBox(0, "", $myCar.DisplayCar) 18 | ``` 19 | 20 | > The way this library implements objects is to mimic javascript object behavior and functionality. 21 | > 22 | > This approach was chosen for it's ease of use and for developers to be able to "jump right in" without learning a whole new syntax. 23 | 24 | ## Comparing AutoItObject Internal to Other options 25 | 26 | | Feature | AutoItObject-Internal | [AutoItObject UDF](https://www.autoitscript.com/forum/topic/110379-autoitobject-udf/) | [OOPEAu3](https://github.com/cosote/OOPEAu3) | [Map](https://www.autoitscript.com/autoit3/docs/intro/lang_variables.htm#ArrayMaps) | 27 | | - | - | - | - | - | 28 | | getters | :heavy_check_mark: | :x: | :x: | :x: | 29 | | setters | :heavy_check_mark: | :x: | :x: | :x: | 30 | | destructors | :heavy_check_mark::warning:¹ | :heavy_check_mark: | :question: | :x: | 31 | | inheritance | :heavy_check_mark::warning:² | :heavy_check_mark: | :x: | :x: | 32 | | supports all au3 var types | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | 33 | | native windows dlls and AutoIt only | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | 34 | | dynamic number of method parameters | :heavy_check_mark: | :x: | :heavy_minus_sign:³ | :x: | 35 | | registering objects in the ROT | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | 36 | | extending/editing UDF object logic | AutoIt | c++ | AutoIt | :x: | 37 | 38 | ¹ destructors are not triggered on script shutdown. 39 | 40 | ² this is done by using the __assign method see https://github.com/genius257/AutoItObject-Internal/issues/1 41 | 42 | ³ only for the constructor 43 | -------------------------------------------------------------------------------- /Examples/05 - Advanced - ROT.au3: -------------------------------------------------------------------------------- 1 | #include "..\AutoItObject_Internal.au3" 2 | #include "..\AutoItObject_Internal_ROT.au3" 3 | 4 | Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") 5 | If @error <> 0 Then 6 | ConsoleWriteError("Could not set AuotIt3 general COM error handler") 7 | Exit 1 8 | EndIf 9 | 10 | Func _ErrFunc($oError) 11 | ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ 12 | @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ 13 | @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ 14 | @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ 15 | @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ 16 | @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ 17 | @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ 18 | @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ 19 | @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ 20 | @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) 21 | EndFunc ;==>_ErrFunc 22 | 23 | $oIDispatch = IDispatch() 24 | $oIDispatch.name = "Shared IDispatch Object" 25 | Global Const $dwID = _AOI_ROT_register($oIDispatch, "AutoIt3.COM.Test", True) 26 | If @error <> 0 Then 27 | ConsoleWriteError("Could not register in the ROT"&@CRLF) 28 | Exit 29 | EndIf 30 | 31 | Opt("GUIOnEventMode", 1) 32 | $hWnd = GUICreate("", 700, 320) 33 | GUISetOnEvent(-3, "_MyExit") 34 | GUICtrlCreateButton("revoke", 10, 10, 100, 30) 35 | GUICtrlSetOnEvent(-1, "_revoke") 36 | GUICtrlCreateButton("test", 10, 50, 100, 30) 37 | GUICtrlSetOnEvent(-1, "_test") 38 | GUISetState(@SW_SHOW, $HWnd) 39 | 40 | While 1 41 | Sleep(10) 42 | WEnd 43 | 44 | Func _revoke() 45 | ConsoleWrite("_AOI_ROT_revoke: "&_AOI_ROT_revoke($dwID)&@CRLF) 46 | EndFunc 47 | 48 | Func _test() 49 | ShellExecute(StringRegExpReplace(@ScriptFullPath, ".\w+$", ".vbs"), "", @ScriptDir) 50 | EndFunc 51 | 52 | Func _MyExit() 53 | $oIDispatch = 0 54 | Exit 55 | EndFunc 56 | -------------------------------------------------------------------------------- /Examples/02 - Basic - Accessors.au3: -------------------------------------------------------------------------------- 1 | #cs ---------------------------------------------------------------------------- 2 | 3 | AutoIt Version: 3.3.14.2 4 | Author: genius257 5 | 6 | #ce ---------------------------------------------------------------------------- 7 | #include "..\AutoItObject_Internal.au3" 8 | 9 | $AutoItError = ObjEvent("AutoIt.Error", "ErrFunc") ; Install a custom error handler 10 | Func ErrFunc($oError) 11 | ConsoleWrite("!>COM Error !"&@CRLF&"!>"&@TAB&"Number: "&Hex($oError.Number,8)&@CRLF&"!>"&@TAB&"Windescription: "&StringRegExpReplace($oError.windescription,"\R$","")&@CRLF&"!>"&@TAB&"Source: "&$oError.source&@CRLF&"!>"&@TAB&"Description: "&$oError.description&@CRLF&"!>"&@TAB&"Helpfile: "&$oError.helpfile&@CRLF&"!>"&@TAB&"Helpcontext: "&$oError.helpcontext&@CRLF&"!>"&@TAB&"Lastdllerror: "&$oError.lastdllerror&@CRLF&"!>"&@TAB&"Scriptline: "&$oError.scriptline&@CRLF) 12 | EndFunc ;==>ErrFunc 13 | ;we need the error handler to prevent crash when IDispatch raises exceptions and the like 14 | 15 | $oIDispatch = IDispatch() 16 | 17 | $oIDispatch.string = "123";optional to define property first 18 | 19 | $oIDispatch.__defineGetter("string", Getter1) 20 | $oIDispatch.__defineSetter("string", Setter1) 21 | 22 | MsgBox(0, "", $oIDispatch.string); invoke getter 23 | $oIDispatch.string = "321"; invoke setter (this will fail) 24 | If @error<>0 Then MsgBox(0, "", "setter set @error<>0"&@CRLF&"see console for more information") 25 | 26 | ;Replace accessors 27 | $oIDispatch.__defineGetter("string", Getter2) 28 | $oIDispatch.__defineSetter("string", Setter2) 29 | 30 | MsgBox(0, "", $oIDispatch.string); invoke getter as before 31 | MsgBox(0, "", $oIDispatch.string('"'));invoke getter with parameters. Try and replace the string if you want 32 | $oIDispatch.string = "321"; invoke setter 33 | MsgBox(0, "", $oIDispatch.string);get the new value after it has been manipulated by the getter 34 | 35 | Func Getter1() 36 | Return "static string return" 37 | EndFunc 38 | 39 | Func Getter2($AccessorObject) 40 | If $AccessorObject.arguments.length=0 Then Return "Simon says: " & $AccessorObject.val 41 | If $AccessorObject.arguments.length>1 Then Return SetError(1, 1, 0) 42 | Return $AccessorObject.arguments.values[0]&$AccessorObject.val&$AccessorObject.arguments.values[0] 43 | EndFunc 44 | 45 | Func Setter1() 46 | Return SetError(1, 1, 0);set @error<>0 to invoke exception 47 | EndFunc 48 | 49 | Func Setter2($AccessorObject) 50 | If Not IsString($AccessorObject.val) Then Return SetError(1, 1, 0);in this example we only allow the value to be a string 51 | $AccessorObject.val = $AccessorObject.ret 52 | EndFunc -------------------------------------------------------------------------------- /Tests/Unit/Constraint/IsIdentical.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | ;https://github.com/sebastianbergmann/phpunit/blob/master/src/Framework/Constraint/IsIdentical.php 3 | 4 | Func Au3UnitConstraintIsIdentical_Evaluate($other, $description = "", $returnResult = false, $line = Null, $exspected = Null) 5 | Local $success = $exspected == $other 6 | 7 | If $returnResult Then Return $success 8 | 9 | If Not $success Then 10 | ;~ Local $f = Null 11 | 12 | ;FIXME: look into implementing some of the original functionallity, @see https://github.com/sebastianbergmann/phpunit/blob/master/src/Framework/Constraint/IsIdentical.php#L84-L102 13 | Call("Au3UnitConstraintIsIdentical_Fail", $other, $description, Null, $line, $exspected) 14 | If @error = 0xDEAD And @extended = 0xBEEF Then Call("Au3UnitConstraintConstraint_Fail", "IsIdentical", $other, $description, Null, $line) 15 | If @error = 0xDEAD And @extended = 0xBEEF Then Exit MsgBox(0, "Au3Unit", "Au3UnitConstraintConstraint_Fail function is missing"&@CRLF&"Exitting") + 1 16 | Return SetError(@error) 17 | EndIf 18 | EndFunc 19 | 20 | Func Au3UnitConstraintIsIdentical_Fail($other, $description, $comparisonFailure, $line, $exspected) 21 | Local $failureDescription = Call("Au3UnitConstraintIsIdentical_FailureDescription", $other, $exspected) 22 | If @error = 0xDEAD And @extended = 0xBEEF Then $failureDescription = Call("Au3UnitConstraintConstraint_FailureDescription", "IsIdentical", $other) 23 | $failureDescription = StringFormat("Failed asserting that %s.", $failureDescription) 24 | 25 | Local $additionalFailureDescription = Call("Au3UnitConstraintIsIdentical_AdditionalFailureDescription", $other) 26 | If @error = 0xDEAD And @extended = 0xBEEF Then $additionalFailureDescription = Call("Au3UnitConstraintConstraint_AdditionalFailureDescription", $other) 27 | 28 | If $additionalFailureDescription Then $failureDescription &= @CRLF & $additionalFailureDescription 29 | 30 | If Not ($description = "") Then $failureDescription = $description & @CRLF & $failureDescription 31 | 32 | ConsoleWriteError($failureDescription&@CRLF&@ScriptFullPath&":"&$line&@CRLF) 33 | Return SetError(1) 34 | EndFunc 35 | 36 | Func Au3UnitConstraintIsIdentical_FailureDescription($other, $exspected) 37 | Local $toString = Call("Au3UnitConstraintIsIdentical_ToString", $exspected) 38 | If @error = 0xDEAD And @extended = 0xBEEF Then $toString = Call("Au3UnitConstraintConstraint_ToString", $other) 39 | Return Au3ExporterExporter_Export($other) & " " & $toString 40 | EndFunc 41 | 42 | Func Au3UnitConstraintIsIdentical_ToString($value) 43 | ;If IsObj($value);TODO: https://github.com/sebastianbergmann/phpunit/blob/master/src/Framework/Constraint/IsIdentical.php#L115 44 | 45 | Return 'is identical to ' & Au3ExporterExporter_Export($value) 46 | EndFunc -------------------------------------------------------------------------------- /Tests/Exporter/Exporter.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | ;https://github.com/sebastianbergmann/exporter/blob/2.0/src/Exporter.php 3 | 4 | Func Au3ExporterExporter_Export($value, $indentation = 0) 5 | Return Au3ExporterExporter_RecursiveExport($value, $indentation) 6 | EndFunc 7 | 8 | Func Au3ExporterExporter_RecursiveExport(ByRef $value, $indentation, $processed = Null) 9 | If $value == Null Then Return "null" 10 | 11 | If $value == True Then Return "true" 12 | 13 | If $value == False Then Return "false" 14 | 15 | If IsFloat($value) And Int($value) == $value Then Return StringFormat("%s.0", $value) 16 | 17 | If IsPtr($value) Or IsHWnd($value) Then Return StringFormat("resource(%d) of type (%s)", $value, VarGetType($value)) 18 | 19 | if IsString($value) Then 20 | If StringRegExp("[^\x09-\x0d\x1b\x20-\xff]", $value) Then Return "Binary String: 0x" & $value ;https://github.com/sebastianbergmann/exporter/blob/2.0/src/Exporter.php#L235 21 | 22 | Return "'" & StringRegExpReplace($value, "(\r\n|\n\r|\r)", @CRLF) & "'" 23 | EndIf 24 | 25 | Local $whitespace = StringRepeat(" ", 4 * $indentation) 26 | 27 | ;~ If Not $processed Then $processed = new Context 28 | 29 | ;Local $key = $processed->contains($value) 30 | If IsArray($value) Then 31 | #cs 32 | If Not $key == False Then Return "Array &" & $key 33 | 34 | Local $array = $value 35 | $key = $processed->add($value) 36 | $values = "" 37 | 38 | If UBound($array) > 0 Then 39 | Local $k 40 | For $k=0 To UBound($array)-1 41 | Local $v = $array[$k] 42 | $values &= StringFormat("%s %s => %s" & @CRLF, $whitespace, Au3ExporterExporter_RecursiveExport($k, $indentation), Au3ExporterExporter_RecursiveExport($value($k), $indentation + 1, $processed)) 43 | Next 44 | Local $values = "\n" & $values & $whitespace 45 | EndIf 46 | Return StringFormat("Array &%s (%s)", $key, $values) 47 | #ce 48 | EndIf 49 | 50 | If IsObj($value) Then 51 | #cs 52 | Local $class = get_class($value) 53 | 54 | Local $hash = $processed->contains($value) 55 | If $hash Then Return StringFormat("%s Object &%s", $class, $hash) 56 | 57 | $hash = $processed->add($value) 58 | $values = "" 59 | $array = $this->toArray($value) 60 | 61 | If UBound($array) > 0 Then 62 | Local $k 63 | For $k=0 To UBound($array)-1 64 | Local $v = $array[$k] 65 | $values &= StringFormat("%s %s => %s" & @CRLF, $whitespace, Au3ExporterExporter_RecursiveExport($k, $indentation), Au3ExporterExporter_RecursiveExport($v, $indentation + 1, $processed)) 66 | Next 67 | $values = @CRLF & $value & $whitespace 68 | EndIf 69 | Return StringFormat("%s Object &%s (%s)", $class, $hash, $values) 70 | #ce 71 | EndIf 72 | 73 | ;Return var_export($value) 74 | $return = String($value) 75 | Return $return?$return:VarGetType($value) 76 | EndFunc 77 | 78 | Func StringRepeat($sChar, $nCount); https://www.autoitscript.com/forum/topic/140190-stringrepeat-very-fast-using-memset/ 79 | $tBuffer = DLLStructCreate("char[" & $nCount & "]") 80 | DllCall("msvcrt.dll", "ptr:cdecl", "memset", "ptr", DLLStructGetPtr($tBuffer), "int", Asc($sChar), "int", $nCount) 81 | Return DLLStructGetData($tBuffer, 1) 82 | EndFunc 83 | -------------------------------------------------------------------------------- /Tests/Collection class.au3: -------------------------------------------------------------------------------- 1 | #include "..\AutoItObject_Internal.au3" 2 | 3 | Func Collection($items) 4 | Local $class = IDispatch() 5 | 6 | $class.__name = "Collection" 7 | $class.__defineSetter("__name", PrivateProperty) 8 | $class.__defineGetter("getArrayableItems", Collection_getArrayableItems) 9 | $class.items = $class.getArrayableItems($items) 10 | $class.__defineSetter("items", PrivateProperty) 11 | $class.__defineGetter("get", Collection_Get) 12 | 13 | Return $class 14 | EndFunc 15 | 16 | Func Collection_Get($this) 17 | Local $arguments = $this.arguments 18 | Local $length = $arguments.length 19 | If $length<1 Or $length>2 Then Return SetError(1) 20 | Local $items = $arguments.values 21 | Local $path = StringSplit($items[0], ".", 2) 22 | Local $return = $this.parent.items 23 | Local $value 24 | For $segment In $path 25 | $value = Execute("$return["&$segment&"]") 26 | If @error==0 Then 27 | $return = $value 28 | ContinueLoop 29 | EndIf 30 | $value = Execute("$return['"&$segment&"']") 31 | If @error==0 Then 32 | $return = $value 33 | ContinueLoop 34 | EndIf 35 | If IsObj($items) And Execute("$items.__name") == "Collection" Then 36 | $value = $return.items.get($segment) 37 | If @error==0 Then 38 | $return = $value 39 | ContinueLoop 40 | EndIf 41 | Else 42 | $value = Execute("$return."&$segment) 43 | If @error==0 Then 44 | $return = $value 45 | ContinueLoop 46 | EndIf 47 | EndIf 48 | Return $length==2?$items[1]:Null;SetError(2, 0, $length==2?$items[1]:Null) 49 | Next 50 | Return $return 51 | EndFunc 52 | 53 | Func Collection_getArrayableItems($this) 54 | Local $arguments = $this.arguments 55 | If $arguments.length <> 1 Then Return SetError(1) 56 | Local $items = $arguments.values[0] 57 | If IsArray($items) Then 58 | Return $items 59 | ElseIf IsObj($items) And Execute("$items.__name") == "Collection" Then 60 | Return $items.items 61 | Else 62 | Local $return = [$items] 63 | Return $return 64 | EndIf 65 | EndFunc 66 | 67 | #cs 68 | $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") 69 | Func _ErrFunc($oError) 70 | ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ 71 | @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ 72 | @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ 73 | @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ 74 | @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ 75 | @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ 76 | @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ 77 | @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ 78 | @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ 79 | @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) 80 | EndFunc 81 | #ce 82 | 83 | $a = "success" 84 | $collection = Collection($a) 85 | MsgBox(0, "", $collection.get("0.0", "failure"));FIXME: currently does not support multi-dimentional 86 | Exit -------------------------------------------------------------------------------- /Tests/Unit/Constraint/Constraint.au3: -------------------------------------------------------------------------------- 1 | Global Const $Au3UnitConstraintCount = 1 ;https://github.com/sebastianbergmann/phpunit/blob/7.2/src/Framework/Constraint/Constraint.php#L72 2 | 3 | Func Au3UnitConstraintConstraint_Evaluate($constraint, $other, $description = "", $returnResult = false, $line = Null, $passedToContraint = Null) 4 | Local $success = False 5 | 6 | Local $matches = Call("Au3UnitConstraint" & $constraint & "_Matches", $other, $passedToContraint) 7 | If @error = 0xDEAD And @extended = 0xBEEF Then $matches = Call("Au3UnitConstraint" & $constraint & "_Matches", $other) 8 | If @error = 0xDEAD And @extended = 0xBEEF Then $matches = Call("Au3UnitConstraintConstraint_Matches", $other) 9 | If $matches Then $success = True 10 | 11 | If $returnResult Then Return $success 12 | 13 | If Not $success Then 14 | Call("Au3UnitConstraint" & $constraint & "_Fail", $other, $description, Null, $line) 15 | If @error = 0xDEAD And @extended = 0xBEEF Then Call("Au3UnitConstraintConstraint_Fail", $constraint, $other, $description, Null, $line, $passedToContraint) 16 | If @error = 0xDEAD And @extended = 0xBEEF Then Exit MsgBox(0, "Au3Unit", "Au3UnitConstraintConstraint_Fail function is missing"&@CRLF&"Exitting") + 1 17 | Return SetError(@error) 18 | EndIf 19 | EndFunc 20 | 21 | Func Au3UnitConstraintConstraint_Fail($constraint, $other, $description, $comparisonFailure = Null, $line = Null, $passedToContraint = Null) 22 | Local $failureDescription = Call("Au3UnitConstraint" & $constraint & "_FailureDescription", $other, $passedToContraint) 23 | If @error = 0xDEAD And @extended = 0xBEEF Then $failureDescription = Call("Au3UnitConstraint" & $constraint & "_FailureDescription", $other) 24 | If @error = 0xDEAD And @extended = 0xBEEF Then $failureDescription = Call("Au3UnitConstraintConstraint_FailureDescription", $constraint, $other, $passedToContraint) 25 | $failureDescription = StringFormat("Failed asserting that %s.", $failureDescription) 26 | 27 | Local $additionalFailureDescription = Call("Au3UnitConstraint" & $constraint & "_AdditionalFailureDescription", $other) 28 | If @error = 0xDEAD And @extended = 0xBEEF Then $additionalFailureDescription = Call("Au3UnitConstraintConstraint_AdditionalFailureDescription", $other) 29 | 30 | If $additionalFailureDescription Then $failureDescription &= @CRLF & $additionalFailureDescription 31 | 32 | If Not ($description = "") Then $failureDescription = $description & @CRLF & $failureDescription 33 | 34 | ConsoleWriteError($failureDescription&@CRLF&@ScriptFullPath&":"&$line&@CRLF) 35 | Return SetError(1) 36 | EndFunc 37 | 38 | Func Au3UnitConstraintConstraint_Matches($other) 39 | Return False 40 | EndFunc 41 | 42 | #include "..\..\Exporter\Exporter.au3" 43 | Func Au3UnitConstraintConstraint_FailureDescription($constraint, $other, $passedToContraint = Null) 44 | Local $toString = Call("Au3UnitConstraint" & $constraint & "_ToString", $other) 45 | If @error = 0xDEAD And @extended = 0xBEEF Then $toString = Call("Au3UnitConstraintConstraint_ToString", $other) 46 | Return Au3ExporterExporter_Export(@NumParams=3?$passedToContraint:$other) & " " & $toString 47 | EndFunc 48 | 49 | Func Au3UnitConstraintConstraint_AdditionalFailureDescription($other) 50 | Return "" 51 | EndFunc 52 | 53 | Func Au3UnitConstraintConstraint_ToString() 54 | Return "" 55 | EndFunc 56 | -------------------------------------------------------------------------------- /AutoItObject_Internal_ROT.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | 3 | If Not IsDeclared("IID_IRunningObjectTable") Then Global Const $IID_IRunningObjectTable = "{00000010-0000-0000-C000-000000000046}" 4 | If Not IsDeclared("IID_IMoniker") Then Global Const $IID_IMoniker = "{0000000F-0000-0000-C000-000000000046}" 5 | 6 | If Not IsDeclared("ROTFLAGS_REGISTRATIONKEEPSALIVE") Then Global Const $ROTFLAGS_REGISTRATIONKEEPSALIVE = 0x01 7 | If Not IsDeclared("ROTFLAGS_ALLOWANYCLIENT") Then Global Const $ROTFLAGS_ALLOWANYCLIENT = 0x02 8 | 9 | #cs 10 | # Registers an object and its identifying moniker in the running object table (ROT). 11 | # @param ptr|object $vObject Object that is being registered as running. 12 | # @param string $sCLSID The string identifier to use in the ROT 13 | # @param bool|int $bStrong Indicates a strong registration for the object. If not boolean, the value will be parsed directly to IRunningObjectTable::Register as the grfFlags parameter 14 | # @returns int The identifier of the ROT entry. 15 | #ce 16 | Func _AOI_ROT_register($vObject, $sCLSID, $bStrong = False) 17 | Local $grfFlags = IsBool($bStrong) ? ($bStrong ? $ROTFLAGS_REGISTRATIONKEEPSALIVE : 0) : $bStrong 18 | Local $dwRegister = 0 19 | Local $IRunningObjectTable = __AOI_ROT_GetRunningObjectTable() 20 | If @error <> 0 Then Return SetError(@error, @extended, $dwRegister) 21 | Local $IMoniker = __AOI_ROT_CreateFileMoniker($sCLSID) 22 | If @error <> 0 Then Return SetError(@error, @extended, $dwRegister) 23 | ;TODO: maybe temp. override ObjEvent for autoit COM Error, to always get @error instead of crash from the $IRunningObjectTable method call 24 | Local $iRet = $IRunningObjectTable.Register($grfFlags, ptr($vObject), Ptr($IMoniker), $dwRegister) 25 | If @error <> 0 Then Return SetError(@error, @extended, $dwRegister) 26 | If $iRet <> 0 Then Return SetError($iRet, @extended, $dwRegister) 27 | Return $dwRegister 28 | EndFunc 29 | 30 | #cs 31 | # Removes an entry from the running object table (ROT) that was previously registered by a call to IRunningObjectTable::Register. 32 | # @param int $dwRegister The identifier of the ROT entry to be revoked. 33 | # @returns bool 34 | #ce 35 | Func _AOI_ROT_revoke($dwRegister) 36 | Local $IRunningObjectTable = __AOI_ROT_GetRunningObjectTable() 37 | If @error <> 0 Then Return SetError(@error, @extended, $dwRegister) 38 | Local $iRet = $IRunningObjectTable.Revoke($dwRegister) 39 | If @error <> 0 Then Return SetError(@error, @extended, False) 40 | If $iRet <> 0 Then Return SetError($iRet, @extended, False) 41 | Return True 42 | EndFunc 43 | 44 | #cs 45 | # @internal 46 | #ce 47 | Func __AOI_ROT_GetRunningObjectTable() 48 | Local $aRet = DllCall("Ole32.dll", "LONG", "GetRunningObjectTable", "DWORD", 0, "PTR*", 0) 49 | If @error <> 0 Then Return SetError(@error, @extended, 0) 50 | If $aRet[0] <> 0 Then Return SetError(0xDEAD, $aRet[0], 0) 51 | Local $IRunningObjectTable = ObjCreateInterface($aRet[2],$IID_IRunningObjectTable,"Register HRESULT(DWORD;PTR;PTR;DWORD*);Revoke HRESULT(DWORD);IsRunning HRESULT(PTR*);GetObject HRESULT(PTR;PTR*);NoteChangeTime HRESULT(DWORD;PTR*);GetTimeOfLastChange HRESULT(PTR*;PTR*);EnumRunning HRESULT(PTR*);",True) 52 | If @error<>0 Then Return SetError(@error, @extended, 0) 53 | Return $IRunningObjectTable 54 | EndFunc 55 | 56 | #cs 57 | # @internal 58 | #ce 59 | Func __AOI_ROT_CreateFileMoniker($sCLSID) 60 | Local $aRet=DllCall("Ole32.dll", "LONG", "CreateFileMoniker", "WSTR", $sCLSID, "PTR*", 0) 61 | If @error <> 0 Then Return SetError(@error, @extended, 0) 62 | If $aRet[0] <> 0 Then Return SetError(0xDEAD, $aRet[0], 0) 63 | ;TODO: we should reveal all methods available on IMoniker object to AutoIt3 64 | ;Local $IMoniker = ObjCreateInterface($aRet[2], $IID_IMoniker, "GetClassID;IsDirty;Load;Save;GetSizeMax;BindToObject;BindToStorage;Reduce;ComposeWith;Enum;IsEqual;Hash;IsRunning;GetTimeOfLastChange;Inverse;CommonPrefixWith;RelativePathTo;GetDisplayName;ParseDisplayName;IsSystemMoniker") 65 | Local $IMoniker = ObjCreateInterface($aRet[2], $IID_IMoniker) 66 | If @error<>0 Then Return SetError(@error, @extended, 0) 67 | Return $IMoniker 68 | EndFunc 69 | -------------------------------------------------------------------------------- /Tests/Unit/assert.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | ; https://github.com/sebastianbergmann/phpunit/blob/7.2/src/Framework/Assert.php 3 | 4 | Global $Au3UnitAssertCount = 0 5 | 6 | #include "Constraint\Constraint.au3" 7 | #include "Constraint\IsType.au3" 8 | 9 | Func assertThat($value, $constraint, $message = "", $line = @ScriptLineNumber, $passedToContraint = Null) 10 | Local $constraintCount = "Au3UnitConstraint" & $constraint & "Count" 11 | $Au3UnitAssertCount += IsDeclared($constraintCount) ? Eval($constraintCount) : $Au3UnitConstraintCount 12 | Call("Au3UnitConstraint" & $constraint & "_Evaluate", $value, $message, False, $line, $passedToContraint) 13 | If @error==0xDEAD And @extended==0xBEEF Then Call("Au3UnitConstraintConstraint_Evaluate", $constraint, $value, $message, False, $line, $passedToContraint) 14 | Return SetError(@error) 15 | EndFunc 16 | 17 | ; Func assertObjectHasAttribute($attributeName, $object, $message = "") 18 | ; 19 | ; EndFunc 20 | 21 | #include "Constraint\IsEqual.au3" 22 | Func assertEquals($expected, $actual, $message = "", $line = @ScriptLineNumber) 23 | assertThat($actual, "IsEqual", $message, $line, $expected) 24 | EndFunc 25 | 26 | Func assertNotEquals($expected, $actual, $message = "", $line = @ScriptLineNumber) 27 | Local $passedToContraint = ["IsEqual", $expected] 28 | assertThat($actual, "LogicalNot", $message, $line, $passedToContraint) 29 | EndFunc 30 | 31 | #include "Constraint\IsFalse.au3" 32 | Func assertFalse($condition, $message = "", $line = @ScriptLineNumber) 33 | assertThat($condition, "IsFalse", $message, $line, $condition) 34 | EndFunc 35 | 36 | Func assertNotFalse($condition, $message = "", $line = @ScriptLineNumber) 37 | Local $passedToContraint = ["IsFalse", $condition] 38 | assertThat($condition, "LogicalNot", $message, $line, $passedToContraint) 39 | EndFunc 40 | 41 | ; Func assertGreaterThan($expected, $actual, $message = "") 42 | 43 | ; EndFunc 44 | 45 | ; Func assertGreaterThanOrEqual($expected, $actual, $message = "") 46 | 47 | ; EndFunc 48 | 49 | ; Func assertInfinite($variable, $message = "") 50 | 51 | ; EndFunc 52 | 53 | ; Func assertFinite($variable, $message = "") 54 | 55 | ; EndFunc 56 | 57 | #include "Constraint\IsIdentical.au3" 58 | Func assertInternalType($expected, $actual, $message = "", $line = @ScriptLineNumber) 59 | assertThat($actual, "IsType", $message, $line, $expected) 60 | EndFunc 61 | 62 | #include "Constraint\LogicalNot.au3" 63 | Func assertNotInternalType($expected, $actual, $message = "", $line = @ScriptLineNumber) 64 | Local $passedToContraint = ["IsType", $expected] 65 | assertThat($actual, "LogicalNot", $message, $line, $passedToContraint) 66 | EndFunc 67 | 68 | ; Func assertLessThan($expected, $actual, $message = "") 69 | 70 | ; EndFunc 71 | 72 | ; Func assertLessThanOrEqual($expected, $actual, $message = "") 73 | 74 | ; EndFunc 75 | 76 | #include "Constraint\IsNull.au3" 77 | Func assertNull($actual, $message = "", $line = @ScriptLineNumber) 78 | assertThat($actual, "IsNull", $message, $line) 79 | EndFunc 80 | 81 | #cs 82 | Func assertNotNull() 83 | assertThat($actual, logicalNot("isNull"), $message) 84 | EndFunc 85 | 86 | 87 | Func assertStringMatchesFormat($format, $string, $message = "") 88 | 89 | EndFunc 90 | #ce 91 | 92 | #include "Constraint\IsIdentical.au3" 93 | Func assertSame($expected, $actual, $message = "", $line = @ScriptLineNumber) 94 | assertThat($actual, "IsIdentical", $message, $line, $expected) 95 | EndFunc 96 | #cs 97 | Func assertNotSame($expected, $actual, $message = "") 98 | 99 | EndFunc 100 | #ce 101 | #cs 102 | Func assertStringEndsWith($suffix, $string, $message = "") 103 | 104 | EndFunc 105 | 106 | Func assertStringEndsNotWith($suffix, $string, $message = "") 107 | 108 | EndFunc 109 | #ce 110 | #cs 111 | Func assertStringStartsWith($prefix, $string, $message = "") 112 | 113 | EndFunc 114 | 115 | Func assertStringStartsNotWith($prefix, $string, $message = "") 116 | 117 | EndFunc 118 | #ce 119 | #include "Constraint\IsTrue.au3" 120 | Func assertTrue($condition, $message = "", $line = @ScriptLineNumber) 121 | assertThat($condition, "IsTrue", $message, $line, $condition) 122 | EndFunc 123 | 124 | Func assertNotTrue($condition, $message = "", $line = @ScriptLineNumber) 125 | Local $passedToContraint = ["IsTrue", $condition] 126 | assertThat($condition, "LogicalNot", $message, $line, $passedToContraint) 127 | EndFunc 128 | -------------------------------------------------------------------------------- /Tests/Unit/Constraint/LogicalNot.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | #include 3 | #include "..\..\helpers.au3" 4 | ;https://github.com/sebastianbergmann/phpunit/blob/master/src/Framework/Constraint/LogicalNot.php 5 | 6 | Func Au3UnitConstraintLogicalNot_Negate($string) 7 | Local $matches, $negatedString, $nonInput 8 | 9 | Local $positives = [ _ 10 | 'contains ', _ 11 | 'exists', _ 12 | 'has ', _ 13 | 'is ', _ 14 | 'are ', _ 15 | 'matches ', _ 16 | 'starts with ', _ 17 | 'ends with ', _ 18 | 'reference ', _ 19 | 'not not ' _ 20 | ] 21 | 22 | Local $negatives = [ _ 23 | 'does not contain ', _ 24 | 'does not exist', _ 25 | 'does not have ', _ 26 | 'is not ', _ 27 | 'are not ', _ 28 | 'does not match ', _ 29 | 'starts not with ', _ 30 | 'ends not with ', _ 31 | 'don''''t reference ', _ 32 | 'not ' _ 33 | ] 34 | 35 | $matches = StringRegExp($string, '(?i)(\''''[\w\W]*'''')([\w\W]*)("[\w\W]*")', $STR_REGEXPARRAYFULLMATCH) 36 | 37 | If UBound($matches) > 0 Then 38 | $nonInput = $matches[2] 39 | 40 | $negatedString = PHP_str_replace($nonInput, PHP_str_replace($positives, $negatives, $nonInput), $string) 41 | Else 42 | $negatedString = PHP_str_replace($positives, $negatives, $string) 43 | EndIf 44 | 45 | Return $negatedString 46 | EndFunc 47 | 48 | Func Au3UnitConstraintLogicalNot_Evaluate($other, $description = "", $returnResult = false, $line = Null, $exspected = Null) 49 | Local $success = Not Call("Au3UnitConstraint" & $exspected[0] & "_Evaluate", $other, $description, True, $line, $exspected[1]) 50 | If @error=0xDEAD And @extended=0xBEEF Then $success = Not Call("Au3UnitConstraint" & $exspected[0] & "_Evaluate", $other, $description, True, $line) 51 | If @error=0xDEAD And @extended=0xBEEF Then $success = Not Call("Au3UnitConstraintConstraint_Evaluate", $exspected[0], $other, $description, True, $line, $exspected[1]) 52 | 53 | If $returnResult Then Return $success 54 | 55 | If Not $success Then 56 | Call("Au3UnitConstraintLogicalNot_Fail", $other, $description, Null, $line, $exspected) 57 | If @error = 0xDEAD And @extended = 0xBEEF Then Call("Au3UnitConstraintConstraint_Fail", "LogicalNot", $other, $description, Null, $line) 58 | If @error = 0xDEAD And @extended = 0xBEEF Then Exit MsgBox(0, "Au3Unit", "Au3UnitConstraintConstraint_Fail function is missing"&@CRLF&"Exitting") + 1 59 | Return SetError(@error) 60 | EndIf 61 | EndFunc 62 | 63 | Func Au3UnitConstraintLogicalNot_Fail($other, $description, $comparisonFailure, $line, $exspected) 64 | Local $failureDescription = Call("Au3UnitConstraintLogicalNot_FailureDescription", $other, $exspected) 65 | If @error = 0xDEAD And @extended = 0xBEEF Then $failureDescription = Call("Au3UnitConstraintConstraint_FailureDescription", "LogicalNot", $other) 66 | $failureDescription = StringFormat("Failed asserting that %s.", $failureDescription) 67 | 68 | Local $additionalFailureDescription = Call("Au3UnitConstraintLogicalNot_AdditionalFailureDescription", $other) 69 | If @error = 0xDEAD And @extended = 0xBEEF Then $additionalFailureDescription = Call("Au3UnitConstraintConstraint_AdditionalFailureDescription", $other) 70 | 71 | If $additionalFailureDescription Then $failureDescription &= @CRLF & $additionalFailureDescription 72 | 73 | If Not ($description = "") Then $failureDescription = $description & @CRLF & $failureDescription 74 | 75 | ConsoleWriteError($failureDescription&@CRLF&@ScriptFullPath&":"&$line&@CRLF) 76 | Return SetError(1) 77 | EndFunc 78 | 79 | Func Au3UnitConstraintLogicalNot_FailureDescription($other, $exspected) 80 | Switch $exspected 81 | Case "LogicalAnd", "LogicalNot", "LogicalOr" 82 | Local $iSize = UBound($exspected)-2 83 | Local $_exspected = Null 84 | If $iSize > 0 Then 85 | Local $_exspected[$iSize] 86 | Local $i 87 | For $i=0 To $iSize-1 88 | $_exspected[$i]=$exspected[2+$i] 89 | Next 90 | EndIf 91 | Local $failureDescription = Call("Au3UnitConstraint" & $exspected[0] & "_FailureDescription", $other, $exspected[0], $_exspected) 92 | If @error = 0xDEAD And @extended = 0xBEEF Then Call("Au3UnitConstraintConstraint_FailureDescription", $other, $exspected[0]) 93 | Return 'not( ' & $failureDescription & ' )' 94 | Case Else 95 | Local $failureDescription = Call("Au3UnitConstraint" & $exspected[0] & "_FailureDescription", $exspected[0], $other, $exspected[1]) 96 | If @error = 0xDEAD And @extended = 0xBEEF Then $failureDescription = Call("Au3UnitConstraintConstraint_FailureDescription", $exspected[0], $other) 97 | Return Au3UnitConstraintLogicalNot_Negate($failureDescription) 98 | EndSwitch 99 | EndFunc 100 | 101 | Func Au3UnitConstraintLogicalNot_ToString($value, $constraint = Null) 102 | Switch $constraint 103 | Case "LogicalAnd", "LogicalNot", "LogicalOr" 104 | Local $failureDescription = Call("Au3UnitConstraint" & $constraint & "_Tostring", $other) 105 | If @error = 0xDEAD And @extended = 0xBEEF Then Call("Au3UnitConstraintConstraint_ToString", $other) 106 | Return 'not( ' & $failureDescription & ' )' 107 | Case Else 108 | Local $failureDescription = Call("Au3UnitConstraint" & $constraint & "_ToString", $other) 109 | If @error = 0xDEAD And @extended = 0xBEEF Then Call("Au3UnitConstraintConstraint_ToString", $other) 110 | Return Au3UnitConstraintLogicalNot_Negate($failureDescription) 111 | EndSwitch 112 | EndFunc 113 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | ## **Methods:** 2 | 3 | ### __get 4 | 5 | #### **Syntax** 6 | 7 | __get("property") 8 | 9 | #### **Description:** 10 | 11 | get the value of property 12 | 13 | #### **Parameters:** 14 | 15 | Type | Name | description 16 | --- | --- | --- 17 | String | "property" | The property to get value of 18 | 19 | ### __set 20 | 21 | #### **Syntax** 22 | 23 | __set("property", value) 24 | 25 | #### **Description:** 26 | 27 | set the value of property 28 | 29 | #### **Parameters:** 30 | 31 | Type | Name | description 32 | --- | --- | --- 33 | String | "property" | The property to get value of 34 | Mixed | value | the value to set the property to 35 | 36 | ### __defineGetter 37 | 38 | #### **Syntax** 39 | 40 | __defineGetter("property", Function) 41 | 42 | #### **Description:** 43 | 44 | set the get-accessor 45 | 46 | #### **Parameters:** 47 | 48 | Type | Name | description 49 | --- | --- | --- 50 | String | "property" | The property to set the get accessor 51 | Function\|String | Function | Function to be called when getting the property value 52 | 53 | ### __lookupGetter 54 | 55 | #### **Syntax** 56 | 57 | __lookupGetter("property") 58 | 59 | #### **Description:** 60 | 61 | return the get-accessor 62 | 63 | #### **Parameters:** 64 | 65 | Type | Name | description 66 | --- | --- | --- 67 | String | "property" | The property to set the get accessor 68 | 69 | ### __assign 70 | 71 | #### **Syntax** 72 | 73 | __assign(IDispatch[, ...]) 74 | 75 | #### **Description:** 76 | 77 | copy the values of all properties from one or more source objects to a the object 78 | 79 | #### **Parameters:** 80 | 81 | Type | Name | description 82 | --- | --- | --- 83 | IDispatch | IDispatch | Source IDispatch object. Note: normal IDispatch objects will result in a crash. 84 | 85 | ### __defineSetter 86 | 87 | #### **Syntax** 88 | 89 | __defineSetter("property", Function) 90 | 91 | #### **Description:** 92 | 93 | set the set-accessor 94 | 95 | #### **Parameters:** 96 | 97 | Type | Name | description 98 | --- | --- | --- 99 | String | "property" | The property to set the get accessor 100 | Function\|String | Function | Function to be called when setting the property value 101 | 102 | ### __lookupSetter 103 | 104 | #### **Syntax** 105 | 106 | __lookupSetter("property", Function) 107 | 108 | #### **Description:** 109 | 110 | get the set-accessor 111 | 112 | #### **Parameters:** 113 | 114 | Type | Name | description 115 | --- | --- | --- 116 | String | "property" | The property to set the get accessor 117 | 118 | ### __keys 119 | 120 | #### **Syntax** 121 | 122 | __keys() 123 | 124 | #### **Description:** 125 | 126 | get all property names defined in object 127 | 128 | #### **Parameters:** 129 | 130 | Type | Name | description 131 | --- | --- | --- 132 | 133 | ### __unset 134 | 135 | #### **Syntax** 136 | 137 | __unset("property") 138 | 139 | #### **Description:** 140 | 141 | delete a property from the object 142 | 143 | #### **Parameters:** 144 | 145 | Type | Name | description 146 | --- | --- | --- 147 | String | "property" | The property to delete 148 | 149 | ### __preventExtensions 150 | 151 | #### **Syntax** 152 | 153 | __preventExtensions() 154 | 155 | #### **Description:** 156 | 157 | prevents new properties from ever being added to the object 158 | 159 | #### **Parameters:** 160 | 161 | Type | Name | description 162 | --- | --- | --- 163 | 164 | ### __isExtensible 165 | 166 | #### **Syntax** 167 | 168 | __isExtensible() 169 | 170 | #### **Description:** 171 | 172 | determines if an object is extensible (whether it can have new properties added to it). 173 | 174 | #### **Parameters:** 175 | 176 | Type | Name | description 177 | --- | --- | --- 178 | 179 | ### __seal 180 | 181 | #### **Syntax** 182 | 183 | __seal() 184 | 185 | #### **Description:** 186 | 187 | seals the object, preventing new properties from being added to it and marking all existing properties as non-configurable. Values of present properties can still be changed 188 | 189 | #### **Parameters:** 190 | 191 | Type | Name | description 192 | --- | --- | --- 193 | 194 | ### __isSealed 195 | 196 | #### **Syntax** 197 | 198 | __isSealed() 199 | 200 | #### **Description:** 201 | 202 | determines if an object is sealed 203 | 204 | #### **Parameters:** 205 | 206 | Type | Name | description 207 | --- | --- | --- 208 | 209 | ### __freeze 210 | 211 | #### **Syntax** 212 | 213 | __freeze() 214 | 215 | #### **Description:** 216 | 217 | freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their configurability, from being changed 218 | 219 | #### **Parameters:** 220 | 221 | Type | Name | description 222 | --- | --- | --- 223 | 224 | ### __isFrozen 225 | 226 | #### **Syntax** 227 | 228 | __isFrozen() 229 | 230 | #### **Description:** 231 | 232 | determines if an object is frozen. 233 | 234 | #### **Parameters:** 235 | 236 | Type | Name | description 237 | --- | --- | --- 238 | 239 | ### __destructor 240 | 241 | #### **Syntax** 242 | 243 | __destructor(DestructorFunction) 244 | 245 | #### **Description:** 246 | 247 | DestructorFunction is called when the lifetime of the object ends 248 | 249 | Type | Name | description 250 | --- | --- | --- 251 | Function\|String | DestructorFunction | Function to be called when lifetime of the object ends 252 | 253 | ## **Properties:** 254 | 255 | ### __case 256 | 257 | #### **Type** 258 | 259 | Bool 260 | 261 | ## **Other** 262 | 263 | ### Function 264 | 265 | #### **Syntax** 266 | 267 | Function([AccessorObject]) 268 | 269 | #### **Description:** 270 | 271 | The callback function used with accessors 272 | Function is a placeholder for the application-defined function name 273 | 274 | #### **Parameters:** 275 | 276 | Type | Name | description 277 | --- | --- | --- 278 | IDispatch | AccessorObject | A IDispatch object used to access passed data and self 279 | 280 | ### AccessorObject 281 | 282 | #### **Description:** 283 | 284 | A locked IDispatch object, used with Accessor callback Function 285 | 286 | #### **Properties:** 287 | 288 | Type | Name | description | Access 289 | --- | --- | --- | --- 290 | IDispatch | parent | The IDispatch object containing the accessor.
**WARNING:** accessing other properties via this object will still trigger accessors. Be careful | Read only 291 | IDispatch | arguments | A locked IDispatch object.
For more info, see ArgumentsObject 292 | *Any* | ret | The value passed in the set-accessor. This is not used by the get-accessor | Read and Write 293 | *Any* | val | The value of the property the accessor is bound to | Read and Write 294 | 295 | ### ArgumentsObject 296 | 297 | #### **Description:** 298 | 299 | A locked IDispatch object, used with the AccessorObject 300 | 301 | #### **Properties:** 302 | 303 | Type | Name | description | Access 304 | --- | --- | --- | --- 305 | int32 | length | number of arguments passed with the call | Read and Write 306 | Array | values | the arguments passed with the call | Read and Write 307 | 308 | ### DestructorFunction([self]) 309 | 310 | #### **Description:** 311 | 312 | the callback function used with destructors 313 | 314 | #### **Parameters:** 315 | 316 | Type | Name | description 317 | --- | --- | --- 318 | IDispatch | self | The IDispatch object containing the destructor 319 | -------------------------------------------------------------------------------- /Tests/Test.au3: -------------------------------------------------------------------------------- 1 | #include "..\AutoItObject_Internal.au3" 2 | #include "Unit\assert.au3" 3 | 4 | #AutoIt3Wrapper_Run_Au3Check=N 5 | 6 | ;TODO: add object struct property for retriving variant types through the Invoke function, name maybe Buffer or Variant 7 | ;TODO: implement helper IDispatch object with a function like: getValueFromVariant($pVariant):Mixed 8 | 9 | $oError = ObjEvent("AutoIt.Error", "_ErrFunc") 10 | ; User's COM error function. Will be called if COM error occurs 11 | Func _ErrFunc($oError) 12 | Return SetError($oError.number, 0, $oError.retcode) 13 | EndFunc ;==>_ErrFunc 14 | 15 | testTypeSupport() 16 | testAccessors() 17 | testCase() 18 | testDestructor() 19 | testSeal() 20 | testFreeze() 21 | testPreventExtensions() 22 | testAssign() 23 | testMethods();tests the remaining non tested methods 24 | testUnset() 25 | 26 | Func testTypeSupport() 27 | Local $oIDispatch = IDispatch() 28 | 29 | $oIDispatch.a = $oIDispatch 30 | assertEquals(@error, 0) 31 | assertInternalType($oIDispatch.a, "Object") 32 | $oIDispatch.a = Int(1, 1) 33 | assertEquals(@error, 0) 34 | assertInternalType($oIDispatch.a, "Int32") 35 | $oIDispatch.a = Int(1, 2) 36 | assertEquals(@error, 0) 37 | assertInternalType($oIDispatch.a, "Int64") 38 | $oIDispatch.a = 1.5 39 | assertEquals(@error, 0) 40 | assertInternalType($oIDispatch.a, "Double") 41 | $oIDispatch.a = "string" 42 | assertEquals(@error, 0) 43 | assertInternalType($oIDispatch.a, "String") 44 | $oIDispatch.a = Binary(1) 45 | assertEquals(@error, 0) 46 | assertInternalType($oIDispatch.a, "Binary") 47 | $oIDispatch.a = Ptr(1) 48 | assertEquals(@error, 0) 49 | assertInternalType($oIDispatch.a, "Ptr", "Fail is expected, AutoIt related, not a fault of the library") 50 | $oIDispatch.a = HWnd(1) 51 | assertEquals(@error, 0) 52 | assertInternalType($oIDispatch.a, "HWnd", "Fail is expected, AutoIt related, not a fault of the library") 53 | $oIDispatch.a = True 54 | assertEquals(@error, 0) 55 | assertInternalType($oIDispatch.a, "Bool") 56 | $oIDispatch.a = Null 57 | assertEquals(@error, 0) 58 | assertInternalType($oIDispatch.a, "Keyword") 59 | $oIDispatch.a = Default 60 | assertEquals(@error, 0) 61 | assertInternalType($oIDispatch.a, "Keyword") 62 | $oIDispatch.a = DllStructCreate("BYTE") 63 | assertEquals(@error, 0) 64 | assertInternalType($oIDispatch.a, "DLLStruct") 65 | $oIDispatch.a = MsgBox 66 | assertEquals(@error, 0) 67 | assertInternalType($oIDispatch.a, "Function") 68 | $oIDispatch.a = IDispatch 69 | assertEquals(@error, 0) 70 | assertInternalType($oIDispatch.a, "UserFunction") 71 | Local $a = [1] 72 | $oIDispatch.a = $a 73 | assertEquals(@error, 0) 74 | assertInternalType($oIDispatch.a, "Array") 75 | EndFunc 76 | 77 | Func Accessor_Getter($oThis) 78 | Return $oThis.val 79 | EndFunc 80 | 81 | Func Accessor_Setter($oThis) 82 | $oThis.val = $oThis.val&$oThis.ret 83 | Return $oThis.val 84 | EndFunc 85 | 86 | Func testAccessors() 87 | Local $oIDispatch = IDispatch() 88 | $oIDispatch.a = "value" 89 | assertEquals(@error, 0) 90 | $oIDispatch.__defineGetter("a", "Accessor_Getter") 91 | assertEquals(@error, 0) 92 | $oIDispatch.__defineSetter("a", "Accessor_Setter") 93 | assertEquals(@error, 0) 94 | assertEquals($oIDispatch.a, "value") 95 | assertEquals($oIDispatch.__lookupGetter("a"), "Accessor_Getter") 96 | assertEquals($oIDispatch.__lookupSetter("a"), "Accessor_Setter") 97 | $oIDispatch.a = "value" 98 | assertEquals(@error, 0) 99 | assertEquals($oIDispatch.a, "valuevalue") 100 | 101 | $oIDispatch.__defineGetter("a", Accessor_Getter) 102 | assertEquals(@error, 0) 103 | $oIDispatch.__defineSetter("a", Accessor_Setter) 104 | assertEquals(@error, 0) 105 | assertEquals($oIDispatch.a, "valuevalue") 106 | assertEquals($oIDispatch.__lookupGetter("a"), Accessor_Getter) 107 | assertEquals($oIDispatch.__lookupSetter("a"), Accessor_Setter) 108 | $oIDispatch.a = "value" 109 | assertEquals(@error, 0) 110 | assertEquals($oIDispatch.a, "valuevaluevalue") 111 | 112 | $oIDispatch.__defineGetter("a", Null) 113 | assertNotEquals(@error, 0) 114 | $oIDispatch.__defineSetter("a", Null) 115 | assertNotEquals(@error, 0) 116 | EndFunc 117 | 118 | Func testCase() 119 | Local $oIDispatch = IDispatch() 120 | Local $value 121 | $value = $oIDispatch.__case 122 | assertEquals(@error, 0) 123 | assertEquals($value, True) 124 | $oIDispatch.a = "a" 125 | assertEquals(@error, 0) 126 | $oIDispatch.__seal() 127 | assertEquals(@error, 0) 128 | $value = $oIDispatch.a 129 | assertEquals(@error, 0) 130 | assertEquals($value, "a") 131 | $value = $oIDispatch.A 132 | assertNotEquals(@error, 0) 133 | assertNotEquals($value, "a") 134 | $oIDispatch.__case = False 135 | $value = $oIDispatch.a 136 | assertEquals(@error, 0) 137 | assertEquals($value, "a") 138 | $value = $oIDispatch.A 139 | assertEquals(@error, 0) 140 | assertEquals($value, "a") 141 | EndFunc 142 | 143 | Func __destructor() 144 | $__destructor+=1 145 | EndFunc 146 | 147 | Func testDestructor() 148 | $oIDispatch = IDispatch() 149 | Global $__destructor = 0 150 | $oIDispatch.__destructor(__destructor) 151 | assertEquals(@error, 0) 152 | $oIDispatch = Null 153 | assertEquals($__destructor, 1) 154 | $oIDispatch = IDispatch() 155 | $oIDispatch.__destructor("__destructor") 156 | assertEquals(@error, 0) 157 | $oIDispatch = Null 158 | assertEquals($__destructor, 2) 159 | EndFunc 160 | 161 | Func testSeal() 162 | Local $oIDispatch = IDispatch() 163 | $oIDispatch.a = "value" 164 | assertFalse($oIDispatch.__isSealed()) 165 | $oIDispatch.__seal() 166 | assertEquals(@error, 0) 167 | assertTrue($oIDispatch.__isSealed()) 168 | $oIDispatch.a = "otherValue" 169 | assertEquals(@error, 0) 170 | assertEquals($oIDispatch.a, "otherValue") 171 | $oIDispatch.b = "value";FIXME: will not result in @error flag. count keys to check 172 | assertNotEquals(@error, 0) 173 | EndFunc 174 | 175 | Func testFreeze() 176 | Local $oIDispatch = IDispatch() 177 | $oIDispatch.a = "value" 178 | assertFalse($oIDispatch.__isFrozen()) 179 | $oIDispatch.__freeze() 180 | assertEquals(@error, 0) 181 | assertTrue($oIDispatch.__isFrozen()) 182 | $oIDispatch.a = "otherValue" 183 | assertNotEquals(@error, 0) 184 | assertNotEquals($oIDispatch.a, "otherValue") 185 | $oIDispatch.b = "value" 186 | assertNotEquals(@error, 0) 187 | EndFunc 188 | 189 | Func testPreventExtensions() 190 | Local $oIDispatch = IDispatch() 191 | $oIDispatch.a = "value" 192 | assertFalse($oIDispatch.__isExtensible()) 193 | $oIDispatch.__preventExtensions() 194 | assertEquals(@error, 0) 195 | assertTrue($oIDispatch.__isExtensible()) 196 | $oIDispatch.a = "value" 197 | assertEquals(@error, 0) 198 | $oIDispatch.b 199 | assertNotEquals(@error, 0);FIXME: add the rest of the checks 200 | EndFunc 201 | 202 | Func testAssign() 203 | Local $oIDispatch1 = IDispatch() 204 | Local $oIDispatch2 = IDispatch() 205 | Local $oIDispatch3 = IDispatch() 206 | 207 | $oIDispatch3.a = 10 208 | $oIDispatch3.b = 20 209 | $oIDispatch3.c = 30 210 | 211 | $oIDispatch2.a = 1 212 | $oIDispatch2.b = 2 213 | $oIDispatch2.c = 3 214 | $oIDispatch2.d = 4 215 | 216 | $oIDispatch1.a = 3 217 | $oIDispatch1.b = 2 218 | $oIDispatch1.c = 1 219 | 220 | $oIDispatch1.__assign($oIDispatch2, $oIDispatch3) 221 | assertEquals(@error, 0) 222 | assertEquals($oIDispatch1.a, 10) 223 | assertEquals($oIDispatch1.b, 20) 224 | assertEquals($oIDispatch1.c, 30) 225 | assertEquals($oIDispatch1.d, 4) 226 | EndFunc 227 | 228 | Func testMethods() 229 | Local $oIDispatch = IDispatch() 230 | Local $value 231 | $oIDispatch.__set("a", "value") 232 | assertEquals(@error, 0) 233 | $value = $oIDispatch.__get("a") 234 | assertEquals(@error, 0) 235 | assertEquals($value, "value") 236 | $value = $oIDispatch.__keys 237 | assertEquals(@error, 0) 238 | assertEquals(UBound($value), 1) 239 | $value = $oIDispatch.__exists("a") 240 | assertEquals($value, True) 241 | $value = $oIDispatch.__exists("A") 242 | assertEquals($value, False) 243 | EndFunc 244 | 245 | Func testUnset() 246 | Local $oIDispatch = IDispatch() 247 | $oIDispatch.a = 1 248 | $oIDispatch.b = 2 249 | $oIDispatch.c = 3 250 | $value = $oIDispatch.__exists("b") 251 | assertEquals($value, True) 252 | $oIDispatch.__unset('b') 253 | $value = $oIDispatch.__exists("b") 254 | assertEquals($value, False) 255 | EndFunc 256 | -------------------------------------------------------------------------------- /Examples/04 - Advanced - Practical example.au3: -------------------------------------------------------------------------------- 1 | #cs ---------------------------------------------------------------------------- 2 | 3 | AutoIt Version: 3.3.14.2 4 | Author: genius257 5 | 6 | #ce ---------------------------------------------------------------------------- 7 | #include 8 | #include "..\AutoItObject_Internal.au3" 9 | 10 | $AutoItError = ObjEvent("AutoIt.Error", "ErrFunc") ; Install a custom error handler 11 | Func ErrFunc($oError) 12 | ConsoleWrite("!>COM Error !"&@CRLF&"!>"&@TAB&"Number: "&Hex($oError.Number,8)&@CRLF&"!>"&@TAB&"Windescription: "&StringRegExpReplace($oError.windescription,"\R$","")&@CRLF&"!>"&@TAB&"Source: "&$oError.source&@CRLF&"!>"&@TAB&"Description: "&$oError.description&@CRLF&"!>"&@TAB&"Helpfile: "&$oError.helpfile&@CRLF&"!>"&@TAB&"Helpcontext: "&$oError.helpcontext&@CRLF&"!>"&@TAB&"Lastdllerror: "&$oError.lastdllerror&@CRLF&"!>"&@TAB&"Scriptline: "&$oError.scriptline&@CRLF) 13 | EndFunc ;==>ErrFunc 14 | 15 | _GDIPlus_Startup() 16 | 17 | $GUI = GUI("old title") 18 | $GUI.bkColor(0xC2E34E).width(200).height(200).title("new title").onExit(_MyExit).Show 19 | 20 | $Pen = Pen(0xFF000000) 21 | $Brush = Brush(0xFF000000) 22 | 23 | $GUI.graphics.DrawRect(10,10,$GUI.clientWidth-21,$GUI.clientHeight-21,$Pen).FillRect(15, 15, $GUI.clientWidth-30, $GUI.clientHeight-30, $Brush) 24 | 25 | Sleep(1000) 26 | 27 | $GUI.graphics.FillRect(15, 15, $GUI.clientWidth-30, $GUI.clientHeight-30, $Brush.color(0xFFc3E3c3)) 28 | 29 | While 1 30 | Sleep(10) 31 | WEnd 32 | 33 | Func _MyExit() 34 | ;remove object references to release resources and activate desctructors 35 | $Pen=0 36 | $Brush=0 37 | $GUI=0 38 | _GDIPlus_Shutdown() 39 | Exit 40 | EndFunc 41 | 42 | Func GUI($title, $width = Default, $height = Default, $left = Default, $top = Default, $style = Default, $exStyle = Default, $parent = Default) 43 | Local $IDispatch = IDispatch() 44 | $IDispatch.hwnd = GUICreate($title, $width, $height, $left, $top, $style, $exStyle, $parent) 45 | $IDispatch.__defineSetter("hwnd", PrivateProperty);PrivateProperty is defined in AutoItObject_Internal.au3 46 | $IDispatch.__defineGetter("Show", Wnd_Show) 47 | $IDispatch.__defineGetter("Hide", Wnd_Hide) 48 | $IDispatch.__defineGetter("bkColor", Wnd_bkColor) 49 | $IDispatch.__defineGetter("width", Wnd_width) 50 | $IDispatch.__defineGetter("height", Wnd_height) 51 | $IDispatch.__defineGetter("clientWidth", Wnd_clientWidth) 52 | $IDispatch.__defineGetter("clientHeight", Wnd_clientHeight) 53 | $IDispatch.__defineGetter("title", Wnd_title) 54 | $IDispatch.__defineGetter("onExit", Wnd_onExit) 55 | $IDispatch.__defineGetter("graphics", Wnd_graphics) 56 | $IDispatch.__destructor(Wnd_Destructor) 57 | $IDispatch.__preventExtensions 58 | Return $IDispatch 59 | EndFunc 60 | 61 | Func Wnd_Destructor($oSelf) 62 | $oSelf.graphics=0 63 | EndFunc 64 | 65 | Func Wnd_Show($oSelf) 66 | GUISetState(@SW_SHOW, $oSelf.parent.hwnd) 67 | Return $oSelf.parent 68 | EndFunc 69 | 70 | Func Wnd_Hide($oSelf) 71 | GUISetState(@SW_HIDE, $oSelf.parent.hwnd) 72 | Return $oSelf.parent 73 | EndFunc 74 | 75 | Func Wnd_bkColor($oSelf) 76 | If Not ($oSelf.arguments.length==1) Then Return SetError(1, 1, $oSelf.parent) 77 | GUISetBkColor($oSelf.arguments.values[0], $oSelf.parent.hwnd) 78 | Return $oSelf.parent 79 | EndFunc 80 | 81 | Func Wnd_width($oSelf) 82 | If Not ($oSelf.arguments.length==1) Then Return SetError(1, 1, $oSelf.parent) 83 | Local $aPos = WinGetPos(ptr($oSelf.parent.hwnd), "") 84 | WinMove(ptr($oSelf.parent.hwnd), "", $aPos[0], $aPos[1], $oSelf.arguments.values[0], $aPos[3], 0) 85 | Return $oSelf.parent 86 | EndFunc 87 | 88 | Func Wnd_height($oSelf) 89 | If Not ($oSelf.arguments.length==1) Then Return SetError(1, 1, $oSelf.parent) 90 | Local $aPos = WinGetPos(ptr($oSelf.parent.hwnd)) 91 | WinMove(ptr($oSelf.parent.hwnd), "", $aPos[0], $aPos[1], $aPos[2], $oSelf.arguments.values[0], 0) 92 | Return $oSelf.parent 93 | EndFunc 94 | 95 | Func Wnd_clientWidth($oSelf) 96 | If ($oSelf.arguments.length==1) Then 97 | Local $aPos = WinGetPos(ptr($oSelf.parent.hwnd)) 98 | Local $tRECT01 = _WinAPI_GetWindowRect($oSelf.parent.hwnd) 99 | Local $tRECT02 = _WinAPI_GetClientRect($oSelf.parent.hwnd) 100 | WinMove(ptr($oSelf.parent.hwnd), "", $aPos[0], $aPos[1], (($tRECT01.Right-$tRECT02.Right)-($tRECT01.Left-$tRECT02.Left))+$oSelf.arguments.values[0], $aPos[3], 0) 101 | Return SetError(@error, @extended, $oSelf.parent) 102 | EndIf 103 | Return _WinAPI_GetClientWidth($oSelf.parent.hwnd) 104 | EndFunc 105 | 106 | 107 | Func Wnd_clientHeight($oSelf) 108 | If ($oSelf.arguments.length==1) Then 109 | Local $aPos = WinGetPos(ptr($oSelf.parent.hwnd)) 110 | Local $tRECT01 = _WinAPI_GetWindowRect($oSelf.parent.hwnd) 111 | Local $tRECT02 = _WinAPI_GetClientRect($oSelf.parent.hwnd) 112 | WinMove(ptr($oSelf.parent.hwnd), "", $aPos[0], $aPos[1], $aPos[2], (($tRECT01.Bottom-$tRECT02.Bottom)-($tRECT01.Top-$tRECT02.Top))+$oSelf.arguments.values[0], 0) 113 | Return SetError(@error, @extended, $oSelf.parent) 114 | EndIf 115 | Return _WinAPI_GetClientHeight($oSelf.parent.hwnd) 116 | EndFunc 117 | 118 | Func Wnd_title($oSelf) 119 | If Not ($oSelf.arguments.length==1) Then Return SetError(1, 1, $oSelf.parent) 120 | WinSetTitle(ptr($oSelf.parent.hwnd), "", $oSelf.arguments.values[0]) 121 | Return $oSelf.parent 122 | EndFunc 123 | 124 | Func Wnd_onExit($oSelf) 125 | If Not ($oSelf.arguments.length==1) Then Return SetError(1, 1, $oSelf.parent) 126 | opt("GuiOnEventMode", 1) 127 | GUISetOnEvent(-3, $oSelf.arguments.values[0], ptr($oSelf.parent.hwnd)) 128 | Return $oSelf.parent 129 | EndFunc 130 | 131 | Func Wnd_graphics($oSelf) 132 | If Not IsObj($oSelf.val) Then 133 | Local $IDispatch = IDispatch() 134 | $IDispatch.hwnd = _GDIPlus_GraphicsCreateFromHWND($oSelf.parent.hwnd) 135 | $IDispatch.__defineSetter("hwnd", PrivateProperty);PrivateProperty is defined in AutoItObject_Internal.au3 136 | $IDispatch.__defineSetter("parent", PrivateProperty);PrivateProperty is defined in AutoItObject_Internal.au3 137 | $IDispatch.__defineGetter("Clear", Graphics_Clear) 138 | $IDispatch.__defineGetter("DrawRect", Graphics_DrawRect) 139 | $IDispatch.__defineGetter("FillRect", Graphics_FillRect) 140 | $IDispatch.__destructor(Graphics_Dispose) 141 | $IDispatch.__preventExtensions 142 | $oSelf.val = $IDispatch 143 | Return $IDispatch 144 | EndIf 145 | Return $oSelf.val 146 | EndFunc 147 | 148 | Func Graphics_Clear($oSelf) 149 | _GDIPlus_GraphicsClear($oSelf.parent.hwnd, ($oSelf.arguments.length>0)?$oSelf.arguments.values[0]:Default) 150 | Return SetError(@error, @extended, $oSelf.parent) 151 | EndFunc 152 | 153 | Func Graphics_Dispose($oSelf) 154 | _GDIPlus_GraphicsDispose($oSelf.hwnd) 155 | EndFunc 156 | 157 | Func Graphics_DrawRect($oSelf) 158 | ;~ MsgBox(0, "", $oSelf.parent.hwnd&@CRLF&$oSelf.arguments.values[4].hwnd) 159 | _GDIPlus_GraphicsDrawRect($oSelf.parent.hwnd, $oSelf.arguments.values[0], $oSelf.arguments.values[1], $oSelf.arguments.values[2], $oSelf.arguments.values[3], $oSelf.arguments.values[4].hwnd) 160 | Return SetError(@error, @extended, $oSelf.parent) 161 | EndFunc 162 | 163 | Func Graphics_FillRect($oSelf) 164 | _GDIPlus_GraphicsFillRect($oSelf.parent.hwnd, $oSelf.arguments.values[0], $oSelf.arguments.values[1], $oSelf.arguments.values[2], $oSelf.arguments.values[3], $oSelf.arguments.values[4].hwnd) 165 | Return SetError(@error, @extended, $oSelf.parent) 166 | EndFunc 167 | 168 | Func Pen($color=Default, $width=Default) 169 | Local $IDispatch = IDispatch() 170 | $IDispatch.hwnd = _GDIPlus_PenCreate($color, $width) 171 | $IDispatch.__defineSetter("hwnd", PrivateProperty);PrivateProperty is defined in AutoItObject_Internal.au3 172 | $IDispatch.__defineGetter("color", Pen_color) 173 | $IDispatch.__destructor(Pen_Dispose) 174 | $IDispatch.__preventExtensions 175 | Return $IDispatch 176 | EndFunc 177 | 178 | Func Pen_color($oSelf) 179 | If $oSelf.arguments.length=0 Then Return _GDIPlus_PenGetColor($oSelf.parent.hwnd) 180 | _GDIPlus_PenSetColor($oSelf.parent.hwnd, $oSelf.arguments.values[0]) 181 | Return SetError(@error, @extended, $oSelf.parent) 182 | EndFunc 183 | 184 | Func Pen_Dispose($oSelf) 185 | _GDIPlus_PenDispose($oSelf.hwnd) 186 | EndFunc 187 | 188 | Func Brush($color=Default) 189 | Local $IDispatch = IDispatch() 190 | $IDispatch.hwnd = _GDIPlus_BrushCreateSolid($color) 191 | $IDispatch.__defineSetter("hwnd", PrivateProperty);PrivateProperty is defined in AutoItObject_Internal.au3 192 | $IDispatch.__defineGetter("color", Brush_color) 193 | $IDispatch.__destructor(Brush_Dispose) 194 | $IDispatch.__preventExtensions 195 | Return $IDispatch 196 | EndFunc 197 | 198 | Func Brush_color($oSelf) 199 | If $oSelf.arguments.length=0 Then Return _GDIPlus_BrushGetSolidColor($oSelf.parent.hwnd) 200 | _GDIPlus_BrushSetSolidColor($oSelf.parent.hwnd, $oSelf.arguments.values[0]) 201 | Return SetError(@error, @extended, $oSelf.parent) 202 | EndFunc 203 | 204 | Func Brush_Dispose($oSelf) 205 | _GDIPlus_BrushDispose($oSelf.hwnd) 206 | EndFunc -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | ### Added 9 | 10 | ### Changed 11 | 12 | ### Removed 13 | 14 | ### Fixed 15 | 16 | ## [4.0.1] - 2022-07-11 17 | ### Fixed 18 | - Crash when creating too many objects (f86a0c40b45915a7b215b86a89aa5c2d92cdae23) 19 | - Could not modify the default object method property `$oIDispatch()` (58fa551319727450e39ee171ae574438b0815372) 20 | 21 | ## [4.0.0] - 2022-07-08 22 | ### Added 23 | - new global varaible `$__AOI_tagObject` 24 | - new global enums `$__AOI_ConstantProperty_*` 25 | - new test for `__unset` method 26 | - internal use function `__AOI_Properties_Add` 27 | - internal use function `__AOI_VariantReplace` 28 | - internal use function `__AOI_Properties_Resize` 29 | - internal use function `__AOI_Properties_Remove` 30 | - internal use function `__AOI_Invoke_isExtensible` 31 | - internal use function `__AOI_Invoke_case` 32 | - internal use function `__AOI_Invoke_lookupSetter` 33 | - internal use function `__AOI_Invoke_lookupGetter` 34 | - internal use function `__AOI_Invoke_assign` 35 | - internal use function `__AOI_Invoke_isSealed` 36 | - internal use function `__AOI_Invoke_isFrozen` 37 | - internal use function `__AOI_Invoke_get` 38 | - internal use function `__AOI_Invoke_set` 39 | - internal use function `__AOI_Invoke_exists` 40 | - internal use function `__AOI_Invoke_destructor` 41 | - internal use function `__AOI_Invoke_freeze` 42 | - internal use function `__AOI_Invoke_seal` 43 | - internal use function `__AOI_Invoke_preventExtensions` 44 | - internal use function `__AOI_Invoke_unset` 45 | - internal use function `__AOI_Invoke_keys` 46 | - internal use function `__AOI_Invoke_defineGetter` 47 | - internal use function `__AOI_Invoke_defineSetter` 48 | 49 | ### Changed 50 | - use of new global variable `$__AOI_tagObject` for object struct reference. 51 | - use of new global enums `$__AOI_ConstantProperty_*` for built in IDispatch object methods (negative id range). 52 | - use of new global varaibles `$__AOI_Object_Element_*` for object pointer element offsets. 53 | - IDispatch properties are now stored as an array instead of a singly linked list. (63836f6a2832c4e4123a00961a8d2184f58e0266) 54 | - function rename `QueryInterface` => `__AOI_QueryInterface` 55 | - function rename `AddRef` => `__AOI_AddRef` 56 | - function rename `Release` => `__AOI_Release` 57 | - function rename `GetIDsOfNames` => `__AOI_GetIDsOfNames` 58 | - function rename `GetTypeInfo` => `__AOI_GetTypeInfo` 59 | - function rename `GetTypeInfoCount` => `__AOI_GetTypeInfoCount` 60 | - function rename `Invoke` => `__AOI_Invoke` 61 | - function rename `MemCloneGlob` => `__AOI_MemCloneGlob` 62 | - function rename `GlobalHandle` => `__AOI_GlobalHandle` 63 | - function rename `VariantInit` => `__AOI_VariantInit` 64 | - function rename `VariantCopy` => `__AOI_VariantCopy` 65 | - function rename `VariantClear` => `__AOI_VariantClear` 66 | - function rename `PrivateProperty` => `_AOI_PrivateProperty` 67 | - variable rename `$IID_IUnknown` => `$__AOI_IID_IUnknown` 68 | - variable rename `$IID_IDispatch` => `$__AOI_IID_IDispatch` 69 | - variable rename `$IID_IConnectionPointContainer` => `$__AOI_IID_IConnectionPointContainer` 70 | - variable rename `$DISPATCH_METHOD` => `$__AOI_DISPATCH_METHOD` 71 | - variable rename `$DISPATCH_PROPERTYGET` => `$__AOI_DISPATCH_PROPERTYGET` 72 | - variable rename `$DISPATCH_PROPERTYPUT` => `$__AOI_DISPATCH_PROPERTYPUT` 73 | - variable rename `$DISPATCH_PROPERTYPUTREF` => `$__AOI_DISPATCH_PROPERTYPUTREF` 74 | - variable rename `$S_OK` => `$__AOI_S_OK` 75 | - variable rename `$E_NOTIMPL` => `$__AOI_E_NOTIMPL` 76 | - variable rename `$E_NOINTERFACE` => `$__AOI_E_NOINTERFACE` 77 | - variable rename `$E_POINTER` => `$__AOI_E_POINTER` 78 | - variable rename `$E_ABORT` => `$__AOI_E_ABORT` 79 | - variable rename `$E_FAIL` => `$__AOI_E_FAIL` 80 | - variable rename `$E_ACCESSDENIED` => `$__AOI_E_ACCESSDENIED` 81 | - variable rename `$E_HANDLE` => `$__AOI_E_HANDLE` 82 | - variable rename `$E_OUTOFMEMORY` => `$__AOI_E_OUTOFMEMORY` 83 | - variable rename `$E_INVALIDARG` => `$__AOI_E_INVALIDARG` 84 | - variable rename `$E_UNEXPECTED` => `$__AOI_E_UNEXPECTED` 85 | - variable rename `$DISP_E_UNKNOWNINTERFACE` => `$__AOI_DISP_E_UNKNOWNINTERFACE` 86 | - variable rename `$DISP_E_MEMBERNOTFOUND` => `$__AOI_DISP_E_MEMBERNOTFOUND` 87 | - variable rename `$DISP_E_PARAMNOTFOUND` => `$__AOI_DISP_E_PARAMNOTFOUND` 88 | - variable rename `$DISP_E_TYPEMISMATCH` => `$__AOI_DISP_E_TYPEMISMATCH` 89 | - variable rename `$DISP_E_UNKNOWNNAME` => `$__AOI_DISP_E_UNKNOWNNAME` 90 | - variable rename `$DISP_E_NONAMEDARGS` => `$__AOI_DISP_E_NONAMEDARGS` 91 | - variable rename `$DISP_E_BADVARTYPE` => `$__AOI_DISP_E_BADVARTYPE` 92 | - variable rename `$DISP_E_EXCEPTION` => `$__AOI_DISP_E_EXCEPTION` 93 | - variable rename `$DISP_E_OVERFLOW` => `$__AOI_DISP_E_OVERFLOW` 94 | - variable rename `$DISP_E_BADINDEX` => `$__AOI_DISP_E_BADINDEX` 95 | - variable rename `$DISP_E_UNKNOWNLCID` => `$__AOI_DISP_E_UNKNOWNLCID` 96 | - variable rename `$DISP_E_ARRAYISLOCKED` => `$__AOI_DISP_E_ARRAYISLOCKED` 97 | - variable rename `$DISP_E_BADPARAMCOUNT` => `$__AOI_DISP_E_BADPARAMCOUNT` 98 | - variable rename `$DISP_E_PARAMNOTOPTIONAL` => `$__AOI_DISP_E_PARAMNOTOPTIONAL` 99 | - variable rename `$DISP_E_BADCALLEE` => `$__AOI_DISP_E_BADCALLEE` 100 | - variable rename `$DISP_E_NOTACOLLECTION` => `$__AOI_DISP_E_NOTACOLLECTION` 101 | - variable rename `$tagVARIANT` => `$__AOI_tagVARIANT` 102 | - variable rename `$tagDISPPARAMS` => `$__AOI_tagDISPPARAMS` 103 | - variable rename `$VT_*` => `$__AOI_VT_*` 104 | - variable rename `$tagProperty` => `$__AOI_tagProperty` 105 | 106 | ### Removed 107 | - function `__AOI_PropertyCreate` 108 | - function `LocalSize` 109 | - function `LocalHandle` 110 | - function `HeapSize` 111 | - function `GetProcessHeap` 112 | - function `VariantChangeType` 113 | - function `VariantChangeTypeEx` 114 | - function `__AOI_GetPtrValue` 115 | 116 | ## [3.0.0] - 2021-02-18 117 | ### Added 118 | - __exists 119 | - _AOI_ROT_register 120 | - _AOI_ROT_revoke 121 | - Internal use function __AOI_ROT_GetRunningObjectTable 122 | - Internal use function __AOI_ROT_CreateFileMoniker 123 | 124 | ### Changed 125 | - output of __keys() will now always return array 126 | - value comparison operators for non string data now wont be type juggling values to strings 127 | 128 | ### Fixed 129 | - QueryInterface did not call AddRef when returning valid pointer 130 | - __unset did not handle as case insensitive if case insensitive mode was on 131 | - Calling IDispatch object as function, would result in first element. Now property with key "" will be searched for. If not found in properties, object will throw exception for this special case! 132 | 133 | ## [2.0.0] - 2018-07-07 134 | ### Added 135 | - This CHANGELOG.md file 136 | - CONTRIBUTING.md file 137 | - Tests 138 | - __get 139 | - __set 140 | - __assign 141 | - __freeze 142 | - __isFrozen 143 | - __isSealed 144 | - __preventExtensions 145 | - __isExtensible 146 | - __lookupGetter 147 | - __lookupSetter 148 | - __seal 149 | - __case 150 | - internal use function __AOI_PropertyGetFromName 151 | - internal use function __AOI_PropertyGetFromId 152 | - internal use function __AOI_PropertyCreate 153 | - internal use function __AOI_GetPtrOffset 154 | - internal use function __AOI_GetPtrValue 155 | 156 | ### Changed 157 | - Moved project to it's own repository 158 | - __defineGetter and __defineSetter now also supports strings as second argument 159 | - __destructor now also supports strings as first argument 160 | - Split docs from readme into /docs/index.md 161 | - documentation blocks are now following a more standardized docblock standard. 162 | 163 | ### Removed 164 | - __lock 165 | 166 | ### Fixed 167 | - desctructor pointer wrong offset after lock propterty was added to the object structure. 168 | 169 | ## [1.0.3] - 2017-08-11 170 | ### Added 171 | - __desctructor 172 | - Garbage collection, with the exception of interface methods 173 | 174 | ## [1.0.2] - 2017-08-09 175 | ### Added 176 | - Parameters for assigning custom methods as IDispatch object internal functionality 177 | - __keys 178 | - PrivateProperty method for ease of use, when making private IDispatch object properties 179 | 180 | ## [1.0.1] - 2016-08-06 181 | ### Added 182 | - Local scope for internal variables used by IDispatch object functionality 183 | 184 | ## [1.0.0] - 2016-08-06 185 | ### Added 186 | - README.md file 187 | - __unset 188 | - __lock 189 | - Accessors can set error code via setError 190 | - Supprt for __all__ AutoIt variable types 191 | 192 | ## [0.1.2] - 2016-12-21 193 | ### Added 194 | - __defineMethod 195 | - Method support for objects 196 | 197 | ## [0.1.1] - 2016-11-25 198 | ### Changed 199 | - Fix script breaking typo in Idispatch function, reported by [Chimp on the AutoIt forum thread](https://www.autoitscript.com/forum/topic/185720-autoitobject-pure-autoit/#elComment_1333941) 200 | 201 | ## [0.1.0] - 2016-11-24 202 | ### Added 203 | - First iteration of the AutoItObject_Internal library 204 | - Accessors via __defineGetter and __defineSetter 205 | -------------------------------------------------------------------------------- /Tests/Dev.au3: -------------------------------------------------------------------------------- 1 | Func GetIDsOfNames2($pSelf, $riid, $rgszNames, $cNames, $lcid, $rgDispId) 2 | Local $tIds = DllStructCreate("long", $rgDispId); 2,147,483,647 properties available to define, per object. And 2,147,483,647 private properties to set in the negative space, per object. 3 | Local $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")),1) 4 | Local $tProperty = 0 5 | Local $iSize2 6 | 7 | Local $pStr = DllStructGetData(DllStructCreate("ptr", $rgszNames), 1) 8 | Local $iSize = _WinAPI_StrLen($pStr, True) 9 | Local $t_rgszNames = DllStructCreate("WCHAR["&$iSize&"]", $pStr) 10 | Local $s_rgszName = DllStructGetData($t_rgszNames, 1) 11 | 12 | ;TODO: implement for loop, to allow processing of each Name provided 13 | 14 | ;~ If $s_rgszName == "" Then 15 | ;look into possible toString emulation 16 | ;~ ElseIf StringLeft($s_rgszName, 2) == "__" Then;to try and improve speed 17 | Switch $s_rgszName 18 | Case "__assign" 19 | DllStructSetData($tIds, 1, -2) 20 | ;~ Case "__clone" 21 | ;~ DllStructSetData($tIds, 1, -3) 22 | Case "__case" 23 | DllStructSetData($tIds, 1, -4) 24 | Case "__freeze" 25 | DllStructSetData($tIds, 1, -5) 26 | Case "__isFrozen" 27 | DllStructSetData($tIds, 1, -6) 28 | Case "__isSealed" 29 | DllStructSetData($tIds, 1, -7) 30 | Case "__keys" 31 | DllStructSetData($tIds, 1, -8) 32 | Case "__preventExtensions" 33 | DllStructSetData($tIds, 1, -9) 34 | Case "__defineGetter" 35 | DllStructSetData($tIds, 1, -10) 36 | Case "__defineSetter" 37 | DllStructSetData($tIds, 1, -11) 38 | Case "__lookupGetter" 39 | DllStructSetData($tIds, 1, -12) 40 | Case "__lookupSetter" 41 | DllStructSetData($tIds, 1, -13) 42 | Case "__seal" 43 | DllStructSetData($tIds, 1, -14) 44 | ;~ Case "__values" 45 | ;~ DllStructSetData($tIds, 1, -15) 46 | Case "__destructor" 47 | DllStructSetData($tIds, 1, -16) 48 | Case "__unset" 49 | DllStructSetData($tIds, 1, -17) 50 | Case "__get" 51 | DllStructSetData($tIds, 1, -18) 52 | Case "__set" 53 | DllStructSetData($tIds, 1, -19) 54 | Case Else 55 | DllStructSetData($tIds, 1, -1) 56 | ;~ Return $DISP_E_UNKNOWNNAME 57 | EndSwitch 58 | If DllStructGetData($tIds, 1) <> -1 Then Return $S_OK 59 | ;~ EndIf 60 | 61 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 62 | Local $bCase = Not (BitAND($iLock, $__AutoItObjectInternal_LOCK_CASE)>0) 63 | Local $pProperty = __AutoItObjectInternal_PropertyGetFromName(__AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("Properties"), "ptr"), DllStructGetData($t_rgszNames, 1), $bCase) 64 | Local $iID = @error<>0?-1:@extended 65 | Local $iIndex = @extended 66 | 67 | If ($iID==-1) And BitAND($iLock, $__AutoItObjectInternal_LOCK_CREATE)=0 Then 68 | Local $pData = __AutoItObjectInternal_PropertyCreate(DllStructGetData($t_rgszNames, 1)) 69 | If $iIndex=-1 Then;first item in list 70 | DllStructSetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")), 1, $pData) 71 | Else 72 | $tProperty = DllStructCreate($tagProperty, $pProperty) 73 | $tProperty.next = $pData 74 | EndIf 75 | $iID = $iIndex+1 76 | EndIf 77 | 78 | If $iID==-1 Then Return $DISP_E_UNKNOWNNAME 79 | DllStructSetData($tIds, 1, $iID) 80 | Return $S_OK 81 | EndFunc 82 | 83 | Func Invoke2($pSelf, $dispIdMember, $riid, $lcid, $wFlags, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr) 84 | If $dispIdMember=-1 Then Return $DISP_E_MEMBERNOTFOUND 85 | Local $tVARIANT, $_tVARIANT, $tDISPPARAMS 86 | Local $t 87 | Local $i 88 | 89 | Local $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")),1) 90 | Local $tProperty = DllStructCreate($tagProperty, $pProperty) 91 | 92 | If $dispIdMember<-1 Then 93 | If $dispIdMember=-4 Then;__case 94 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 95 | If (Not(BitAND($wFlags, $DISPATCH_PROPERTYGET)=0)) Then 96 | If $tDISPPARAMS.cArgs<>0 Then Return $DISP_E_BADPARAMCOUNT 97 | $tVARIANT=DllStructCreate($tagVARIANT, $pVarResult) 98 | $tVARIANT.vt = $VT_BOOL 99 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 100 | $tVARIANT.data = (BitAND($iLock, $__AutoItObjectInternal_LOCK_CASE)>0)?0:1 101 | Else; $DISPATCH_PROPERTYPUT 102 | If $tDISPPARAMS.cArgs<>1 Then Return $DISP_E_BADPARAMCOUNT 103 | $tVARIANT=DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs) 104 | If $tVARIANT.vt<>$VT_BOOL Then Return $DISP_E_BADVARTYPE 105 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 106 | If BitAND($iLock, $__AutoItObjectInternal_LOCK_UPDATE)>0 Then Return $DISP_E_EXCEPTION 107 | Local $tLock = DllStructCreate("BYTE", $pSelf + __AutoItObjectInternal_GetPtrOffset("lock")) 108 | $b = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data") 109 | DllStructSetData($tLock, 1, _ 110 | (Not $b) ? BitOR(DllStructGetData($tLock, 1), $__AutoItObjectInternal_LOCK_CASE) : BitAND(DllStructGetData($tLock, 1), BitNOT(BitShift(1 , 0-(Log($__AutoItObjectInternal_LOCK_CASE)/log(2))))) _ 111 | ) 112 | 113 | EndIf 114 | Return $S_OK 115 | EndIf 116 | 117 | If $dispIdMember=-13 Then;__lookupSetter 118 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 119 | If $tDISPPARAMS.cArgs<>1 Then Return $DISP_E_BADPARAMCOUNT 120 | 121 | $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 122 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 123 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs) 124 | $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data") 125 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 126 | If Not GetIDsOfNames2($pSelf, $riid, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) == $S_OK Then Return $DISP_E_EXCEPTION 127 | 128 | $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")),1) 129 | $tProperty = __AutoItObjectInternal_PropertyGetFromId($pProperty, $t.id) 130 | If Not $tProperty.__setter=0 Then 131 | VariantClear($pVarResult) 132 | VariantCopy($pVarResult, $tProperty.__setter) 133 | EndIf 134 | Return $S_OK 135 | EndIf 136 | 137 | If $dispIdMember=-12 Then;__lookupGetter 138 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 139 | If $tDISPPARAMS.cArgs<>1 Then Return $DISP_E_BADPARAMCOUNT 140 | 141 | $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 142 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 143 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs) 144 | $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data") 145 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 146 | If Not GetIDsOfNames2($pSelf, $riid, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) == $S_OK Then Return $DISP_E_EXCEPTION 147 | 148 | $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")),1) 149 | $tProperty = __AutoItObjectInternal_PropertyGetFromId($pProperty, $t.id) 150 | If Not $tProperty.__getter=0 Then 151 | VariantClear($pVarResult) 152 | VariantCopy($pVarResult, $tProperty.__getter) 153 | EndIf 154 | Return $S_OK 155 | EndIf 156 | 157 | If $dispIdMember=-2 Then;__assign 158 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 159 | If BitAND($iLock, $__AutoItObjectInternal_LOCK_CREATE)>0 Then Return $DISP_E_EXCEPTION 160 | 161 | 162 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 163 | If $tDISPPARAMS.cArgs=0 Then Return $DISP_E_BADPARAMCOUNT 164 | 165 | ;FIXME 166 | Local $tVARIANT = DllStructCreate($tagVARIANT) 167 | Local $iVARIANT = DllStructGetSize($tVARIANT) 168 | Local $i 169 | Local $pExternalProperty, $tExternalProperty 170 | Local $pProperty, $tProperty 171 | Local $iID, $iIndex, $pData 172 | For $i=$tDISPPARAMS.cArgs-1 To 0 Step -1 173 | $tVARIANT=DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs+$iVARIANT*$i) 174 | If Not (DllStructGetData($tVARIANT, "vt")==$VT_DISPATCH) Then Return $DISP_E_BADVARTYPE 175 | $pExternalProperty = __AutoItObjectInternal_GetPtrValue(DllStructGetData($tVARIANT, "data") + __AutoItObjectInternal_GetPtrOffset("Properties"), "ptr") 176 | While 1 177 | ConsoleWrite($pExternalProperty&@CRLF) 178 | If $pExternalProperty = 0 Then ExitLoop 179 | $tExternalProperty = DllStructCreate($tagProperty, $pExternalProperty) 180 | ConsoleWrite(_WinAPI_GetString($tExternalProperty.Name)&@CRLF) 181 | 182 | $pProperty = __AutoItObjectInternal_PropertyGetFromName(__AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("Properties"), "ptr"), _WinAPI_GetString($tExternalProperty.Name), False) 183 | $iID = @error<>0?-1:@extended 184 | $iIndex = @extended 185 | 186 | If ($iID==-1) Then 187 | $pData = __AutoItObjectInternal_PropertyCreate(_WinAPI_GetString($tExternalProperty.Name)) 188 | $tProperty = DllStructCreate($tagProperty, $pData) 189 | VariantClear($tProperty.Variant) 190 | VariantCopy($tProperty.Variant, $tExternalProperty.Variant) 191 | 192 | If $iIndex=-1 Then;first item in list 193 | DllStructSetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")), 1, $pData) 194 | Else 195 | $tProperty = DllStructCreate($tagProperty, $pProperty) 196 | $tProperty.Next = $pData 197 | EndIf 198 | Else 199 | $tProperty = DllStructCreate($tagProperty, $pProperty) 200 | VariantClear($tProperty.Variant) 201 | VariantCopy($tProperty.Variant, $tExternalProperty.Variant) 202 | EndIf 203 | 204 | $pExternalProperty = $tExternalProperty.Next 205 | WEnd 206 | Next 207 | Return $S_OK 208 | EndIf 209 | 210 | If $dispIdMember=-7 Then;__isSealed 211 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 212 | Local $iSeal = $__AutoItObjectInternal_LOCK_CREATE + $__AutoItObjectInternal_LOCK_DELETE 213 | $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult) 214 | $tVARIANT.vt = $VT_BOOL 215 | $tVARIANT.data = (BitAND($iLock, $iSeal) = $iSeal)?1:0 216 | Return $S_OK 217 | EndIf 218 | 219 | If $dispIdMember=-6 Then;__isFrozen 220 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 221 | Local $iFreeze = $__AutoItObjectInternal_LOCK_CREATE + $__AutoItObjectInternal_LOCK_UPDATE + $__AutoItObjectInternal_LOCK_DELETE 222 | $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult) 223 | $tVARIANT.vt = $VT_BOOL 224 | $tVARIANT.data = (BitAND($iLock, $iFreeze) = $iFreeze)?1:0 225 | Return $S_OK 226 | EndIf 227 | 228 | If $dispIdMember=-18 Then;__get 229 | ;TODO: check number of parameters == 1 and the parameter type is bstr 230 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 231 | $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 232 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 233 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs+DllStructGetSize(DllStructCreate($tagVARIANT))) 234 | $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data") 235 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 236 | If Not GetIDsOfNames2($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION 237 | Return Invoke2($pSelf, $t.id, $riid, $lcid, $DISPATCH_PROPERTYGET, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr) 238 | EndIf 239 | 240 | If $dispIdMember=-19 Then;__set 241 | ;TODO: check number of parameters == 2 and parameter 1 type is bstr 242 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 243 | $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 244 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 245 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs+DllStructGetSize(DllStructCreate($tagVARIANT))) 246 | $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs+DllStructGetSize(DllStructCreate($tagVARIANT))), "data") 247 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 248 | If Not GetIDsOfNames2($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION 249 | Return Invoke2($pSelf, $t.id, $riid, $lcid, $DISPATCH_PROPERTYPUT, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr) 250 | EndIf 251 | 252 | If $dispIdMember=-16 Then;__destructor 253 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 254 | If BitAND($iLock, $__AutoItObjectInternal_LOCK_CREATE)>0 Then Return $DISP_E_EXCEPTION 255 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 256 | If $tDISPPARAMS.cArgs<>1 Then Return $DISP_E_BADPARAMCOUNT 257 | If Not (DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs),"vt")==$VT_RECORD) Then Return $DISP_E_BADVARTYPE 258 | Local $tVARIANT = DllStructCreate($tagVARIANT) 259 | Local $pVARIANT = MemCloneGlob($tVARIANT) 260 | $tVARIANT = DllStructCreate($tagVARIANT, $pVARIANT) 261 | VariantInit($pVARIANT) 262 | VariantCopy($pVARIANT, $tDISPPARAMS.rgvargs) 263 | DllStructSetData(DllStructCreate("PTR", $pSelf + __AutoItObjectInternal_GetPtrOffset("__destructor")),1,$pVARIANT) 264 | Return $S_OK 265 | EndIf 266 | 267 | If $dispIdMember=-5 Then;__freeze 268 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 269 | If $tDISPPARAMS.cArgs<>0 Then Return $DISP_E_BADPARAMCOUNT 270 | Local $tLock = DllStructCreate("BYTE", $pSelf + __AutoItObjectInternal_GetPtrOffset("lock")) 271 | DllStructSetData($tLock, 1, BitOR(DllStructGetData($tLock, 1), $__AutoItObjectInternal_LOCK_CREATE + $__AutoItObjectInternal_LOCK_DELETE + $__AutoItObjectInternal_LOCK_UPDATE)) 272 | Return $S_OK 273 | EndIf 274 | 275 | If $dispIdMember=-14 Then;__seal 276 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 277 | If $tDISPPARAMS.cArgs<>0 Then Return $DISP_E_BADPARAMCOUNT 278 | Local $tLock = DllStructCreate("BYTE", $pSelf + __AutoItObjectInternal_GetPtrOffset("lock")) 279 | DllStructSetData($tLock, 1, BitOR(DllStructGetData($tLock, 1), $__AutoItObjectInternal_LOCK_CREATE + $__AutoItObjectInternal_LOCK_DELETE)) 280 | Return $S_OK 281 | EndIf 282 | 283 | If $dispIdMember=-9 Then;__preventExtensions 284 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 285 | If $tDISPPARAMS.cArgs<>0 Then Return $DISP_E_BADPARAMCOUNT 286 | Local $tLock = DllStructCreate("BYTE", $pSelf + __AutoItObjectInternal_GetPtrOffset("lock")) 287 | DllStructSetData($tLock, 1, BitOR(DllStructGetData($tLock, 1), $__AutoItObjectInternal_LOCK_CREATE)) 288 | Return $S_OK 289 | EndIf 290 | 291 | If $dispIdMember=-17 Then;__unset 292 | ;TODO: remove getter/setter if !=0 293 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 294 | If BitAND($iLock, $__AutoItObjectInternal_LOCK_DELETE)>0 Then Return $DISP_E_EXCEPTION 295 | 296 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 297 | If $tDISPPARAMS.cArgs<>1 Then Return $DISP_E_BADPARAMCOUNT 298 | $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs) 299 | If Not($VT_BSTR==$tVARIANT.vt) Then Return $DISP_E_BADVARTYPE 300 | Local $sProperty = _WinAPI_GetString($tVARIANT.data);the string to search for 301 | Local $tProperty=0,$tProperty_Prev 302 | While 1 303 | If $pProperty=0 Then ExitLoop 304 | $tProperty_Prev = $tProperty 305 | $tProperty = DllStructCreate($tagProperty, $pProperty) 306 | If _WinAPI_GetString($tProperty.Name)==$sProperty Then 307 | If $tProperty_Prev==0 Then 308 | DllStructSetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")), 1, $tProperty.Next) 309 | Else 310 | $tProperty_Prev.Next = $tProperty.next 311 | EndIf 312 | VariantClear($tProperty.Variant) 313 | _MemGlobalFree(GlobalHandle($tProperty.Variant)) 314 | $tProperty = 0 315 | _MemGlobalFree(GlobalHandle($pProperty)) 316 | Return $S_OK 317 | EndIf 318 | $pProperty = $tProperty.Next 319 | WEnd 320 | Return $DISP_E_MEMBERNOTFOUND 321 | EndIf 322 | 323 | If ($dispIdMember=-8) Then;__keys 324 | Local $aKeys[1] 325 | Local $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")),1) 326 | While 1 327 | If $pProperty=0 Then ExitLoop 328 | Local $tProperty = DllStructCreate($tagProperty, $pProperty) 329 | $aKeys[UBound($aKeys,1)-1] = DllStructGetData(DllStructCreate("WCHAR["&_WinAPI_StrLen($tProperty.Name)&"]", $tProperty.Name), 1) 330 | If $tProperty.next=0 Then ExitLoop 331 | ReDim $aKeys[UBound($aKeys,1)+1] 332 | $pProperty = $tProperty.next 333 | WEnd 334 | If $pProperty=0 Then Return $S_OK 335 | Local $oIDispatch = IDispatch() 336 | $oIDispatch.a=$aKeys 337 | VariantClear($pVarResult) 338 | VariantCopy($pVarResult, DllStructGetData(DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AutoItObjectInternal_GetPtrOffset("Properties")),1)), "Variant")) 339 | $oIDispatch=0 340 | Return $S_OK 341 | EndIf 342 | 343 | If ($dispIdMember=-10) Then;__defineGetter 344 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 345 | If BitAND($iLock, $__AutoItObjectInternal_LOCK_CREATE)>0 Then Return $DISP_E_EXCEPTION 346 | 347 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 348 | If $tDISPPARAMS.cArgs<>2 Then Return $DISP_E_BADPARAMCOUNT 349 | $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs) 350 | If Not (($tVARIANT.vt==$VT_RECORD) Or ($tVARIANT.vt==$VT_BSTR)) Then Return $DISP_E_BADVARTYPE 351 | Local $tVARIANT2 = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs+DllStructGetSize($tVARIANT)) 352 | If Not ($tVARIANT2.vt==$VT_BSTR) Then Return $DISP_E_BADVARTYPE 353 | 354 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 355 | $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 356 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 357 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs+DllStructGetSize(DllStructCreate($tagVARIANT))) 358 | $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs+DllStructGetSize(DllStructCreate($tagVARIANT))), "data") 359 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 360 | GetIDsOfNames2($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id"));TODO 361 | 362 | $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")),1) 363 | $tProperty = __AutoItObjectInternal_PropertyGetFromId($pProperty, $t.id) 364 | 365 | If ($tProperty.__getter=0) Then 366 | Local $tVARIANT_Getter = DllStructCreate($tagVARIANT) 367 | $pVARIANT_Getter = MemCloneGlob($tVARIANT_Getter) 368 | VariantInit($pVARIANT_Getter) 369 | Else 370 | Local $pVARIANT_Getter = $tProperty.__getter 371 | VariantClear($pVARIANT_Getter) 372 | EndIf 373 | $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs) 374 | VariantCopy($pVARIANT_Getter, $tVARIANT) 375 | $tProperty.__getter = $pVARIANT_Getter 376 | Return $S_OK 377 | ElseIf ($dispIdMember=-11) Then;defineSetter 378 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 379 | If BitAND($iLock, $__AutoItObjectInternal_LOCK_CREATE)>0 Then Return $DISP_E_EXCEPTION 380 | 381 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 382 | If $tDISPPARAMS.cArgs<>2 Then Return $DISP_E_BADPARAMCOUNT 383 | $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs) 384 | If Not (($tVARIANT.vt==$VT_RECORD) Or ($tVARIANT.vt==$VT_BSTR)) Then Return $DISP_E_BADVARTYPE 385 | Local $tVARIANT2 = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs+DllStructGetSize($tVARIANT)) 386 | If Not ($tVARIANT2.vt==$VT_BSTR) Then Return $DISP_E_BADVARTYPE 387 | 388 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 389 | $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 390 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 391 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs+DllStructGetSize(DllStructCreate($tagVARIANT))) 392 | $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs+DllStructGetSize(DllStructCreate($tagVARIANT))), "data") 393 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 394 | GetIDsOfNames2($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id"));TODO 395 | 396 | $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AutoItObjectInternal_GetPtrOffset("Properties")),1) 397 | $tProperty = DllStructCreate($tagProperty, $pProperty) 398 | 399 | $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs) 400 | For $i=1 To $t.id 401 | $pProperty = $tProperty.Next 402 | $tProperty = DllStructCreate($tagProperty, $pProperty) 403 | Next 404 | If ($tProperty.__setter=0) Then 405 | Local $tVARIANT_Setter = DllStructCreate($tagVARIANT) 406 | Local $pVARIANT_Setter = MemCloneGlob($tVARIANT_Setter) 407 | VariantInit($pVARIANT_Setter) 408 | Else 409 | Local $pVARIANT_Setter = $tProperty.__setter 410 | VariantClear($pVARIANT_Setter) 411 | EndIf 412 | VariantCopy($pVARIANT_Setter, $tVARIANT) 413 | $tProperty.__setter = $pVARIANT_Setter 414 | Return $S_OK 415 | EndIf 416 | Return $DISP_E_EXCEPTION;TODO: The application needs to raise an exception. In this case, the structure passed in pexcepinfo should be filled in. 417 | EndIf 418 | 419 | For $i=1 To $dispIdMember 420 | $pProperty = $tProperty.Next 421 | $tProperty = DllStructCreate($tagProperty, $pProperty) 422 | Next 423 | 424 | $tVARIANT = DllStructCreate($tagVARIANT, $tProperty.Variant) 425 | 426 | ;~ If (Not(BitAND($wFlags, $DISPATCH_PROPERTYGET)=0)) And (Not(BitAND($wFlags, $DISPATCH_METHOD)=0)) Then 427 | If (Not(BitAND($wFlags, $DISPATCH_PROPERTYGET)=0)) Then 428 | $_tVARIANT = DllStructCreate($tagVARIANT, $pVarResult) 429 | If Not($tProperty.__getter = 0) Then 430 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 431 | Local $oIDispatch = IDispatch() 432 | $oIDispatch.val = 0 433 | $oIDispatch.ret = 0 434 | DllStructSetData(DllStructCreate("INT", $pSelf-4-4), 1, DllStructGetData(DllStructCreate("INT", $pSelf-4-4), 1)+1) 435 | $oIDispatch.parent = 0 436 | Local $tProperty02 = DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", ptr($oIDispatch) + __AutoItObjectInternal_GetPtrOffset("Properties")),1)) 437 | $tProperty02=DllStructCreate($tagProperty, $tProperty02.Next) 438 | $tProperty02=DllStructCreate($tagProperty, $tProperty02.Next) 439 | $tVARIANT = DllStructCreate($tagVARIANT, $tProperty02.Variant) 440 | $tVARIANT.vt = $VT_DISPATCH 441 | $tVARIANT.data = $pSelf 442 | $oIDispatch.arguments = IDispatch(); 443 | $oIDispatch.arguments.length=$tDISPPARAMS.cArgs 444 | Local $aArguments[$tDISPPARAMS.cArgs], $iArguments=$tDISPPARAMS.cArgs-1 445 | Local $_pProperty = DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AutoItObjectInternal_GetPtrOffset("Properties")),1) 446 | Local $_tProperty = DllStructCreate($tagProperty, $_pProperty) 447 | For $i=0 To $iArguments 448 | VariantClear($_tProperty.Variant) 449 | VariantCopy($_tProperty.Variant, $tDISPPARAMS.rgvargs+(($iArguments-$i)*DllStructGetSize($_tVARIANT))) 450 | $aArguments[$i]=$oIDispatch.val 451 | Next 452 | $oIDispatch.arguments.values=$aArguments 453 | $oIDispatch.arguments.__seal() 454 | $oIDispatch.__defineSetter("parent", PrivateProperty) 455 | VariantClear($_tProperty.Variant) 456 | VariantCopy($_tProperty.Variant, $tProperty.__getter) 457 | Local $fGetter = $oIDispatch.val 458 | VariantClear($_tProperty.Variant) 459 | VariantCopy($_tProperty.Variant, $tProperty.Variant) 460 | $oIDispatch.__seal() 461 | Local $mRet = Call($fGetter, $oIDispatch) 462 | Local $iError = @error, $iExtended = @extended 463 | VariantClear($tProperty.Variant) 464 | VariantCopy($tProperty.Variant, $_tProperty.Variant) 465 | $oIDispatch.ret = $mRet 466 | $_tProperty = DllStructCreate($tagProperty, $_tProperty.Next) 467 | VariantCopy($pVarResult, $_tProperty.Variant) 468 | $oIDispatch=0 469 | Return ($iError<>0)?$DISP_E_EXCEPTION:$S_OK 470 | Return $S_OK 471 | EndIf 472 | 473 | VariantCopy($pVarResult, $tVARIANT) 474 | Return $S_OK 475 | Else; ~ $DISPATCH_PROPERTYPUT 476 | $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams) 477 | If Not ($tProperty.__setter=0) Then 478 | Local $oIDispatch = IDispatch() 479 | $oIDispatch.val = 0 480 | $oIDispatch.ret = 0 481 | DllStructSetData(DllStructCreate("INT", $pSelf-4-4), 1, DllStructGetData(DllStructCreate("INT", $pSelf-4-4), 1)+1) 482 | $oIDispatch.parent = 0 483 | Local $tProperty02 = DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", ptr($oIDispatch) + __AutoItObjectInternal_GetPtrOffset("Properties")),1)) 484 | $tProperty02=DllStructCreate($tagProperty, $tProperty02.Next) 485 | $tProperty02=DllStructCreate($tagProperty, $tProperty02.Next) 486 | $tVARIANT = DllStructCreate($tagVARIANT, $tProperty02.Variant) 487 | $tVARIANT.vt = $VT_DISPATCH 488 | $tVARIANT.data = $pSelf 489 | Local $_pProperty = DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AutoItObjectInternal_GetPtrOffset("Properties")),1) 490 | Local $_tProperty = DllStructCreate($tagProperty, $_pProperty) 491 | Local $_tProperty2 = DllStructCreate($tagProperty, $_tProperty.Next) 492 | VariantClear($_tProperty.Variant) 493 | VariantCopy($_tProperty.Variant, $tProperty.__setter) 494 | VariantClear($_tProperty2.Variant) 495 | VariantCopy($_tProperty2.Variant, $tDISPPARAMS.rgvargs) 496 | Local $fSetter = $oIDispatch.val 497 | VariantClear($_tProperty.Variant) 498 | VariantCopy($_tProperty.Variant, $tProperty.Variant) 499 | $oIDispatch.__seal() 500 | Local $mRet = Call($fSetter, $oIDispatch) 501 | Local $iError = @error, $iExtended = @extended 502 | VariantClear($tProperty.Variant) 503 | VariantCopy($tProperty.Variant, $_tProperty.Variant) 504 | $oIDispatch.ret = $mRet 505 | $_tProperty = DllStructCreate($tagProperty, $_tProperty.Next) 506 | VariantCopy($pVarResult, $_tProperty.Variant) 507 | $oIDispatch=0 508 | Return ($iError<>0)?$DISP_E_EXCEPTION:$S_OK 509 | Return $S_OK 510 | EndIf 511 | 512 | Local $iLock = __AutoItObjectInternal_GetPtrValue($pSelf + __AutoItObjectInternal_GetPtrOffset("lock"), "BYTE") 513 | If BitAND($iLock, $__AutoItObjectInternal_LOCK_UPDATE)>0 Then Return $DISP_E_EXCEPTION 514 | 515 | $_tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs) 516 | VariantClear($tVARIANT) 517 | VariantCopy($tVARIANT, $_tVARIANT) 518 | EndIf 519 | Return $S_OK 520 | EndFunc -------------------------------------------------------------------------------- /AutoItObject_Internal.au3: -------------------------------------------------------------------------------- 1 | #include-once 2 | #include 3 | #include 4 | 5 | Global Const $__AOI_IID_IUnknown = "{00000000-0000-0000-C000-000000000046}" 6 | Global Const $__AOI_IID_IDispatch = "{00020400-0000-0000-C000-000000000046}" 7 | Global Const $__AOI_IID_IConnectionPointContainer = "{B196B284-BAB4-101A-B69C-00AA00341D07}" 8 | 9 | Global Const $__AOI_DISPATCH_METHOD = 1 10 | Global Const $__AOI_DISPATCH_PROPERTYGET = 2 11 | Global Const $__AOI_DISPATCH_PROPERTYPUT = 4 12 | Global Const $__AOI_DISPATCH_PROPERTYPUTREF = 8 13 | 14 | Global Const $__AOI_S_OK = 0x00000000 15 | Global Const $__AOI_E_NOTIMPL = 0x80004001 16 | Global Const $__AOI_E_NOINTERFACE = 0x80004002 17 | Global Const $__AOI_E_POINTER = 0x80004003 18 | Global Const $__AOI_E_ABORT = 0x80004004 19 | Global Const $__AOI_E_FAIL = 0x80004005 20 | Global Const $__AOI_E_ACCESSDENIED = 0x80070005 21 | Global Const $__AOI_E_HANDLE = 0x80070006 22 | Global Const $__AOI_E_OUTOFMEMORY = 0x8007000E 23 | Global Const $__AOI_E_INVALIDARG = 0x80070057 24 | Global Const $__AOI_E_UNEXPECTED = 0x8000FFFF 25 | 26 | Global Const $__AOI_DISP_E_UNKNOWNINTERFACE = 0x80020001 27 | Global Const $__AOI_DISP_E_MEMBERNOTFOUND = 0x80020003 28 | Global Const $__AOI_DISP_E_PARAMNOTFOUND = 0x80020004 29 | Global Const $__AOI_DISP_E_TYPEMISMATCH = 0x80020005 30 | Global Const $__AOI_DISP_E_UNKNOWNNAME = 0x80020006 31 | Global Const $__AOI_DISP_E_NONAMEDARGS = 0x80020007 32 | Global Const $__AOI_DISP_E_BADVARTYPE = 0x80020008 33 | Global Const $__AOI_DISP_E_EXCEPTION = 0x80020009 34 | Global Const $__AOI_DISP_E_OVERFLOW = 0x8002000A 35 | Global Const $__AOI_DISP_E_BADINDEX = 0x8002000B 36 | Global Const $__AOI_DISP_E_UNKNOWNLCID = 0x8002000C 37 | Global Const $__AOI_DISP_E_ARRAYISLOCKED = 0x8002000D 38 | Global Const $__AOI_DISP_E_BADPARAMCOUNT = 0x8002000E 39 | Global Const $__AOI_DISP_E_PARAMNOTOPTIONAL = 0x8002000F 40 | Global Const $__AOI_DISP_E_BADCALLEE = 0x80020010 41 | Global Const $__AOI_DISP_E_NOTACOLLECTION = 0x80020011 42 | 43 | Global Const $__AOI_tagVARIANT = "ushort vt;ushort r1;ushort r2;ushort r3;PTR data;PTR data2" 44 | Global Const $__AOI_cVARIANT = DllStructGetSize(DllStructCreate($__AOI_tagVARIANT)) 45 | Global Const $__AOI_tagDISPPARAMS = "ptr rgvargs;ptr rgdispidNamedArgs;dword cArgs;dword cNamedArgs;" 46 | 47 | Global Const $__AOI_LOCK_CREATE = 1 48 | Global Const $__AOI_LOCK_UPDATE = 2 49 | Global Const $__AOI_LOCK_DELETE = 4 50 | Global Const $__AOI_LOCK_CASE = 8 51 | 52 | Global Enum $__AOI_VT_EMPTY,$__AOI_VT_NULL,$__AOI_VT_I2,$__AOI_VT_I4,$__AOI_VT_R4,$__AOI_VT_R8,$__AOI_VT_CY,$__AOI_VT_DATE,$__AOI_VT_BSTR,$__AOI_VT_DISPATCH, _ 53 | $__AOI_VT_ERROR,$__AOI_VT_BOOL,$__AOI_VT_VARIANT,$__AOI_VT_UNKNOWN,$__AOI_VT_DECIMAL,$__AOI_VT_I1=16,$__AOI_VT_UI1,$__AOI_VT_UI2,$__AOI_VT_UI4,$__AOI_VT_I8, _ 54 | $__AOI_VT_UI8,$__AOI_VT_INT,$__AOI_VT_UINT,$__AOI_VT_VOID,$__AOI_VT_HRESULT,$__AOI_VT_PTR,$__AOI_VT_SAFEARRAY,$__AOI_VT_CARRAY,$__AOI_VT_USERDEFINED, _ 55 | $__AOI_VT_LPSTR,$__AOI_VT_LPWSTR,$__AOI_VT_RECORD=36,$__AOI_VT_FILETIME=64,$__AOI_VT_BLOB,$__AOI_VT_STREAM,$__AOI_VT_STORAGE,$__AOI_VT_STREAMED_OBJECT, _ 56 | $__AOI_VT_STORED_OBJECT,$__AOI_VT_BLOB_OBJECT,$__AOI_VT_CF,$__AOI_VT_CLSID,$__AOI_VT_BSTR_BLOB=0xfff,$__AOI_VT_VECTOR=0x1000, _ 57 | $__AOI_VT_ARRAY=0x2000,$__AOI_VT_BYREF=0x4000,$__AOI_VT_RESERVED=0x8000,$__AOI_VT_ILLEGAL=0xffff,$__AOI_VT_ILLEGALMASKED=0xfff, _ 58 | $__AOI_VT_TYPEMASK=0xfff 59 | 60 | Global Const $__AOI_tagObject = "int RefCount;int Size;ptr Object;ptr Methods[7];int_ptr Callbacks[7];ptr Properties;long iProperties;long cProperties;BYTE lock;PTR __destructor" 61 | Global Const $__AOI_tagProperty = "ptr Name;int cName;ptr Variant;ptr __getter;ptr __setter" 62 | Global Const $__AOI_cProperty = DllStructGetSize(DllStructCreate($__AOI_tagProperty)) 63 | 64 | Global Enum Step -1 $__AOI_ConstantProperty_assign = -2, $__AOI_ConstantProperty_isExtensible, $__AOI_ConstantProperty_case, $__AOI_ConstantProperty_freeze, $__AOI_ConstantProperty_isFrozen, $__AOI_ConstantProperty_isSealed, $__AOI_ConstantProperty_keys, $__AOI_ConstantProperty_preventExtensions, $__AOI_ConstantProperty_defineGetter, $__AOI_ConstantProperty_defineSetter, $__AOI_ConstantProperty_lookupGetter, $__AOI_ConstantProperty_lookupSetter, $__AOI_ConstantProperty_seal, $__AOI_ConstantProperty_destructor = -16, $__AOI_ConstantProperty_unset, $__AOI_ConstantProperty_get, $__AOI_ConstantProperty_set, $__AOI_ConstantProperty_exists 65 | 66 | Global Const $__AOI_Object_Element_RefCount = __AOI_GetPtrOffset("RefCount") 67 | Global Const $__AOI_Object_Element_Size = __AOI_GetPtrOffset("Size") 68 | Global Const $__AOI_Object_Element_Object = __AOI_GetPtrOffset("Object") 69 | Global Const $__AOI_Object_Element_Methods = __AOI_GetPtrOffset("Methods") 70 | Global Const $__AOI_Object_Element_Callbacks = __AOI_GetPtrOffset("Callbacks") 71 | Global Const $__AOI_Object_Element_Properties = __AOI_GetPtrOffset("Properties") 72 | Global Const $__AOI_Object_Element_iProperties = __AOI_GetPtrOffset("iProperties") 73 | Global Const $__AOI_Object_Element_cProperties = __AOI_GetPtrOffset("cProperties") 74 | Global Const $__AOI_Object_Element_lock = __AOI_GetPtrOffset("lock") 75 | Global Const $__AOI_Object_Element___destructor = __AOI_GetPtrOffset("__destructor") 76 | 77 | Func IDispatch($QueryInterface=__AOI_QueryInterface, $AddRef=__AOI_AddRef, $Release=__AOI_Release, $GetTypeInfoCount=__AOI_GetTypeInfoCount, $GetTypeInfo=__AOI_GetTypeInfo, $GetIDsOfNames=__AOI_GetIDsOfNames, $Invoke=__AOI_Invoke) 78 | Local $tObject = DllStructCreate($__AOI_tagObject) 79 | 80 | Local Static $hQueryInterface = DllCallbackRegister(__AOI_QueryInterface, "LONG", "ptr;ptr;ptr") 81 | Local Static $hAddRef = DllCallbackRegister(__AOI_AddRef, "dword", "PTR") 82 | Local Static $hRelease = DllCallbackRegister(__AOI_Release, "dword", "PTR") 83 | Local Static $hGetTypeInfoCount = DllCallbackRegister(__AOI_GetTypeInfoCount, "long", "ptr;ptr") 84 | Local Static $hGetTypeInfo = DllCallbackRegister(__AOI_GetTypeInfo, "long", "ptr;uint;int;ptr") 85 | Local Static $hGetIDsOfNames = DllCallbackRegister(__AOI_GetIDsOfNames, "long", "ptr;ptr;ptr;uint;int;ptr") 86 | Local Static $hInvoke = DllCallbackRegister(__AOI_Invoke, "long", "ptr;int;ptr;int;ushort;ptr;ptr;ptr;ptr") 87 | 88 | $QueryInterface = $QueryInterface = __AOI_QueryInterface ? $hQueryInterface : DllCallbackRegister($QueryInterface, "LONG", "ptr;ptr;ptr") 89 | DllStructSetData($tObject, "Methods", DllCallbackGetPtr($QueryInterface), 1) 90 | DllStructSetData($tObject, "Callbacks", $QueryInterface, 1) 91 | 92 | $AddRef = $AddRef = __AOI_AddRef ? $hAddRef : DllCallbackRegister($AddRef, "dword", "PTR") 93 | DllStructSetData($tObject, "Methods", DllCallbackGetPtr($AddRef), 2) 94 | DllStructSetData($tObject, "Callbacks", $AddRef, 2) 95 | 96 | $Release = $Release = __AOI_Release ? $hRelease : DllCallbackRegister($Release, "dword", "PTR") 97 | DllStructSetData($tObject, "Methods", DllCallbackGetPtr($Release), 3) 98 | DllStructSetData($tObject, "Callbacks", $Release, 3) 99 | 100 | $GetTypeInfoCount = $GetTypeInfoCount = __AOI_GetTypeInfoCount ? $hGetTypeInfoCount : DllCallbackRegister($GetTypeInfoCount, "long", "ptr;ptr") 101 | DllStructSetData($tObject, "Methods", DllCallbackGetPtr($GetTypeInfoCount), 4) 102 | DllStructSetData($tObject, "Callbacks", $GetTypeInfoCount, 4) 103 | 104 | $GetTypeInfo = $GetTypeInfo = __AOI_GetTypeInfo ? $hGetTypeInfo : DllCallbackRegister($GetTypeInfo, "long", "ptr;uint;int;ptr") 105 | DllStructSetData($tObject, "Methods", DllCallbackGetPtr($GetTypeInfo), 5) 106 | DllStructSetData($tObject, "Callbacks", $GetTypeInfo, 5) 107 | 108 | $GetIDsOfNames = $GetIDsOfNames = __AOI_GetIDsOfNames ? $hGetIDsOfNames : DllCallbackRegister($GetIDsOfNames, "long", "ptr;ptr;ptr;uint;int;ptr") 109 | DllStructSetData($tObject, "Methods", DllCallbackGetPtr($GetIDsOfNames), 6) 110 | DllStructSetData($tObject, "Callbacks", $GetIDsOfNames, 6) 111 | 112 | $Invoke = $Invoke = __AOI_Invoke ? $hInvoke : DllCallbackRegister($Invoke, "long", "ptr;int;ptr;int;ushort;ptr;ptr;ptr;ptr") 113 | DllStructSetData($tObject, "Methods", DllCallbackGetPtr($Invoke), 7) 114 | DllStructSetData($tObject, "Callbacks", $Invoke, 7) 115 | 116 | DllStructSetData($tObject, "RefCount", 1) ; initial ref count is 1 117 | DllStructSetData($tObject, "Size", 7) ; number of interface methods 118 | 119 | Local $pData = __AOI_MemCloneGlob($tObject) 120 | 121 | Local $tObject = DllStructCreate($__AOI_tagObject, $pData) 122 | 123 | DllStructSetData($tObject, "Object", DllStructGetPtr($tObject, "Methods")) ; Interface method pointers 124 | Return ObjCreateInterface(DllStructGetPtr($tObject, "Object"), $__AOI_IID_IDispatch, Default, True) ; pointer that's wrapped into object 125 | EndFunc 126 | 127 | #cs 128 | # @internal 129 | #ce 130 | Func __AOI_QueryInterface($pSelf, $pRIID, $pObj) 131 | If $pObj=0 Then Return $__AOI_E_POINTER 132 | Local $sGUID=DllCall("ole32.dll", "int", "StringFromGUID2", "PTR", $pRIID, "wstr", "", "int", 40)[2] 133 | If (Not ($sGUID=$__AOI_IID_IDispatch)) And (Not ($sGUID=$__AOI_IID_IUnknown)) Then Return $__AOI_E_NOINTERFACE 134 | Local $tStruct = DllStructCreate("ptr", $pObj) 135 | DllStructSetData($tStruct, 1, $pSelf) 136 | __AOI_AddRef($pSelf) 137 | Return $__AOI_S_OK 138 | EndFunc 139 | 140 | #cs 141 | # @internal 142 | #ce 143 | Func __AOI_AddRef($pSelf) 144 | Local $tStruct = DllStructCreate("int Ref", $pSelf + $__AOI_Object_Element_RefCount) 145 | $tStruct.Ref += 1 146 | Return $tStruct.Ref 147 | EndFunc 148 | 149 | #cs 150 | # @internal 151 | #ce 152 | Func __AOI_Release($pSelf) 153 | Local $i 154 | Local $tObject = DllStructCreate($__AOI_tagObject, $pSelf + $__AOI_Object_Element_RefCount) 155 | $tObject.RefCount -= 1 156 | If $tObject.RefCount = 0 Then; initiate garbage collection 157 | Local $pDescructor = $tObject.__destructor 158 | If Not ($pDescructor=0) Then 159 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $pDescructor) 160 | $tObject.__destructor = 0 161 | Local $IDispatch = IDispatch() 162 | $IDispatch.a=0 163 | $tIDispatch = DllStructCreate($__AOI_tagObject, Ptr($IDispatch) + $__AOI_Object_Element_RefCount) 164 | Local $tProperty = __AOI_PropertyGetFromId($tIDispatch.Properties, 1) 165 | Local $pVARIANT = $tProperty.Variant 166 | __AOI_VariantReplace($pVARIANT, $tVARIANT) 167 | Local $f__destructor = $IDispatch.a ;FIXME: make a helper method for convertion between au3 varaible and variant (with optional copy variant flag) 168 | __AOI_VariantClear($pVARIANT) 169 | $tObject.RefCount += 1 170 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $pVARIANT) 171 | $tVARIANT.vt = $__AOI_VT_DISPATCH 172 | $tVARIANT.data = $pSelf 173 | Call($f__destructor, $IDispatch.a) 174 | __AOI_VariantClear($pVARIANT) 175 | $IDispatch=0 176 | EndIf 177 | $tObject.__lock = 1;lock 178 | Local $pProperty = $tObject.Properties;get first property 179 | If Not ($pProperty = 0) Then 180 | $tObject.Properties = 0;detatch properties from object 181 | Local $tProperty 182 | For $i=0 To $tObject.iProperties;releases all properties 183 | $tProperty = __AOI_PropertyGetFromId($pProperty, $i) 184 | If Not ($tProperty.__getter=0) Then 185 | __AOI_VariantClear($tProperty.__getter) 186 | _MemGlobalFree(__AOI_GlobalHandle($tProperty.__getter)) 187 | EndIf 188 | If Not ($tProperty.__setter=0) Then 189 | __AOI_VariantClear($tProperty.__setter) 190 | _MemGlobalFree(__AOI_GlobalHandle($tProperty.__setter)) 191 | EndIf 192 | If Not ($tProperty.Variant = 0) Then 193 | __AOI_VariantClear($tProperty.Variant) 194 | _MemGlobalFree(__AOI_GlobalHandle($tProperty.Variant)) 195 | EndIf 196 | _WinAPI_FreeMemory($tProperty.Name) 197 | Next 198 | $tProperty=0 199 | _MemGlobalFree(__AOI_GlobalHandle($pProperty)) 200 | EndIf 201 | _MemGlobalFree(__AOI_GlobalHandle(DllStructGetPtr($tObject))) 202 | Return 0 203 | EndIf 204 | Return $tObject.RefCount 205 | EndFunc 206 | 207 | #cs 208 | # @internal 209 | #ce 210 | Func __AOI_GetIDsOfNames($pSelf, $riid, $rgszNames, $cNames, $lcid, $rgDispId) 211 | Local $tIds = DllStructCreate("long i", $rgDispId); 2,147,483,647 properties available to define, per object. And 2,147,483,647 private properties to set in the negative space, per object. 212 | Local $tProperty = 0 213 | 214 | Local $pStr = DllStructGetData(DllStructCreate("ptr", $rgszNames), 1) 215 | Local $s_rgszName = DllStructGetData(DllStructCreate("WCHAR[255]", $pStr), 1) 216 | 217 | $tIds.i = -1 218 | if StringLeft($s_rgszName, 2) = "__" Then 219 | __AOI_ConstantProperty_Lookup($s_rgszName, $tIds) 220 | If DllStructGetData($tIds, 1) <> -1 Then Return $__AOI_S_OK 221 | EndIf 222 | 223 | Local $tObject = DllStructCreate($__AOI_tagObject, $pSelf + $__AOI_Object_Element_RefCount) 224 | Local $iLock = $tObject.lock 225 | Local $bCase = Not (BitAND($iLock, $__AOI_LOCK_CASE)>0) 226 | Local $pProperty = __AOI_PropertyGetFromName($tObject, $pStr, $bCase) 227 | Local $iID = @error<>0?-1:@extended 228 | 229 | If ($iID=-1) And BitAND($iLock, $__AOI_LOCK_CREATE)=0 Then 230 | __AOI_Properties_Add($tObject, $pStr, 0) 231 | $iID = @extended 232 | EndIf 233 | 234 | If $iID=-1 Then Return $__AOI_DISP_E_UNKNOWNNAME 235 | DllStructSetData($tIds, 1, $iID) 236 | Return $__AOI_S_OK 237 | EndFunc 238 | 239 | #cs 240 | # @internal 241 | #ce 242 | Func __AOI_ConstantProperty_Lookup($s_rgszName, $tIds) 243 | Switch $s_rgszName 244 | Case "__assign" 245 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_assign) 246 | Case "__isExtensible" 247 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_isExtensible) 248 | Case "__case" 249 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_case) 250 | Case "__freeze" 251 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_freeze) 252 | Case "__isFrozen" 253 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_isFrozen) 254 | Case "__isSealed" 255 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_isSealed) 256 | Case "__keys" 257 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_keys) 258 | Case "__preventExtensions" 259 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_preventExtensions) 260 | Case "__defineGetter" 261 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_defineGetter) 262 | Case "__defineSetter" 263 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_defineSetter) 264 | Case "__lookupGetter" 265 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_lookupGetter) 266 | Case "__lookupSetter" 267 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_lookupSetter) 268 | Case "__seal" 269 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_seal) 270 | Case "__destructor" 271 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_destructor) 272 | Case "__unset" 273 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_unset) 274 | Case "__get" 275 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_get) 276 | Case "__set" 277 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_set) 278 | Case "__exists" 279 | DllStructSetData($tIds, 1, $__AOI_ConstantProperty_exists) 280 | EndSwitch 281 | EndFunc 282 | 283 | #cs 284 | # @internal 285 | #ce 286 | Func __AOI_GetTypeInfo($pSelf, $iTInfo, $lcid, $ppTInfo) 287 | If $iTInfo<>0 Then Return $__AOI_DISP_E_BADINDEX 288 | If $ppTInfo=0 Then Return $__AOI_E_INVALIDARG 289 | Return $__AOI_S_OK 290 | EndFunc 291 | 292 | #cs 293 | # @internal 294 | #ce 295 | Func __AOI_GetTypeInfoCount($pSelf, $pctinfo) 296 | DllStructSetData(DllStructCreate("UINT",$pctinfo),1, 0) 297 | Return $__AOI_S_OK 298 | EndFunc 299 | 300 | #cs 301 | # @internal 302 | #ce 303 | Func __AOI_Invoke($pSelf, $dispIdMember, $riid, $lcid, $wFlags, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr) 304 | Local $tObject = DllStructCreate($__AOI_tagObject, $pSelf + $__AOI_Object_Element_RefCount) 305 | If $dispIdMember=-1 Then Return $__AOI_DISP_E_MEMBERNOTFOUND 306 | Local $_tVARIANT, $tDISPPARAMS 307 | 308 | Local $pProperty = $tObject.Properties 309 | 310 | If $dispIdMember<-1 Then 311 | Switch $dispIdMember 312 | Case $__AOI_ConstantProperty_isExtensible 313 | Return __AOI_Invoke_isExtensible($tObject, $pVarResult) 314 | Case $__AOI_ConstantProperty_case 315 | Return __AOI_Invoke_case($tObject, $pDispParams, $pVarResult, $wFlags) 316 | Case $__AOI_ConstantProperty_lookupSetter 317 | Return __AOI_Invoke_lookupSetter($tObject, $riid, $lcid, $pDispParams, $pVarResult) 318 | Case $__AOI_ConstantProperty_lookupGetter 319 | Return __AOI_Invoke_lookupGetter($tObject, $riid, $lcid, $pDispParams, $pVarResult) 320 | Case $__AOI_ConstantProperty_assign 321 | Return __AOI_Invoke_assign($tObject, $pDispParams) 322 | Case $__AOI_ConstantProperty_isSealed 323 | Return __AOI_Invoke_isSealed($tObject, $pVarResult) 324 | Case $__AOI_ConstantProperty_isFrozen 325 | Return __AOI_Invoke_isFrozen($tObject, $pVarResult) 326 | Case $__AOI_ConstantProperty_get 327 | Return __AOI_Invoke_get($pSelf, $riid, $lcid, $pDispParams, $puArgErr, $pExcepInfo, $pVarResult) 328 | Case $__AOI_ConstantProperty_set 329 | Return __AOI_Invoke_set($pSelf, $riid, $lcid, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr) 330 | Case $__AOI_ConstantProperty_exists 331 | Return __AOI_Invoke_exists($tObject, $pDispParams, $pVarResult) 332 | Case $__AOI_ConstantProperty_destructor 333 | Return __AOI_Invoke_destructor($tObject, $pDispParams) 334 | Case $__AOI_ConstantProperty_freeze 335 | Return __AOI_Invoke_freeze($tObject, $pDispParams) 336 | Case $__AOI_ConstantProperty_seal 337 | Return __AOI_Invoke_seal($tObject, $pDispParams) 338 | Case $__AOI_ConstantProperty_preventExtensions 339 | Return __AOI_Invoke_preventExtensions($tObject, $pDispParams) 340 | Case $__AOI_ConstantProperty_unset 341 | Return __AOI_Invoke_unset($tObject, $pDispParams, $pProperty) 342 | Case $__AOI_ConstantProperty_keys 343 | Return __AOI_Invoke_keys($tObject, $pVarResult) 344 | Case $__AOI_ConstantProperty_defineGetter 345 | Return __AOI_Invoke_defineGetter($tObject, $pDispParams, $lcid) 346 | Case $__AOI_ConstantProperty_defineSetter 347 | Return __AOI_Invoke_defineSetter($tObject, $pDispParams, $lcid) 348 | EndSwitch 349 | Return $__AOI_DISP_E_EXCEPTION 350 | EndIf 351 | 352 | Local $tProperty = __AOI_PropertyGetFromId($pProperty, $dispIdMember) 353 | 354 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tProperty.Variant) 355 | 356 | If (Not(BitAND($wFlags, $__AOI_DISPATCH_PROPERTYGET)=0)) Then 357 | If Not($tProperty.__getter = 0) Then 358 | $_tVARIANT = DllStructCreate($__AOI_tagVARIANT, $pVarResult) 359 | $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 360 | Local $oIDispatch = IDispatch() 361 | $oIDispatch.val = 0 362 | $oIDispatch.ret = 0 363 | DllStructSetData(DllStructCreate("INT", $pSelf-4-4), 1, DllStructGetData(DllStructCreate("INT", $pSelf-4-4), 1)+1) 364 | $oIDispatch.parent = 0 365 | Local $_tObject = DllStructCreate($__AOI_tagObject, Ptr($oIDispatch) + $__AOI_Object_Element_RefCount) 366 | Local $tProperty02 = __AOI_PropertyGetFromId($_tObject.Properties, 3) 367 | $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tProperty02.Variant) 368 | $tVARIANT.vt = $__AOI_VT_DISPATCH 369 | $tVARIANT.data = $pSelf 370 | $oIDispatch.arguments = IDispatch(); 371 | $oIDispatch.arguments.length=$tDISPPARAMS.cArgs 372 | Local $aArguments[$tDISPPARAMS.cArgs], $iArguments=$tDISPPARAMS.cArgs-1 373 | Local $_tProperty = __AOI_PropertyGetFromId($_tObject.Properties, 1) 374 | For $i=0 To $iArguments 375 | __AOI_VariantReplace($_tProperty.Variant, $tDISPPARAMS.rgvargs+(($iArguments-$i)*$__AOI_cVARIANT)) 376 | $aArguments[$i]=$oIDispatch.val 377 | Next 378 | $oIDispatch.arguments.values=$aArguments 379 | $oIDispatch.arguments.__seal() 380 | $oIDispatch.__defineSetter("parent", _AOI_PrivateProperty) 381 | __AOI_VariantReplace($_tProperty.Variant, $tProperty.__getter) 382 | Local $fGetter = $oIDispatch.val 383 | __AOI_VariantReplace($_tProperty.Variant, $tProperty.Variant) 384 | $oIDispatch.__seal() 385 | Local $mRet = Call($fGetter, $oIDispatch) 386 | Local $iError = @error, $iExtended = @extended 387 | __AOI_VariantReplace($tProperty.Variant, $_tProperty.Variant) 388 | $oIDispatch.ret = $mRet 389 | $_tProperty = __AOI_PropertyGetFromId($_tObject.Properties, 2) 390 | __AOI_VariantReplace($pVarResult, $_tProperty.Variant) 391 | $oIDispatch=0 392 | Return ($iError<>0)?$__AOI_DISP_E_EXCEPTION:$__AOI_S_OK 393 | EndIf 394 | 395 | __AOI_VariantCopy($pVarResult, $tVARIANT) 396 | Return $__AOI_S_OK 397 | Else; ~ $DISPATCH_PROPERTYPUT 398 | $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 399 | If Not ($tProperty.__setter=0) Then 400 | Local $oIDispatch = IDispatch() 401 | $oIDispatch.val = 0 402 | $oIDispatch.ret = 0 403 | DllStructSetData(DllStructCreate("INT", $pSelf-4-4), 1, DllStructGetData(DllStructCreate("INT", $pSelf-4-4), 1)+1) 404 | $oIDispatch.parent = 0 405 | $_tObject = DllStructCreate($__AOI_tagObject, Ptr($oIDispatch) + $__AOI_Object_Element_RefCount) 406 | Local $tProperty02 = __AOI_PropertyGetFromId($_tObject.Properties, 3) 407 | $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tProperty02.Variant) 408 | $tVARIANT.vt = $__AOI_VT_DISPATCH 409 | $tVARIANT.data = $pSelf 410 | Local $_tProperty = __AOI_PropertyGetFromId($_tObject.Properties, 1) 411 | Local $_tProperty2 = __AOI_PropertyGetFromId($_tObject.Properties, 2) 412 | __AOI_VariantReplace($_tProperty.Variant, $tProperty.__setter) 413 | __AOI_VariantReplace($_tProperty2.Variant, $tDISPPARAMS.rgvargs) 414 | Local $fSetter = $oIDispatch.val 415 | __AOI_VariantReplace($_tProperty.Variant, $tProperty.Variant) 416 | $oIDispatch.__seal() 417 | Local $mRet = Call($fSetter, $oIDispatch) 418 | Local $iError = @error, $iExtended = @extended 419 | __AOI_VariantReplace($tProperty.Variant, $_tProperty.Variant) 420 | $oIDispatch.ret = $mRet 421 | __AOI_VariantReplace($pVarResult, $_tProperty2.Variant) 422 | $oIDispatch=0 423 | Return ($iError<>0)?$__AOI_DISP_E_EXCEPTION:$__AOI_S_OK 424 | EndIf 425 | 426 | Local $iLock = $tObject.lock 427 | If BitAND($iLock, $__AOI_LOCK_UPDATE)>0 Then Return $__AOI_DISP_E_EXCEPTION 428 | 429 | $_tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs) 430 | __AOI_VariantReplace($tVARIANT, $_tVARIANT) 431 | EndIf 432 | Return $__AOI_S_OK 433 | EndFunc 434 | 435 | Func __AOI_Invoke_isExtensible($tObject, $pVarResult) 436 | Local $iLock = $tObject.lock 437 | Local $iExtensible = $__AOI_LOCK_CREATE 438 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $pVarResult) 439 | $tVARIANT.vt = $__AOI_VT_BOOL 440 | $tVARIANT.data = (BitAND($iLock, $iExtensible) = $iExtensible)?1:0 441 | Return $__AOI_S_OK 442 | EndFunc 443 | 444 | Func __AOI_Invoke_case($tObject, $pDispParams, $pVarResult, $wFlags) 445 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 446 | If (Not(BitAND($wFlags, $__AOI_DISPATCH_PROPERTYGET)=0)) Then 447 | If $tDISPPARAMS.cArgs<>0 Then Return $__AOI_DISP_E_BADPARAMCOUNT 448 | Local $tVARIANT=DllStructCreate($__AOI_tagVARIANT, $pVarResult) 449 | $tVARIANT.vt = $__AOI_VT_BOOL 450 | Local $iLock = $tObject.lock 451 | $tVARIANT.data = (BitAND($iLock, $__AOI_LOCK_CASE)>0)?0:1 452 | Else; $DISPATCH_PROPERTYPUT 453 | If $tDISPPARAMS.cArgs<>1 Then Return $__AOI_DISP_E_BADPARAMCOUNT 454 | Local $tVARIANT=DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs) 455 | If $tVARIANT.vt<>$__AOI_VT_BOOL Then Return $__AOI_DISP_E_BADVARTYPE 456 | Local $iLock = $tObject.lock 457 | If BitAND($iLock, $__AOI_LOCK_UPDATE)>0 Then Return $__AOI_DISP_E_EXCEPTION 458 | Local $b = $tVARIANT.data 459 | $tObject.lock = (Not $b) ? BitOR($iLock, $__AOI_LOCK_CASE) : BitAND($iLock, BitNOT(BitShift(1 , 0-(Log($__AOI_LOCK_CASE)/log(2))))) 460 | EndIf 461 | Return $__AOI_S_OK 462 | EndFunc 463 | 464 | Func __AOI_Invoke_lookupSetter($tObject, $riid, $lcid, $pDispParams, $pVarResult) 465 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 466 | If $tDISPPARAMS.cArgs<>1 Then Return $__AOI_DISP_E_BADPARAMCOUNT 467 | 468 | Local $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 469 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 470 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs) 471 | $t.str_ptr = DllStructGetData(DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs), "data") 472 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 473 | If Not __AOI_GetIDsOfNames(DllStructGetPtr($tObject, "Object"), $riid, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $__AOI_S_OK Then Return $__AOI_DISP_E_EXCEPTION 474 | 475 | Local $pProperty = $tObject.Properties 476 | Local $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id) 477 | If Not $tProperty.__setter=0 Then 478 | __AOI_VariantReplace($pVarResult, $tProperty.__setter) 479 | EndIf 480 | Return $__AOI_S_OK 481 | EndFunc 482 | 483 | Func __AOI_Invoke_lookupGetter($tObject, $riid, $lcid, $pDispParams, $pVarResult) 484 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 485 | If $tDISPPARAMS.cArgs<>1 Then Return $__AOI_DISP_E_BADPARAMCOUNT 486 | 487 | Local $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 488 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 489 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs) 490 | $t.str_ptr = DllStructGetData(DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs), "data") 491 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 492 | If Not (__AOI_GetIDsOfNames(DllStructGetPtr($tObject, "Object"), $riid, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $__AOI_S_OK) Then Return $__AOI_DISP_E_EXCEPTION 493 | 494 | Local $pProperty = $tObject.Properties 495 | Local $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id) 496 | If Not $tProperty.__getter=0 Then 497 | __AOI_VariantReplace($pVarResult, $tProperty.__getter) 498 | EndIf 499 | Return $__AOI_S_OK 500 | EndFunc 501 | 502 | Func __AOI_Invoke_assign($tObject, $pDispParams) 503 | Local $iLock = $tObject.lock 504 | If BitAND($iLock, $__AOI_LOCK_CREATE)>0 Then Return $__AOI_DISP_E_EXCEPTION 505 | 506 | 507 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 508 | If $tDISPPARAMS.cArgs=0 Then Return $__AOI_DISP_E_BADPARAMCOUNT 509 | 510 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT) 511 | Local $iVARIANT = $__AOI_cVARIANT 512 | Local $pExternalProperty, $tExternalProperty 513 | Local $pProperty, $tProperty, $_tProperty 514 | Local $iID, $iIndex, $pData 515 | Local $_tObject 516 | For $i=$tDISPPARAMS.cArgs-1 To 0 Step -1 517 | $tVARIANT=DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs+$iVARIANT*$i) 518 | If Not (DllStructGetData($tVARIANT, "vt")=$__AOI_VT_DISPATCH) Then Return $__AOI_DISP_E_BADVARTYPE 519 | $_tObject = DllStructCreate($__AOI_tagObject, $tVARIANT.data + $__AOI_Object_Element_RefCount) 520 | For $j = 1 To $_tObject.iProperties 521 | $_tProperty = __AOI_PropertyGetFromId($_tObject.Properties, $j) 522 | $pProperty = __AOI_PropertyGetFromName($tObject, $_tProperty.Name, False);TODO: the case sensitive option should reflect the main object case sensitive setting. 523 | 524 | $iID = @error<>0?-1:@extended 525 | 526 | If ($iID=-1) Then 527 | __AOI_Properties_Add($tObject, $_tProperty.Name, $_tProperty.Variant) 528 | Else 529 | $tProperty = DllStructCreate($__AOI_tagProperty, $pProperty) 530 | __AOI_VariantReplace($tProperty.Variant, $_tProperty.Variant) 531 | EndIf 532 | Next 533 | Next 534 | Return $__AOI_S_OK 535 | EndFunc 536 | 537 | Func __AOI_Invoke_isSealed($tObject, $pVarResult) 538 | Local $iLock = $tObject.lock 539 | Local $iSeal = $__AOI_LOCK_CREATE + $__AOI_LOCK_DELETE 540 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $pVarResult) 541 | $tVARIANT.vt = $__AOI_VT_BOOL 542 | $tVARIANT.data = (BitAND($iLock, $iSeal) = $iSeal)?1:0 543 | Return $__AOI_S_OK 544 | EndFunc 545 | 546 | Func __AOI_Invoke_isFrozen($tObject, $pVarResult) 547 | Local $iLock = $tObject.lock 548 | Local $iFreeze = $__AOI_LOCK_CREATE + $__AOI_LOCK_UPDATE + $__AOI_LOCK_DELETE 549 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $pVarResult) 550 | $tVARIANT.vt = $__AOI_VT_BOOL 551 | $tVARIANT.data = (BitAND($iLock, $iFreeze) = $iFreeze)?1:0 552 | Return $__AOI_S_OK 553 | EndFunc 554 | 555 | Func __AOI_Invoke_get($pSelf, $riid, $lcid, $pDispParams, $puArgErr, $pExcepInfo, $pVarResult) 556 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 557 | If $tDISPPARAMS.cArgs<>1 Then Return $__AOI_DISP_E_BADPARAMCOUNT 558 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs) 559 | If $tVARIANT.vt<>$__AOI_VT_BSTR Then Return $__AOI_DISP_E_BADVARTYPE 560 | Local $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 561 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 562 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs) 563 | $t.str_ptr = DllStructGetData($tVARIANT, "data") 564 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 565 | If Not (__AOI_GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $__AOI_S_OK) Then Return $__AOI_DISP_E_EXCEPTION 566 | Return __AOI_Invoke($pSelf, $t.id, $riid, $lcid, $__AOI_DISPATCH_PROPERTYGET, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr) 567 | EndFunc 568 | 569 | Func __AOI_Invoke_set($pSelf, $riid, $lcid, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr) 570 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 571 | If $tDISPPARAMS.cArgs<>2 Then Return $__AOI_DISP_E_BADPARAMCOUNT 572 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs+$__AOI_cVARIANT) 573 | If $tVARIANT.vt<>$__AOI_VT_BSTR Then Return $__AOI_DISP_E_BADVARTYPE 574 | Local $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 575 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 576 | $t.str_ptr = DllStructGetData($tVARIANT, "data") 577 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 578 | If Not (__AOI_GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $__AOI_S_OK) Then Return $__AOI_DISP_E_EXCEPTION 579 | $tDISPPARAMS.cArgs=1 580 | Return __AOI_Invoke($pSelf, $t.id, $riid, $lcid, $__AOI_DISPATCH_PROPERTYPUT, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr) 581 | EndFunc 582 | 583 | Func __AOI_Invoke_exists($tObject, $pDispParams, $pVarResult) 584 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 585 | If $tDISPPARAMS.cArgs<>1 Then Return $__AOI_DISP_E_BADPARAMCOUNT 586 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs) 587 | If $tVARIANT.vt<>$__AOI_VT_BSTR Then Return $__AOI_DISP_E_BADVARTYPE 588 | Local $iLock = $tObject.lock 589 | Local $bCase = Not (BitAND($iLock, $__AOI_LOCK_CASE)>0) 590 | Local $pProperty = __AOI_PropertyGetFromName($tObject, $tVARIANT.data, $bCase) 591 | Local $error = @error 592 | $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $pVarResult) 593 | $tVARIANT.vt = $__AOI_VT_BOOL 594 | $tVARIANT.data = $error<>0?0:1 595 | Return $__AOI_S_OK 596 | EndFunc 597 | 598 | Func __AOI_Invoke_destructor($tObject, $pDispParams) 599 | Local $iLock = $tObject.lock 600 | If BitAND($iLock, $__AOI_LOCK_CREATE)>0 Then Return $__AOI_DISP_E_EXCEPTION 601 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 602 | If $tDISPPARAMS.cArgs<>1 Then Return $__AOI_DISP_E_BADPARAMCOUNT 603 | If (Not (DllStructGetData(DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs),"vt")=$__AOI_VT_RECORD)) And (Not (DllStructGetData(DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs),"vt")=$__AOI_VT_BSTR)) Then Return $__AOI_DISP_E_BADVARTYPE 604 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT) 605 | Local $pVARIANT = __AOI_MemCloneGlob($tVARIANT) 606 | $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $pVARIANT) 607 | __AOI_VariantInit($pVARIANT) 608 | __AOI_VariantCopy($pVARIANT, $tDISPPARAMS.rgvargs) 609 | $tObject.__destructor = $pVARIANT 610 | Return $__AOI_S_OK 611 | EndFunc 612 | 613 | Func __AOI_Invoke_freeze($tObject, $pDispParams) 614 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 615 | If $tDISPPARAMS.cArgs<>0 Then Return $__AOI_DISP_E_BADPARAMCOUNT 616 | $tObject.lock = BitOR($tObject.lock, $__AOI_LOCK_CREATE + $__AOI_LOCK_DELETE + $__AOI_LOCK_UPDATE) 617 | Return $__AOI_S_OK 618 | EndFunc 619 | 620 | Func __AOI_Invoke_seal($tObject, $pDispParams) 621 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 622 | If $tDISPPARAMS.cArgs<>0 Then Return $__AOI_DISP_E_BADPARAMCOUNT 623 | $tObject.lock = BitOR($tObject.lock, $__AOI_LOCK_CREATE + $__AOI_LOCK_DELETE) 624 | Return $__AOI_S_OK 625 | EndFunc 626 | 627 | Func __AOI_Invoke_preventExtensions($tObject, $pDispParams) 628 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 629 | If $tDISPPARAMS.cArgs<>0 Then Return $__AOI_DISP_E_BADPARAMCOUNT 630 | $tObject.lock = BitOR($tObject.lock, $__AOI_LOCK_CREATE) 631 | Return $__AOI_S_OK 632 | EndFunc 633 | 634 | Func __AOI_Invoke_unset($tObject, $pDispParams, $pProperty) 635 | Local $iLock = $tObject.lock 636 | If BitAND($iLock, $__AOI_LOCK_DELETE)>0 Then Return $__AOI_DISP_E_EXCEPTION 637 | 638 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 639 | If $tDISPPARAMS.cArgs<>1 Then Return $__AOI_DISP_E_BADPARAMCOUNT 640 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs) 641 | If Not($__AOI_VT_BSTR=$tVARIANT.vt) Then Return $__AOI_DISP_E_BADVARTYPE 642 | Local $sProperty = _WinAPI_GetString($tVARIANT.data);the string to search for 643 | Local $tProperty=0,$tProperty_Prev 644 | Local $bCase = Not (BitAND($iLock, $__AOI_LOCK_CASE)>0) 645 | __AOI_PropertyGetFromName($tObject, $tVARIANT.data, $bCase) 646 | If @error <> 0 Then Return $__AOI_DISP_E_MEMBERNOTFOUND 647 | __AOI_Properties_Remove($tObject, @extended) 648 | Return $__AOI_S_OK 649 | EndFunc 650 | 651 | Func __AOI_Invoke_keys($tObject, $pVarResult) 652 | Local $aKeys[$tObject.iProperties] 653 | Local $pProperties = $tObject.Properties 654 | Local $tProperty 655 | For $i=1 To $tObject.iProperties 656 | $tProperty = __AOI_PropertyGetFromId($pProperties, $i) 657 | $aKeys[$i-1] = _WinAPI_GetString($tProperty.Name) 658 | Next 659 | 660 | Local $oIDispatch = IDispatch() 661 | Local $_tObject = DllStructCreate($__AOI_tagObject, Ptr($oIDispatch)+$__AOI_Object_Element_RefCount) 662 | $oIDispatch.a=$aKeys 663 | Local $_tProperty = __AOI_PropertyGetFromId($_tObject.Properties, 1) 664 | __AOI_VariantReplace($pVarResult, $_tProperty.Variant) 665 | $oIDispatch=0 666 | Return $__AOI_S_OK 667 | EndFunc 668 | 669 | Func __AOI_Invoke_defineGetter($tObject, $pDispParams, $lcid) 670 | Local $iLock = $tObject.lock 671 | If BitAND($iLock, $__AOI_LOCK_CREATE)>0 Then Return $__AOI_DISP_E_EXCEPTION 672 | 673 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 674 | If $tDISPPARAMS.cArgs<>2 Then Return $__AOI_DISP_E_BADPARAMCOUNT 675 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs) 676 | If Not (($tVARIANT.vt=$__AOI_VT_RECORD) Or ($tVARIANT.vt=$__AOI_VT_BSTR)) Then Return $__AOI_DISP_E_BADVARTYPE 677 | Local $tVARIANT2 = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs+$__AOI_cVARIANT) 678 | If Not ($tVARIANT2.vt=$__AOI_VT_BSTR) Then Return $__AOI_DISP_E_BADVARTYPE 679 | 680 | $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 681 | Local $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 682 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 683 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs+$__AOI_cVARIANT) 684 | $t.str_ptr = DllStructGetData(DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs+$__AOI_cVARIANT), "data") 685 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 686 | __AOI_GetIDsOfNames(DllStructGetPtr($tObject, "Object"), 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) 687 | 688 | Local $pProperty = $tObject.Properties 689 | Local $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id) 690 | 691 | If ($tProperty.__getter=0) Then 692 | Local $tVARIANT_Getter = DllStructCreate($__AOI_tagVARIANT) 693 | Local $pVARIANT_Getter = __AOI_MemCloneGlob($tVARIANT_Getter) 694 | __AOI_VariantInit($pVARIANT_Getter) 695 | Else 696 | Local $pVARIANT_Getter = $tProperty.__getter 697 | __AOI_VariantClear($pVARIANT_Getter) 698 | EndIf 699 | $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs) 700 | __AOI_VariantCopy($pVARIANT_Getter, $tVARIANT) 701 | $tProperty.__getter = $pVARIANT_Getter 702 | Return $__AOI_S_OK 703 | EndFunc 704 | 705 | Func __AOI_Invoke_defineSetter($tObject, $pDispParams, $lcid) 706 | Local $iLock = $tObject.lock 707 | If BitAND($iLock, $__AOI_LOCK_CREATE)>0 Then Return $__AOI_DISP_E_EXCEPTION 708 | 709 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 710 | If $tDISPPARAMS.cArgs<>2 Then Return $__AOI_DISP_E_BADPARAMCOUNT 711 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs) 712 | If Not (($tVARIANT.vt=$__AOI_VT_RECORD) Or ($tVARIANT.vt=$__AOI_VT_BSTR)) Then Return $__AOI_DISP_E_BADVARTYPE 713 | Local $tVARIANT2 = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs+$__AOI_cVARIANT) 714 | If Not ($tVARIANT2.vt=$__AOI_VT_BSTR) Then Return $__AOI_DISP_E_BADVARTYPE 715 | 716 | Local $tDISPPARAMS = DllStructCreate($__AOI_tagDISPPARAMS, $pDispParams) 717 | Local $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr") 718 | DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2)) 719 | DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs+$__AOI_cVARIANT) 720 | $t.str_ptr = DllStructGetData(DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs+$__AOI_cVARIANT), "data") 721 | $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr") 722 | __AOI_GetIDsOfNames(DllStructGetPtr($tObject, "Object"), 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) 723 | 724 | Local $pProperty = $tObject.Properties 725 | 726 | $tVARIANT = DllStructCreate($__AOI_tagVARIANT, $tDISPPARAMS.rgvargs) 727 | Local $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id) 728 | If ($tProperty.__setter=0) Then 729 | Local $tVARIANT_Setter = DllStructCreate($__AOI_tagVARIANT) 730 | Local $pVARIANT_Setter = __AOI_MemCloneGlob($tVARIANT_Setter) 731 | __AOI_VariantInit($pVARIANT_Setter) 732 | Else 733 | Local $pVARIANT_Setter = $tProperty.__setter 734 | __AOI_VariantClear($pVARIANT_Setter) 735 | EndIf 736 | __AOI_VariantCopy($pVARIANT_Setter, $tVARIANT) 737 | $tProperty.__setter = $pVARIANT_Setter 738 | Return $__AOI_S_OK 739 | EndFunc 740 | 741 | Func __AOI_MemCloneGlob($tObject);clones DllStruct to Global memory and return pointer to new allocated memory 742 | Local $iSize = DllStructGetSize($tObject) 743 | Local $hData = _MemGlobalAlloc($iSize, $GMEM_MOVEABLE) 744 | Local $pData = _MemGlobalLock($hData) 745 | _MemMoveMemory(DllStructGetPtr($tObject), $pData, $iSize) 746 | Return $pData 747 | EndFunc 748 | 749 | Func __AOI_GlobalHandle($pMem) 750 | Local $aRet = DllCall("Kernel32.dll", "ptr", "GlobalHandle", "ptr", $pMem) 751 | If @error<>0 Then Return SetError(@error, @extended, 0) 752 | If $aRet[0]=0 Then Return SetError(-1, @extended, 0) 753 | Return $aRet[0] 754 | EndFunc 755 | 756 | Func __AOI_VariantInit($tVARIANT) 757 | Local $aRet=DllCall("OleAut32.dll","LONG","VariantInit",IsDllStruct($tVARIANT)?"struct*":"PTR",$tVARIANT) 758 | If @error<>0 Then Return SetError(-1, @error, 0) 759 | If $aRet[0]<>$__AOI_S_OK Then SetError($aRet, 0, $tVARIANT) 760 | Return 1 761 | EndFunc 762 | 763 | Func __AOI_VariantCopy($tVARIANT_Dest,$tVARIANT_Src) 764 | Local $aRet=DllCall("OleAut32.dll","LONG","VariantCopy",IsDllStruct($tVARIANT_Dest)?"struct*":"PTR",$tVARIANT_Dest, IsDllStruct($tVARIANT_Src)?"struct*":"PTR", $tVARIANT_Src) 765 | If @error<>0 Then Return SetError(-1, @error, 0) 766 | If $aRet[0]<>$__AOI_S_OK Then SetError($aRet, 0, 0) 767 | Return 1 768 | EndFunc 769 | 770 | Func __AOI_VariantClear($tVARIANT) 771 | Local $aRet=DllCall("OleAut32.dll","LONG","VariantClear",IsDllStruct($tVARIANT)?"struct*":"PTR",$tVARIANT) 772 | If @error<>0 Then Return SetError(-1, @error, 0) 773 | If $aRet[0]<>$__AOI_S_OK Then SetError($aRet, 0, $tVARIANT) 774 | Return 1 775 | EndFunc 776 | 777 | Func _AOI_PrivateProperty() 778 | Return SetError(1, 1, 0) 779 | EndFunc 780 | 781 | #cs 782 | # @internal 783 | #ce 784 | Func __AOI_PropertyGetFromName($tObject, $psName, $bCase = True) 785 | Local $iID = -1, $tProperty 786 | Local $pProperties = $tObject.Properties 787 | If $pProperties = 0 Then Return SetExtended(-1, 0) 788 | Local $sName = DllStructGetData(DllStructCreate("WCHAR[255]", $psName), 1) 789 | If $sName = "" Then Return SetError(0, 0, $pProperties) 790 | For $i=1 To $tObject.iProperties 791 | $tProperty = DllStructCreate($__AOI_tagProperty, $pProperties + ($__AOI_cProperty * $i)) 792 | If $bCase And DllStructGetData(DllStructCreate("WCHAR["&$tProperty.cName&"]", $tProperty.Name), 1) == $sName Then 793 | $iID = $i 794 | ExitLoop 795 | ElseIf Not $bCase And DllStructGetData(DllStructCreate("WCHAR["&$tProperty.cName&"]", $tProperty.Name), 1) = $sName Then 796 | $iID = $i 797 | ExitLoop 798 | EndIf 799 | Next 800 | If $iID=-1 Then Return SetError(1, $iID, 0) 801 | Return SetError(0, $iID, DllStructGetPtr($tProperty)) 802 | EndFunc 803 | 804 | #cs 805 | # @internal 806 | #ce 807 | Func __AOI_PropertyGetFromId($pProperty, $iID) 808 | Return DllStructCreate($__AOI_tagProperty, $pProperty + ($__AOI_cProperty * $iID)) 809 | EndFunc 810 | 811 | #cs 812 | # Get IDispatch property pointer offset from Object property in bytes 813 | # @internal 814 | # @param String $sElement struct element name 815 | # @return Integer offset 816 | #ce 817 | Func __AOI_GetPtrOffset($sElement) 818 | Local Static $tObject = DllStructCreate($__AOI_tagObject), $iObject = Int(DllStructGetPtr($tObject, "Object"), @AutoItX64?2:1) 819 | Return DllStructGetPtr($tObject, $sElement) - $iObject 820 | EndFunc 821 | 822 | Func __AOI_Properties_Add($tObject, $pName, $pVariant = 0) 823 | If ($tObject.iProperties+1) >= $tObject.cProperties Then __AOI_Properties_Resize($tObject) 824 | If @error <> 0 Then Return SetError(@error, -1) 825 | $tObject.iProperties += 1 826 | Local $tProperty = DllStructCreate($__AOI_tagProperty, $tObject.Properties + ($__AOI_cProperty * ($tObject.iProperties))) 827 | ;$tProperty.Name = SysAllocString($pName) 828 | $tProperty.Name = _WinAPI_CreateString(_WinAPI_GetString($pName)) 829 | $tProperty.cName = _WinAPI_StrLen($pName, True) 830 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, __AOI_MemCloneGlob(DllStructCreate($__AOI_tagVARIANT))) 831 | __AOI_VariantInit($tVARIANT) 832 | If Not ($pVARIANT = 0) Then 833 | __AOI_VariantReplace($tVARIANT, $pVariant) 834 | EndIf 835 | $tProperty.Variant = DllStructGetPtr($tVARIANT) 836 | Return SetExtended($tObject.iProperties, $tProperty) 837 | EndFunc 838 | 839 | Func __AOI_VariantReplace($tVARIANT_Dest, $tVARIANT_Src) 840 | __AOI_VariantClear($tVARIANT_Dest) 841 | __AOI_VariantCopy($tVARIANT_Dest, $tVARIANT_Src) 842 | EndFunc 843 | 844 | Func __AOI_Properties_Resize($tObject) 845 | Local $cProperties = $tObject.cProperties 846 | $cProperties = $cProperties > 0 ? $cProperties * 2 : 16; double the array capacity, or default to 16 as initial capacity 847 | Local $hProperties = _MemGlobalAlloc($__AOI_cProperty * $cProperties, $GMEM_MOVEABLE + $GMEM_ZEROINIT) 848 | Local $pProperties = _MemGlobalLock($hProperties) 849 | If $cProperties = 16 Then; no previous array exists 850 | Local $tProperty = __AOI_PropertyGetFromId($pProperties, 0) 851 | Local $tVARIANT = DllStructCreate($__AOI_tagVARIANT, __AOI_MemCloneGlob(DllStructCreate($__AOI_tagVARIANT))) 852 | __AOI_VariantInit($tVARIANT) 853 | $tProperty.Variant = DllStructGetPtr($tVARIANT) 854 | Else; there exists a previous array we need to copy and free 855 | _MemMoveMemory($tObject.Properties, $pProperties, $__AOI_cProperty * $tObject.cProperties) 856 | _MemGlobalFree(__AOI_GlobalHandle($tObject.Propertiesy)) 857 | EndIf 858 | $tObject.Properties = $pProperties 859 | $tObject.cProperties = $cProperties 860 | EndFunc 861 | 862 | Func __AOI_Properties_Remove($tObject, $iIndex);WARNING: do not remove index zero! 863 | Local $tProperty = DllStructCreate($__AOI_tagProperty, $tObject.Properties + ($__AOI_cProperty * $iIndex)) 864 | __AOI_VariantClear($tProperty.Variant) 865 | _WinAPI_FreeMemory($tProperty.Name) 866 | _MemMoveMemory($tObject.Properties + ($__AOI_cProperty * ($iIndex + 1)), $tObject.Properties + ($__AOI_cProperty * $iIndex), $__AOI_cProperty * ($tObject.cProperties - ($iIndex + 1))) 867 | $tObject.iProperties -= 1 868 | EndFunc 869 | --------------------------------------------------------------------------------