Jump to content

Recommended Posts

version: 2.0.0

So many new changes :)

Most notably, the change of Github repository. This project, now has it very own Github repository, for less obscurity with issues and releases.

Edited by genius257
fixed changes link
Link to post
Share on other sites
  • Replies 45
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

I've made a library, based on AutoItObject UDF with the goal of implementing getter and setter functionality and make it possible to define new object properties in as few steps as possible. Than

version: 4.0.0 changes Most notable changes: speed and readability. When testing speed i found a minimum increase in speed by ~20%

version: 3.0.0 changes Most notable change: ROT¹ support! 🎊 ¹ Running Object Table

Hello. ChangeLog says. [2.0.0] - 2017-07-07 I think is [2.0.0] - 2018-07-07

Between nice update.

 

Saludos

Link to post
Share on other sites
Link to post
Share on other sites
2 hours ago, Danyfirex said:

Hello. ChangeLog says. [2.0.0] - 2017-07-07 I think is [2.0.0] - 2018-07-07

Between nice update.

 

Saludos

Ooops :> yeah my mistake.

Thanks for noticing ^^ i will change that immediately.

Link to post
Share on other sites
  • 1 month later...

Did you ever fix the Running Object Table challenge you had?
In the title you say solved but wondering if you solved the reference count and if the solution is posted somewhere

I found another example on registering to ROT which maybe can give some directions if not refcount issue is solved

 

Link to post
Share on other sites
  • 1 year later...

Can this be used like in AutoItObject with this example:

 

?

 

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to post
Share on other sites

Hi @MrCreatoR.

I think you're asking if AutoItObject Internal can be used with ObjGet?

 

This is something that CAN work, but for me it's in the alpha stage.

I have unpublished code, where this works somewhat by registering an object with the Running Object Table, but I have yet to solve an issue where the obj ref count gets messed up, due to Release being called more times than the AddRef method for some strange reason.

My theory is that i somehow handle the QueryInterface method wrong in some cases, but i have yet to find the precise problem.

 

TLDR;

not currently, sorry.

Link to post
Share on other sites
1 hour ago, genius257 said:

I think you're asking if AutoItObject Internal can be used with ObjGet?

Yes, this also. I want to use it for interaction between process, to pass any type of data over COM object.

1 hour ago, genius257 said:

not currently, sorry.

It's ok, keep up the good work you do, thanks for that.

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to post
Share on other sites
  • 9 months later...

Hi @genius257,

thanks a lot for the effort on this! amazing.

based on this, I've created a very simple IPC solution: 

 

 

I've noticed in the event viewer, that when executing my examples, there seems to be an application crash. Sometimes it's in the ntdll, sometimes in combase. I didn't notice those crashes in autoit, because the two example scripts seem to run fine except (except when they dont).

I am quite sure, I am not using your Library as intended - could you be so kind to take a look at the linked post (and the files attached there) and let me know what I could be doing wrong.

Thanks & best regards, 

Link to post
Share on other sites

Hi @SEuBo.

Thanks! :) happy to know you like it.

Pretty cool idea. I've got work in progress for adding ROT functionality with my AutoObject_Internal, so if i work out the kinks, you won't need AutoItObject also :)

I can't seem to reproduce the problems you seem to describe (tested on win10).

IPC with AutoObject_Internal is unstable and very unpredictable currently.

Your usage, besides using it between processes seems to be fine :)

While current version is mostly stable, many edge cases makes the code more like a beta release currently. The issue for me is shallow COM interface documentation from MSDN and not many seems to report errors with the project (if more than a handful of people are using it).

 

My best guesses currently for the problem would be:

  • The reference count may reach 0 and trigger the object to release the memory (a bug with IPC i am looking into)
  • Currently i return no info from the TypeInfo part of IDispatch interface. This seems to cause no problems most of the time, but i suspect it may be the cause for crashes in some cases.

I will be happy to try and look into it, if I'm able to reproduce the bug reliably :)

Edited by genius257
Link to post
Share on other sites
  • 2 weeks later...

Hi @genius257,

Do we have a chance to make this method call work withouth the extra paranthesis?

($oObject.Method1)("Test")
#include <AutoItObject_Internal.au3>
#include <Array.au3>

#AutoIt3Wrapper_Run_Au3Check=n
Local $aArray[3] = [1, 2, 3]

$oObject = IDispatch()
$oObject.Method1 = _method1
$oObject.Method2_with_byref = _TestMethodByref

; Test Method1
($oObject.Method1)("Test")
$oObject.Method1("Test2")


; Test Method 2
_ArrayDisplay($aArray)
($oObject.Method2_with_byref)($aArray, "New Value")
$oObject.Method2_with_byref($aArray, "Aw, Shit")
_ArrayDisplay($aArray)


;MsgBox(0,"",VarGetType($oObject.Method1))
;MsgBox(0,"",VarGetType($oObject.Method1("vargettype")))

Func _method1($vParam)
    MsgBox(0,"",$vParam)
EndFunc

Func _TestMethodByref(ByRef $aData, $sText)
    ReDim $aArray[UBound($aArray) + 1]
    $aArray[UBound($aArray)-1] = $sText
EndFunc

I tried to play with the Invoke Function and in an seperate $DISPATCH_METHOD section under the $DISPATCH_PROPERTYGET, I managed to get the arguments from rgvargs but i'm not sure on how to proceed and invoke the actual function. 

I have now added a new section for $DISPATCH_METHOD to the Invoke()-Function. It's near the bottom and begins with:

If BitAND($wFlags, $DISPATCH_METHOD) = $DISPATCH_METHOD Then

I've also changed the lines for $DISPATCH_PROPERTYPUT and $DISPATCH_PROPERTYGET (I think the BitAnd wasn't really correct.)

Spoiler
Func Invoke($pSelf, $dispIdMember, $riid, $lcid, $wFlags, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr)
    If $dispIdMember = 0 Then
        Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
        Local $bCase = Not (BitAND($iLock, $__AOI_LOCK_CASE) > 0)
        __AOI_PropertyGetFromName(__AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("Properties"), "ptr"), "", $bCase)
        $dispIdMember = @error <> 0 ? -1 : (@extended + 1)
    EndIf
    If $dispIdMember = -1 Then Return $DISP_E_MEMBERNOTFOUND
    Local $tVARIANT, $_tVARIANT, $tDISPPARAMS
    Local $t
    Local $i

    Local $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
    Local $tProperty = DllStructCreate($tagProperty, $pProperty)

    If $dispIdMember < -1 Then
        If $dispIdMember = -3 Then;__isExtensible
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            Local $iExtensible = $__AOI_LOCK_CREATE
            $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
            $tVARIANT.vt = $VT_BOOL
            $tVARIANT.data = (BitAND($iLock, $iExtensible) = $iExtensible) ? 1 : 0
            Return $S_OK
        EndIf

        If $dispIdMember = -4 Then;__case
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If (Not (BitAND($wFlags, $DISPATCH_PROPERTYGET) = 0)) Then
                If $tDISPPARAMS.cArgs <> 0 Then Return $DISP_E_BADPARAMCOUNT
                $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
                $tVARIANT.vt = $VT_BOOL
                Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
                $tVARIANT.data = (BitAND($iLock, $__AOI_LOCK_CASE) > 0) ? 0 : 1
            Else; $DISPATCH_PROPERTYPUT
                If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
                $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
                If $tVARIANT.vt <> $VT_BOOL Then Return $DISP_E_BADVARTYPE
                Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
                If BitAND($iLock, $__AOI_LOCK_UPDATE) > 0 Then Return $DISP_E_EXCEPTION
                Local $tLock = DllStructCreate("BYTE", $pSelf + __AOI_GetPtrOffset("lock"))
                $b = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data")
                DllStructSetData($tLock, 1, _
                        (Not $b) ? BitOR(DllStructGetData($tLock, 1), $__AOI_LOCK_CASE) : BitAND(DllStructGetData($tLock, 1), BitNOT(BitShift(1, 0 - (Log($__AOI_LOCK_CASE) / Log(2))))) _
                        )

            EndIf
            Return $S_OK
        EndIf

        If $dispIdMember = -13 Then;__lookupSetter
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT

            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs)
            $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            If Not GetIDsOfNames($pSelf, $riid, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION

            $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id - 1)
            If Not $tProperty.__setter = 0 Then
                VariantClear($pVarResult)
                VariantCopy($pVarResult, $tProperty.__setter)
            EndIf
            Return $S_OK
        EndIf

        If $dispIdMember = -12 Then;__lookupGetter
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT

            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs)
            $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            If Not GetIDsOfNames($pSelf, $riid, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION

            $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id - 1)
            If Not $tProperty.__getter = 0 Then
                VariantClear($pVarResult)
                VariantCopy($pVarResult, $tProperty.__getter)
            EndIf
            Return $S_OK
        EndIf

        If $dispIdMember = -2 Then;__assign
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_CREATE) > 0 Then Return $DISP_E_EXCEPTION


            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs = 0 Then Return $DISP_E_BADPARAMCOUNT

            Local $tVARIANT = DllStructCreate($tagVARIANT)
            Local $iVARIANT = DllStructGetSize($tVARIANT)
            Local $i
            Local $pExternalProperty, $tExternalProperty
            Local $pProperty, $tProperty
            Local $iID, $iIndex, $pData
            For $i = $tDISPPARAMS.cArgs - 1 To 0 Step -1
                $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + $iVARIANT * $i)
                If Not (DllStructGetData($tVARIANT, "vt") = $VT_DISPATCH) Then Return $DISP_E_BADVARTYPE
                $pExternalProperty = __AOI_GetPtrValue(DllStructGetData($tVARIANT, "data") + __AOI_GetPtrOffset("Properties"), "ptr")
                While 1
                    If $pExternalProperty = 0 Then ExitLoop
                    $tExternalProperty = DllStructCreate($tagProperty, $pExternalProperty)

                    $pProperty = __AOI_PropertyGetFromName(__AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("Properties"), "ptr"), _WinAPI_GetString($tExternalProperty.Name), False)
                    $iID = @error <> 0 ? -1 : @extended
                    $iIndex = @extended

                    If ($iID = -1) Then
                        $pData = __AOI_PropertyCreate(_WinAPI_GetString($tExternalProperty.Name))
                        $tProperty = DllStructCreate($tagProperty, $pData)
                        VariantClear($tProperty.Variant)
                        VariantCopy($tProperty.Variant, $tExternalProperty.Variant)

                        If $iIndex = -1 Then;first item in list
                            DllStructSetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1, $pData)
                        Else
                            $tProperty = DllStructCreate($tagProperty, $pProperty)
                            $tProperty.Next = $pData
                        EndIf
                    Else
                        $tProperty = DllStructCreate($tagProperty, $pProperty)
                        VariantClear($tProperty.Variant)
                        VariantCopy($tProperty.Variant, $tExternalProperty.Variant)
                    EndIf

                    $pExternalProperty = $tExternalProperty.Next
                WEnd
            Next
            Return $S_OK
        EndIf

        If $dispIdMember = -7 Then;__isSealed
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            Local $iSeal = $__AOI_LOCK_CREATE + $__AOI_LOCK_DELETE
            $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
            $tVARIANT.vt = $VT_BOOL
            $tVARIANT.data = (BitAND($iLock, $iSeal) = $iSeal) ? 1 : 0
            Return $S_OK
        EndIf

        If $dispIdMember = -6 Then;__isFrozen
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            Local $iFreeze = $__AOI_LOCK_CREATE + $__AOI_LOCK_UPDATE + $__AOI_LOCK_DELETE
            $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
            $tVARIANT.vt = $VT_BOOL
            $tVARIANT.data = (BitAND($iLock, $iFreeze) = $iFreeze) ? 1 : 0
            Return $S_OK
        EndIf

        If $dispIdMember = -18 Then;__get
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If $tVARIANT.vt <> $VT_BSTR Then Return $DISP_E_BADVARTYPE
            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs)
            $t.str_ptr = DllStructGetData($tVARIANT, "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            If Not GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION
            Return Invoke($pSelf, $t.id, $riid, $lcid, $DISPATCH_PROPERTYGET, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr)
        EndIf

        If $dispIdMember = -19 Then;__set
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 2 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT)))
            If $tVARIANT.vt <> $VT_BSTR Then Return $DISP_E_BADVARTYPE
            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            $t.str_ptr = DllStructGetData($tVARIANT, "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            If Not GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION
            $tDISPPARAMS.cArgs = 1
            Return Invoke($pSelf, $t.id, $riid, $lcid, $DISPATCH_PROPERTYPUT, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr)
        EndIf

        If $dispIdMember = -20 Then;__exists
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If $tVARIANT.vt <> $VT_BSTR Then Return $DISP_E_BADVARTYPE
            Local $sProperty = _WinAPI_GetString($tVARIANT.data);the string to search for
            $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
            $tVARIANT.vt = $VT_BOOL
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            Local $bCase = Not (BitAND($iLock, $__AOI_LOCK_CASE) > 0)
            Local $pProperty = __AOI_PropertyGetFromName(__AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("Properties"), "ptr"), $sProperty, $bCase)
            $tVARIANT.data = @error <> 0 ? 0 : 1
            Return $S_OK
        EndIf

        If $dispIdMember = -16 Then;__destructor
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_CREATE) > 0 Then Return $DISP_E_EXCEPTION
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
            If (Not (DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "vt") = $VT_RECORD)) And (Not (DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "vt") = $VT_BSTR)) Then Return $DISP_E_BADVARTYPE
            Local $tVARIANT = DllStructCreate($tagVARIANT)
            Local $pVARIANT = MemCloneGlob($tVARIANT)
            $tVARIANT = DllStructCreate($tagVARIANT, $pVARIANT)
            VariantInit($pVARIANT)
            VariantCopy($pVARIANT, $tDISPPARAMS.rgvargs)
            DllStructSetData(DllStructCreate("PTR", $pSelf + __AOI_GetPtrOffset("__destructor")), 1, $pVARIANT)
            Return $S_OK
        EndIf

        If $dispIdMember = -5 Then;__freeze
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 0 Then Return $DISP_E_BADPARAMCOUNT
            Local $tLock = DllStructCreate("BYTE", $pSelf + __AOI_GetPtrOffset("lock"))
            DllStructSetData($tLock, 1, BitOR(DllStructGetData($tLock, 1), $__AOI_LOCK_CREATE + $__AOI_LOCK_DELETE + $__AOI_LOCK_UPDATE))
            Return $S_OK
        EndIf

        If $dispIdMember = -14 Then;__seal
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 0 Then Return $DISP_E_BADPARAMCOUNT
            Local $tLock = DllStructCreate("BYTE", $pSelf + __AOI_GetPtrOffset("lock"))
            DllStructSetData($tLock, 1, BitOR(DllStructGetData($tLock, 1), $__AOI_LOCK_CREATE + $__AOI_LOCK_DELETE))
            Return $S_OK
        EndIf

        If $dispIdMember = -9 Then;__preventExtensions
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 0 Then Return $DISP_E_BADPARAMCOUNT
            Local $tLock = DllStructCreate("BYTE", $pSelf + __AOI_GetPtrOffset("lock"))
            DllStructSetData($tLock, 1, BitOR(DllStructGetData($tLock, 1), $__AOI_LOCK_CREATE))
            Return $S_OK
        EndIf

        If $dispIdMember = -17 Then;__unset
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_DELETE) > 0 Then Return $DISP_E_EXCEPTION

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If Not ($VT_BSTR = $tVARIANT.vt) Then Return $DISP_E_BADVARTYPE
            Local $sProperty = _WinAPI_GetString($tVARIANT.data);the string to search for
            Local $tProperty = 0, $tProperty_Prev
            While 1
                If $pProperty = 0 Then ExitLoop
                $tProperty_Prev = $tProperty
                $tProperty = DllStructCreate($tagProperty, $pProperty)
                Local $bCase = Not (BitAND($iLock, $__AOI_LOCK_CASE) > 0)
                If ($bCase And _WinAPI_GetString($tProperty.Name) == $sProperty) Or ((Not $bCase) And _WinAPI_GetString($tProperty.Name) = $sProperty) Then
                    If $tProperty_Prev = 0 Then
                        DllStructSetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1, $tProperty.Next)
                    Else
                        $tProperty_Prev.Next = $tProperty.Next
                    EndIf
                    VariantClear($tProperty.Variant)
                    _MemGlobalFree(GlobalHandle($tProperty.Variant))
                    $tProperty = 0
                    _MemGlobalFree(GlobalHandle($pProperty))
                    Return $S_OK
                EndIf
                $pProperty = $tProperty.Next
            WEnd
            Return $DISP_E_MEMBERNOTFOUND
        EndIf

        If ($dispIdMember = -8) Then;__keys
            Local $aKeys[0]
            Local $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            While 1
                If $pProperty = 0 Then ExitLoop
                Local $tProperty = DllStructCreate($tagProperty, $pProperty)
                ReDim $aKeys[UBound($aKeys, 1) + 1]
                $aKeys[UBound($aKeys, 1) - 1] = DllStructGetData(DllStructCreate("WCHAR[" & _WinAPI_StrLen($tProperty.Name) & "]", $tProperty.Name), 1)
                If $tProperty.Next = 0 Then ExitLoop
                $pProperty = $tProperty.Next
            WEnd
            Local $oIDispatch = IDispatch()
            $oIDispatch.a = $aKeys
            VariantClear($pVarResult)
            VariantCopy($pVarResult, DllStructGetData(DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1)), "Variant"))
            $oIDispatch = 0
            Return $S_OK
        EndIf

        If ($dispIdMember = -10) Then;__defineGetter
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_CREATE) > 0 Then Return $DISP_E_EXCEPTION

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 2 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If Not (($tVARIANT.vt = $VT_RECORD) Or ($tVARIANT.vt = $VT_BSTR)) Then Return $DISP_E_BADVARTYPE
            Local $tVARIANT2 = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize($tVARIANT))
            If Not ($tVARIANT2.vt = $VT_BSTR) Then Return $DISP_E_BADVARTYPE

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT)))
            $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT))), "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id"))

            $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id - 1)

            If ($tProperty.__getter = 0) Then
                Local $tVARIANT_Getter = DllStructCreate($tagVARIANT)
                $pVARIANT_Getter = MemCloneGlob($tVARIANT_Getter)
                VariantInit($pVARIANT_Getter)
            Else
                Local $pVARIANT_Getter = $tProperty.__getter
                VariantClear($pVARIANT_Getter)
            EndIf
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            VariantCopy($pVARIANT_Getter, $tVARIANT)
            $tProperty.__getter = $pVARIANT_Getter
            Return $S_OK
        ElseIf ($dispIdMember = -11) Then;defineSetter
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_CREATE) > 0 Then Return $DISP_E_EXCEPTION

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 2 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If Not (($tVARIANT.vt = $VT_RECORD) Or ($tVARIANT.vt = $VT_BSTR)) Then Return $DISP_E_BADVARTYPE
            Local $tVARIANT2 = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize($tVARIANT))
            If Not ($tVARIANT2.vt = $VT_BSTR) Then Return $DISP_E_BADVARTYPE

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT)))
            $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT))), "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id"))

            $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            $tProperty = DllStructCreate($tagProperty, $pProperty)

            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            For $i = 1 To $t.id - 1
                $pProperty = $tProperty.Next
                $tProperty = DllStructCreate($tagProperty, $pProperty)
            Next
            If ($tProperty.__setter = 0) Then
                Local $tVARIANT_Setter = DllStructCreate($tagVARIANT)
                Local $pVARIANT_Setter = MemCloneGlob($tVARIANT_Setter)
                VariantInit($pVARIANT_Setter)
            Else
                Local $pVARIANT_Setter = $tProperty.__setter
                VariantClear($pVARIANT_Setter)
            EndIf
            VariantCopy($pVARIANT_Setter, $tVARIANT)
            $tProperty.__setter = $pVARIANT_Setter
            Return $S_OK
        EndIf
        Return $DISP_E_EXCEPTION
    EndIf

    For $i = 1 To $dispIdMember - 1
        $pProperty = $tProperty.Next
        $tProperty = DllStructCreate($tagProperty, $pProperty)
    Next

    $tVARIANT = DllStructCreate($tagVARIANT, $tProperty.Variant)


    If BitAND($wFlags, $DISPATCH_METHOD) = $DISPATCH_METHOD Then

        $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
        If $tDISPPARAMS.cArgs Then
            Local $tPropertyTarget, $iArguments, $_oIDispatch = IDispatch()
            $_oIDispatch.val = 0
            $tPropertyTarget = DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", Ptr($_oIDispatch) + __AOI_GetPtrOffset("Properties")), 1))

            Local $aArguments[$tDISPPARAMS.cArgs + 1]
            For $i = 1 To $tDISPPARAMS.cArgs
                ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $tPropertyTarget.Name = ' & _WinAPI_GetString($tPropertyTarget.Name) & @CRLF) ;### Debug Console
                VariantInit($tPropertyTarget.Variant)
                $tVariantSource = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + (($tDISPPARAMS.cArgs - $i) * DllStructGetSize($_tVARIANT)))
                VariantCopy($tPropertyTarget.Variant, $tVariantSource)
                $aArguments[$i] = $_oIDispatch.val
            Next
            $aArguments[0] = 'CallArgArray'
            VariantInit($tPropertyTarget.Variant)
            VariantCopy($tPropertyTarget.Variant, $tVARIANT)

            $_oIDispatch.val = Call($_oIDispatch.val, $aArguments)
            SetError(@error, @extended)

            VariantCopy($pVarResult, $tPropertyTarget)
            Return $S_OK
        Else
            VariantCopy($pVarResult, $tVARIANT)
            Return $S_OK

        EndIf



    ElseIf (BitAND($wFlags, $DISPATCH_PROPERTYGET) = $DISPATCH_PROPERTYGET) Then
        $_tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
        If Not ($tProperty.__getter = 0) Then
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            Local $oIDispatch = IDispatch()
            $oIDispatch.val = 0
            $oIDispatch.ret = 0
            DllStructSetData(DllStructCreate("INT", $pSelf - 4 - 4), 1, DllStructGetData(DllStructCreate("INT", $pSelf - 4 - 4), 1) + 1)
            $oIDispatch.parent = 0
            Local $tProperty02 = DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1))
            $tProperty02 = DllStructCreate($tagProperty, $tProperty02.Next)
            $tProperty02 = DllStructCreate($tagProperty, $tProperty02.Next)
            $tVARIANT = DllStructCreate($tagVARIANT, $tProperty02.Variant)
            $tVARIANT.vt = $VT_DISPATCH
            $tVARIANT.data = $pSelf
            $oIDispatch.arguments = IDispatch();
            $oIDispatch.arguments.length = $tDISPPARAMS.cArgs
            Local $aArguments[$tDISPPARAMS.cArgs], $iArguments = $tDISPPARAMS.cArgs - 1
            Local $_pProperty = DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1)
            Local $_tProperty = DllStructCreate($tagProperty, $_pProperty)
            For $i = 0 To $iArguments
                VariantClear($_tProperty.Variant)
                VariantCopy($_tProperty.Variant, $tDISPPARAMS.rgvargs + (($iArguments - $i) * DllStructGetSize($_tVARIANT)))
                $aArguments[$i] = $oIDispatch.val
            Next
            $oIDispatch.arguments.values = $aArguments
            $oIDispatch.arguments.__seal()
            $oIDispatch.__defineSetter("parent", PrivateProperty)
            VariantClear($_tProperty.Variant)
            VariantCopy($_tProperty.Variant, $tProperty.__getter)
            Local $fGetter = $oIDispatch.val
            VariantClear($_tProperty.Variant)
            VariantCopy($_tProperty.Variant, $tProperty.Variant)
            $oIDispatch.__seal()
            Local $mRet = Call($fGetter, $oIDispatch)
            Local $iError = @error, $iExtended = @extended
            VariantClear($tProperty.Variant)
            VariantCopy($tProperty.Variant, $_tProperty.Variant)
            $oIDispatch.ret = $mRet
            $_tProperty = DllStructCreate($tagProperty, $_tProperty.Next)
            VariantCopy($pVarResult, $_tProperty.Variant)
            $oIDispatch = 0
            Return ($iError <> 0) ? $DISP_E_EXCEPTION : $S_OK
            Return $S_OK
        EndIf

        VariantCopy($pVarResult, $tVARIANT)
        Return $S_OK
    ElseIf (BitAND($wFlags, $DISPATCH_PROPERTYPUT) = $DISPATCH_PROPERTYPUT) Then
        $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
        If Not ($tProperty.__setter = 0) Then
            Local $oIDispatch = IDispatch()
            $oIDispatch.val = 0
            $oIDispatch.ret = 0
            DllStructSetData(DllStructCreate("INT", $pSelf - 4 - 4), 1, DllStructGetData(DllStructCreate("INT", $pSelf - 4 - 4), 1) + 1)
            $oIDispatch.parent = 0
            Local $tProperty02 = DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1))
            $tProperty02 = DllStructCreate($tagProperty, $tProperty02.Next)
            $tProperty02 = DllStructCreate($tagProperty, $tProperty02.Next)
            $tVARIANT = DllStructCreate($tagVARIANT, $tProperty02.Variant)
            $tVARIANT.vt = $VT_DISPATCH
            $tVARIANT.data = $pSelf
            Local $_pProperty = DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1)
            Local $_tProperty = DllStructCreate($tagProperty, $_pProperty)
            Local $_tProperty2 = DllStructCreate($tagProperty, $_tProperty.Next)
            VariantClear($_tProperty.Variant)
            VariantCopy($_tProperty.Variant, $tProperty.__setter)
            VariantClear($_tProperty2.Variant)
            VariantCopy($_tProperty2.Variant, $tDISPPARAMS.rgvargs)
            Local $fSetter = $oIDispatch.val
            VariantClear($_tProperty.Variant)
            VariantCopy($_tProperty.Variant, $tProperty.Variant)
            $oIDispatch.__seal()
            Local $mRet = Call($fSetter, $oIDispatch)
            Local $iError = @error, $iExtended = @extended
            VariantClear($tProperty.Variant)
            VariantCopy($tProperty.Variant, $_tProperty.Variant)
            $oIDispatch.ret = $mRet
            $_tProperty = DllStructCreate($tagProperty, $_tProperty.Next)
            VariantCopy($pVarResult, $_tProperty.Variant)
            $oIDispatch = 0
            Return ($iError <> 0) ? $DISP_E_EXCEPTION : $S_OK
            Return $S_OK
        EndIf

        Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
        If BitAND($iLock, $__AOI_LOCK_UPDATE) > 0 Then Return $DISP_E_EXCEPTION

        $_tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
        VariantClear($tVARIANT)
        VariantCopy($tVARIANT, $_tVARIANT)
    EndIf
    Return $S_OK
EndFunc   ;==>Invoke

 

 

I didn't manage to get the functions return value, and ByRef parameters still don't work except when using the extra parenthesis I wanted to get rid of, see below. i assume that is because with the parenthesis, it's 'accessing' the method member, thus receiving the function ptr, thus letting AutoIt handle the Byref because it's not tunneled through COM.

($oObject.Method2_with_byref)($aArray, "New Value") ; works with ByRef
$oObject.Method2_with_byref($aArray, "Oh No!") ; doesnt work

 

Any Ideas on Return value & ByRef?

 

/Edit2: or is there another way to define/call methods which I didn't see?

Edited by SEuBo
Link to post
Share on other sites

Hi @SEuBo.

4 hours ago, SEuBo said:

Do we have a chance to make this method call work withouth the extra paranthesis?

Yes. if you use a getter. See /Examples/02 - Basic - Accessors.au3 for reference.

Why?

Spoiler

The $DISPATCH_METHOD flag is sent by AutoIt3 no matter if you try to call it, or simply get the value.

$object = IDispatch()

$oObject.item = 123

$a = $oObject.item
$b = $oObject.item()

ConsoleWrite($a&@CRLF); 123
ConsoleWrite($a&@CRLF); 123

The way to get value with or without parentheses is indistinguishable when called from AutoIt3.

I would classify it as a bug, but have not reported it.

That is why the parentheses are needed, if you don't define a getter. the first parentheses are for getting the value from the object and the second are for calling the method retrieved. If you omit the first parentheses AutoIt3 sees it as you trying to call a method on the object, not the function the property holds. And again since Invoke always receives the $DISPATCH_METHOD flag, the current way it works is the only way to provide predictable behavior.

 

5 hours ago, SEuBo said:

Do you have an Idea?

Yeah but it's fiddly:

Spoiler

Getting the variant data value for a AutoIt3 function data type is not possible to my knowledge (upon further glance is may be possible but i don't have the answer now), unless you get it from AutoIt3 itself. You can see me doing just that here.

If you want some help with the invoke function, let me know, but i need more details of what problem you're having.

Link to post
Share on other sites
34 minutes ago, genius257 said:

Yes. if you use a getter. See /Examples/02 - Basic - Accessors.au3 for reference.

Why?

It may be that I don't fully understand the library yet. I assumed that using an Accessor, I could only have one single parameter and could access other properties only by using the .parent-property. 

 

34 minutes ago, genius257 said:

The $DISPATCH_METHOD flag is sent by AutoIt3 no matter if you try to call it, or simply get the value.

that really sounds like it could become troublesome. I will watch out for this when digging deeper into this topic.

 

34 minutes ago, genius257 said:

Getting the variant data value for a AutoIt3 function data type is not possible to my knowledge (upon further glance is may be possible but i don't have the answer now), unless you get it from AutoIt3 itself. You can see me doing just that here.

Yes, I copied that behaviour in my version of the Invoke method. Did you take a look at Accessing AutoIt Variables from LarsJ? (I am sure you did). I will play around a bit more to see if I can get the behaviour I want.

 

34 minutes ago, genius257 said:

If you want some help with the invoke function, let me know, but i need more details of what problem you're having.

If you could take a look at the following script and the custom Invoke and tell me how I could get the return Value of method1, I would be pleased.

Spoiler
#include <AutoItObject_Internal.au3>
#include <Array.au3>

#AutoIt3Wrapper_Run_Au3Check=n
Local $aArray[3] = [1, 2, 3]

$oObject = IDispatch(QueryInterface, AddRef, Release, GetTypeInfoCount, GetTypeInfo, GetIDsOfNames, _
        Seubo_Invoke) ; <--
$oObject.Method1 = __method1
$oObject.Method2_with_byref = _TestMethodByref

; Test Method1
($oObject.Method1)("Test", "Text")
$iRet = $oObject.Method1("Test2", "Text2")
MsgBox(0,"","Return: " & $iRet)

; Test Method 2
_ArrayDisplay($aArray)
($oObject.Method2_with_byref)($aArray, "New Value")
$oObject.Method2_with_byref($aArray, "Oh no.")
_ArrayDisplay($aArray)


Func __method1($sTitle, $sParam)
    MsgBox(32, $sTitle, $sParam)
    Return 42
EndFunc   ;==>__method1


Func _TestMethodByref(ByRef $aData, $sText)
    ReDim $aArray[UBound($aArray) + 1]
    $aArray[UBound($aArray) - 1] = $sText
    Return 42
EndFunc   ;==>_TestMethodByref


Func Seubo_Invoke($pSelf, $dispIdMember, $riid, $lcid, $wFlags, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr)
    If $dispIdMember = 0 Then
        Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
        Local $bCase = Not (BitAND($iLock, $__AOI_LOCK_CASE) > 0)
        __AOI_PropertyGetFromName(__AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("Properties"), "ptr"), "", $bCase)
        $dispIdMember = @error <> 0 ? -1 : (@extended + 1)
    EndIf
    If $dispIdMember = -1 Then Return $DISP_E_MEMBERNOTFOUND
    Local $tVARIANT, $_tVARIANT, $tDISPPARAMS
    Local $t
    Local $i

    Local $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
    Local $tProperty = DllStructCreate($tagProperty, $pProperty)

    If $dispIdMember < -1 Then
        If $dispIdMember = -3 Then;__isExtensible
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            Local $iExtensible = $__AOI_LOCK_CREATE
            $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
            $tVARIANT.vt = $VT_BOOL
            $tVARIANT.data = (BitAND($iLock, $iExtensible) = $iExtensible) ? 1 : 0
            Return $S_OK
        EndIf

        If $dispIdMember = -4 Then;__case
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If (Not (BitAND($wFlags, $DISPATCH_PROPERTYGET) = 0)) Then
                If $tDISPPARAMS.cArgs <> 0 Then Return $DISP_E_BADPARAMCOUNT
                $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
                $tVARIANT.vt = $VT_BOOL
                Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
                $tVARIANT.data = (BitAND($iLock, $__AOI_LOCK_CASE) > 0) ? 0 : 1
            Else; $DISPATCH_PROPERTYPUT
                If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
                $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
                If $tVARIANT.vt <> $VT_BOOL Then Return $DISP_E_BADVARTYPE
                Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
                If BitAND($iLock, $__AOI_LOCK_UPDATE) > 0 Then Return $DISP_E_EXCEPTION
                Local $tLock = DllStructCreate("BYTE", $pSelf + __AOI_GetPtrOffset("lock"))
                $b = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data")
                DllStructSetData($tLock, 1, _
                        (Not $b) ? BitOR(DllStructGetData($tLock, 1), $__AOI_LOCK_CASE) : BitAND(DllStructGetData($tLock, 1), BitNOT(BitShift(1, 0 - (Log($__AOI_LOCK_CASE) / Log(2))))) _
                        )

            EndIf
            Return $S_OK
        EndIf

        If $dispIdMember = -13 Then;__lookupSetter
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT

            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs)
            $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            If Not GetIDsOfNames($pSelf, $riid, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION

            $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id - 1)
            If Not $tProperty.__setter = 0 Then
                VariantClear($pVarResult)
                VariantCopy($pVarResult, $tProperty.__setter)
            EndIf
            Return $S_OK
        EndIf

        If $dispIdMember = -12 Then;__lookupGetter
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT

            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs)
            $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            If Not GetIDsOfNames($pSelf, $riid, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION

            $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id - 1)
            If Not $tProperty.__getter = 0 Then
                VariantClear($pVarResult)
                VariantCopy($pVarResult, $tProperty.__getter)
            EndIf
            Return $S_OK
        EndIf

        If $dispIdMember = -2 Then;__assign
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_CREATE) > 0 Then Return $DISP_E_EXCEPTION


            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs = 0 Then Return $DISP_E_BADPARAMCOUNT

            Local $tVARIANT = DllStructCreate($tagVARIANT)
            Local $iVARIANT = DllStructGetSize($tVARIANT)
            Local $i
            Local $pExternalProperty, $tExternalProperty
            Local $pProperty, $tProperty
            Local $iID, $iIndex, $pData
            For $i = $tDISPPARAMS.cArgs - 1 To 0 Step -1
                $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + $iVARIANT * $i)
                If Not (DllStructGetData($tVARIANT, "vt") = $VT_DISPATCH) Then Return $DISP_E_BADVARTYPE
                $pExternalProperty = __AOI_GetPtrValue(DllStructGetData($tVARIANT, "data") + __AOI_GetPtrOffset("Properties"), "ptr")
                While 1
                    If $pExternalProperty = 0 Then ExitLoop
                    $tExternalProperty = DllStructCreate($tagProperty, $pExternalProperty)

                    $pProperty = __AOI_PropertyGetFromName(__AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("Properties"), "ptr"), _WinAPI_GetString($tExternalProperty.Name), False)
                    $iID = @error <> 0 ? -1 : @extended
                    $iIndex = @extended

                    If ($iID = -1) Then
                        $pData = __AOI_PropertyCreate(_WinAPI_GetString($tExternalProperty.Name))
                        $tProperty = DllStructCreate($tagProperty, $pData)
                        VariantClear($tProperty.Variant)
                        VariantCopy($tProperty.Variant, $tExternalProperty.Variant)

                        If $iIndex = -1 Then;first item in list
                            DllStructSetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1, $pData)
                        Else
                            $tProperty = DllStructCreate($tagProperty, $pProperty)
                            $tProperty.Next = $pData
                        EndIf
                    Else
                        $tProperty = DllStructCreate($tagProperty, $pProperty)
                        VariantClear($tProperty.Variant)
                        VariantCopy($tProperty.Variant, $tExternalProperty.Variant)
                    EndIf

                    $pExternalProperty = $tExternalProperty.Next
                WEnd
            Next
            Return $S_OK
        EndIf

        If $dispIdMember = -7 Then;__isSealed
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            Local $iSeal = $__AOI_LOCK_CREATE + $__AOI_LOCK_DELETE
            $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
            $tVARIANT.vt = $VT_BOOL
            $tVARIANT.data = (BitAND($iLock, $iSeal) = $iSeal) ? 1 : 0
            Return $S_OK
        EndIf

        If $dispIdMember = -6 Then;__isFrozen
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            Local $iFreeze = $__AOI_LOCK_CREATE + $__AOI_LOCK_UPDATE + $__AOI_LOCK_DELETE
            $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
            $tVARIANT.vt = $VT_BOOL
            $tVARIANT.data = (BitAND($iLock, $iFreeze) = $iFreeze) ? 1 : 0
            Return $S_OK
        EndIf

        If $dispIdMember = -18 Then;__get
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If $tVARIANT.vt <> $VT_BSTR Then Return $DISP_E_BADVARTYPE
            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs)
            $t.str_ptr = DllStructGetData($tVARIANT, "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            If Not GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION
            Return Invoke($pSelf, $t.id, $riid, $lcid, $DISPATCH_PROPERTYGET, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr)
        EndIf

        If $dispIdMember = -19 Then;__set
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 2 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT)))
            If $tVARIANT.vt <> $VT_BSTR Then Return $DISP_E_BADVARTYPE
            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            $t.str_ptr = DllStructGetData($tVARIANT, "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            If Not GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id")) = $S_OK Then Return $DISP_E_EXCEPTION
            $tDISPPARAMS.cArgs = 1
            Return Invoke($pSelf, $t.id, $riid, $lcid, $DISPATCH_PROPERTYPUT, $pDispParams, $pVarResult, $pExcepInfo, $puArgErr)
        EndIf

        If $dispIdMember = -20 Then;__exists
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If $tVARIANT.vt <> $VT_BSTR Then Return $DISP_E_BADVARTYPE
            Local $sProperty = _WinAPI_GetString($tVARIANT.data);the string to search for
            $tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
            $tVARIANT.vt = $VT_BOOL
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            Local $bCase = Not (BitAND($iLock, $__AOI_LOCK_CASE) > 0)
            Local $pProperty = __AOI_PropertyGetFromName(__AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("Properties"), "ptr"), $sProperty, $bCase)
            $tVARIANT.data = @error <> 0 ? 0 : 1
            Return $S_OK
        EndIf

        If $dispIdMember = -16 Then;__destructor
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_CREATE) > 0 Then Return $DISP_E_EXCEPTION
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
            If (Not (DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "vt") = $VT_RECORD)) And (Not (DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs), "vt") = $VT_BSTR)) Then Return $DISP_E_BADVARTYPE
            Local $tVARIANT = DllStructCreate($tagVARIANT)
            Local $pVARIANT = MemCloneGlob($tVARIANT)
            $tVARIANT = DllStructCreate($tagVARIANT, $pVARIANT)
            VariantInit($pVARIANT)
            VariantCopy($pVARIANT, $tDISPPARAMS.rgvargs)
            DllStructSetData(DllStructCreate("PTR", $pSelf + __AOI_GetPtrOffset("__destructor")), 1, $pVARIANT)
            Return $S_OK
        EndIf

        If $dispIdMember = -5 Then;__freeze
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 0 Then Return $DISP_E_BADPARAMCOUNT
            Local $tLock = DllStructCreate("BYTE", $pSelf + __AOI_GetPtrOffset("lock"))
            DllStructSetData($tLock, 1, BitOR(DllStructGetData($tLock, 1), $__AOI_LOCK_CREATE + $__AOI_LOCK_DELETE + $__AOI_LOCK_UPDATE))
            Return $S_OK
        EndIf

        If $dispIdMember = -14 Then;__seal
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 0 Then Return $DISP_E_BADPARAMCOUNT
            Local $tLock = DllStructCreate("BYTE", $pSelf + __AOI_GetPtrOffset("lock"))
            DllStructSetData($tLock, 1, BitOR(DllStructGetData($tLock, 1), $__AOI_LOCK_CREATE + $__AOI_LOCK_DELETE))
            Return $S_OK
        EndIf

        If $dispIdMember = -9 Then;__preventExtensions
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 0 Then Return $DISP_E_BADPARAMCOUNT
            Local $tLock = DllStructCreate("BYTE", $pSelf + __AOI_GetPtrOffset("lock"))
            DllStructSetData($tLock, 1, BitOR(DllStructGetData($tLock, 1), $__AOI_LOCK_CREATE))
            Return $S_OK
        EndIf

        If $dispIdMember = -17 Then;__unset
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_DELETE) > 0 Then Return $DISP_E_EXCEPTION

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 1 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If Not ($VT_BSTR = $tVARIANT.vt) Then Return $DISP_E_BADVARTYPE
            Local $sProperty = _WinAPI_GetString($tVARIANT.data);the string to search for
            Local $tProperty = 0, $tProperty_Prev
            While 1
                If $pProperty = 0 Then ExitLoop
                $tProperty_Prev = $tProperty
                $tProperty = DllStructCreate($tagProperty, $pProperty)
                Local $bCase = Not (BitAND($iLock, $__AOI_LOCK_CASE) > 0)
                If ($bCase And _WinAPI_GetString($tProperty.Name) == $sProperty) Or ((Not $bCase) And _WinAPI_GetString($tProperty.Name) = $sProperty) Then
                    If $tProperty_Prev = 0 Then
                        DllStructSetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1, $tProperty.Next)
                    Else
                        $tProperty_Prev.Next = $tProperty.Next
                    EndIf
                    VariantClear($tProperty.Variant)
                    _MemGlobalFree(GlobalHandle($tProperty.Variant))
                    $tProperty = 0
                    _MemGlobalFree(GlobalHandle($pProperty))
                    Return $S_OK
                EndIf
                $pProperty = $tProperty.Next
            WEnd
            Return $DISP_E_MEMBERNOTFOUND
        EndIf

        If ($dispIdMember = -8) Then;__keys
            Local $aKeys[0]
            Local $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            While 1
                If $pProperty = 0 Then ExitLoop
                Local $tProperty = DllStructCreate($tagProperty, $pProperty)
                ReDim $aKeys[UBound($aKeys, 1) + 1]
                $aKeys[UBound($aKeys, 1) - 1] = DllStructGetData(DllStructCreate("WCHAR[" & _WinAPI_StrLen($tProperty.Name) & "]", $tProperty.Name), 1)
                If $tProperty.Next = 0 Then ExitLoop
                $pProperty = $tProperty.Next
            WEnd
            Local $oIDispatch = IDispatch()
            $oIDispatch.a = $aKeys
            VariantClear($pVarResult)
            VariantCopy($pVarResult, DllStructGetData(DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1)), "Variant"))
            $oIDispatch = 0
            Return $S_OK
        EndIf

        If ($dispIdMember = -10) Then;__defineGetter
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_CREATE) > 0 Then Return $DISP_E_EXCEPTION

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 2 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If Not (($tVARIANT.vt = $VT_RECORD) Or ($tVARIANT.vt = $VT_BSTR)) Then Return $DISP_E_BADVARTYPE
            Local $tVARIANT2 = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize($tVARIANT))
            If Not ($tVARIANT2.vt = $VT_BSTR) Then Return $DISP_E_BADVARTYPE

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT)))
            $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT))), "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id"))

            $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            $tProperty = __AOI_PropertyGetFromId($pProperty, $t.id - 1)

            If ($tProperty.__getter = 0) Then
                Local $tVARIANT_Getter = DllStructCreate($tagVARIANT)
                $pVARIANT_Getter = MemCloneGlob($tVARIANT_Getter)
                VariantInit($pVARIANT_Getter)
            Else
                Local $pVARIANT_Getter = $tProperty.__getter
                VariantClear($pVARIANT_Getter)
            EndIf
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            VariantCopy($pVARIANT_Getter, $tVARIANT)
            $tProperty.__getter = $pVARIANT_Getter
            Return $S_OK
        ElseIf ($dispIdMember = -11) Then;defineSetter
            Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
            If BitAND($iLock, $__AOI_LOCK_CREATE) > 0 Then Return $DISP_E_EXCEPTION

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            If $tDISPPARAMS.cArgs <> 2 Then Return $DISP_E_BADPARAMCOUNT
            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            If Not (($tVARIANT.vt = $VT_RECORD) Or ($tVARIANT.vt = $VT_BSTR)) Then Return $DISP_E_BADVARTYPE
            Local $tVARIANT2 = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize($tVARIANT))
            If Not ($tVARIANT2.vt = $VT_BSTR) Then Return $DISP_E_BADVARTYPE

            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            $t = DllStructCreate("ptr id_ptr;long id;ptr str_ptr_ptr;ptr str_ptr")
            DllStructSetData($t, "id_ptr", DllStructGetPtr($t, 2))
            DllStructSetData($t, "str_ptr", $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT)))
            $t.str_ptr = DllStructGetData(DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + DllStructGetSize(DllStructCreate($tagVARIANT))), "data")
            $t.str_ptr_ptr = DllStructGetPtr($t, "str_ptr")
            GetIDsOfNames($pSelf, 0, $t.str_ptr_ptr, 1, $lcid, DllStructGetPtr($t, "id"))

            $pProperty = DllStructGetData(DllStructCreate("ptr", $pSelf + __AOI_GetPtrOffset("Properties")), 1)
            $tProperty = DllStructCreate($tagProperty, $pProperty)

            $tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
            For $i = 1 To $t.id - 1
                $pProperty = $tProperty.Next
                $tProperty = DllStructCreate($tagProperty, $pProperty)
            Next
            If ($tProperty.__setter = 0) Then
                Local $tVARIANT_Setter = DllStructCreate($tagVARIANT)
                Local $pVARIANT_Setter = MemCloneGlob($tVARIANT_Setter)
                VariantInit($pVARIANT_Setter)
            Else
                Local $pVARIANT_Setter = $tProperty.__setter
                VariantClear($pVARIANT_Setter)
            EndIf
            VariantCopy($pVARIANT_Setter, $tVARIANT)
            $tProperty.__setter = $pVARIANT_Setter
            Return $S_OK
        EndIf
        Return $DISP_E_EXCEPTION
    EndIf

    For $i = 1 To $dispIdMember - 1
        $pProperty = $tProperty.Next
        $tProperty = DllStructCreate($tagProperty, $pProperty)
    Next

    $tVARIANT = DllStructCreate($tagVARIANT, $tProperty.Variant)


    If BitAND($wFlags, $DISPATCH_METHOD) = $DISPATCH_METHOD Then

        $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
        If $tDISPPARAMS.cArgs Then
            Local $tPropertyTarget, $iArguments, $_oIDispatch = IDispatch()
            $_oIDispatch.val = 0
            $tPropertyTarget = DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", Ptr($_oIDispatch) + __AOI_GetPtrOffset("Properties")), 1))

            Local $aArguments[$tDISPPARAMS.cArgs + 1]
            For $i = 1 To $tDISPPARAMS.cArgs
                ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $tPropertyTarget.Name = ' & _WinAPI_GetString($tPropertyTarget.Name) & @CRLF) ;### Debug Console
                VariantInit($tPropertyTarget.Variant)
                $tVariantSource = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs + (($tDISPPARAMS.cArgs - $i) * DllStructGetSize($_tVARIANT)))
                VariantCopy($tPropertyTarget.Variant, $tVariantSource)
                $aArguments[$i] = $_oIDispatch.val
            Next
            $aArguments[0] = 'CallArgArray'
            VariantInit($tPropertyTarget.Variant)
            VariantCopy($tPropertyTarget.Variant, $tVARIANT)

            $_oIDispatch.val = Call($_oIDispatch.val, $aArguments)
            SetError(@error, @extended)

            VariantCopy($pVarResult, $tPropertyTarget)
            Return $S_OK
        Else
            VariantCopy($pVarResult, $tVARIANT)
            Return $S_OK

        EndIf



    ElseIf (BitAND($wFlags, $DISPATCH_PROPERTYGET) = $DISPATCH_PROPERTYGET) Then
        $_tVARIANT = DllStructCreate($tagVARIANT, $pVarResult)
        If Not ($tProperty.__getter = 0) Then
            $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
            Local $oIDispatch = IDispatch()
            $oIDispatch.val = 0
            $oIDispatch.ret = 0
            DllStructSetData(DllStructCreate("INT", $pSelf - 4 - 4), 1, DllStructGetData(DllStructCreate("INT", $pSelf - 4 - 4), 1) + 1)
            $oIDispatch.parent = 0
            Local $tProperty02 = DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1))
            $tProperty02 = DllStructCreate($tagProperty, $tProperty02.Next)
            $tProperty02 = DllStructCreate($tagProperty, $tProperty02.Next)
            $tVARIANT = DllStructCreate($tagVARIANT, $tProperty02.Variant)
            $tVARIANT.vt = $VT_DISPATCH
            $tVARIANT.data = $pSelf
            $oIDispatch.arguments = IDispatch();
            $oIDispatch.arguments.length = $tDISPPARAMS.cArgs
            Local $aArguments[$tDISPPARAMS.cArgs], $iArguments = $tDISPPARAMS.cArgs - 1
            Local $_pProperty = DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1)
            Local $_tProperty = DllStructCreate($tagProperty, $_pProperty)
            For $i = 0 To $iArguments
                VariantClear($_tProperty.Variant)
                VariantCopy($_tProperty.Variant, $tDISPPARAMS.rgvargs + (($iArguments - $i) * DllStructGetSize($_tVARIANT)))
                $aArguments[$i] = $oIDispatch.val
            Next
            $oIDispatch.arguments.values = $aArguments
            $oIDispatch.arguments.__seal()
            $oIDispatch.__defineSetter("parent", PrivateProperty)
            VariantClear($_tProperty.Variant)
            VariantCopy($_tProperty.Variant, $tProperty.__getter)
            Local $fGetter = $oIDispatch.val
            VariantClear($_tProperty.Variant)
            VariantCopy($_tProperty.Variant, $tProperty.Variant)
            $oIDispatch.__seal()
            Local $mRet = Call($fGetter, $oIDispatch)
            Local $iError = @error, $iExtended = @extended
            VariantClear($tProperty.Variant)
            VariantCopy($tProperty.Variant, $_tProperty.Variant)
            $oIDispatch.ret = $mRet
            $_tProperty = DllStructCreate($tagProperty, $_tProperty.Next)
            VariantCopy($pVarResult, $_tProperty.Variant)
            $oIDispatch = 0
            Return ($iError <> 0) ? $DISP_E_EXCEPTION : $S_OK
            Return $S_OK
        EndIf

        VariantCopy($pVarResult, $tVARIANT)
        Return $S_OK
    ElseIf (BitAND($wFlags, $DISPATCH_PROPERTYPUT) = $DISPATCH_PROPERTYPUT) Then
        $tDISPPARAMS = DllStructCreate($tagDISPPARAMS, $pDispParams)
        If Not ($tProperty.__setter = 0) Then
            Local $oIDispatch = IDispatch()
            $oIDispatch.val = 0
            $oIDispatch.ret = 0
            DllStructSetData(DllStructCreate("INT", $pSelf - 4 - 4), 1, DllStructGetData(DllStructCreate("INT", $pSelf - 4 - 4), 1) + 1)
            $oIDispatch.parent = 0
            Local $tProperty02 = DllStructCreate($tagProperty, DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1))
            $tProperty02 = DllStructCreate($tagProperty, $tProperty02.Next)
            $tProperty02 = DllStructCreate($tagProperty, $tProperty02.Next)
            $tVARIANT = DllStructCreate($tagVARIANT, $tProperty02.Variant)
            $tVARIANT.vt = $VT_DISPATCH
            $tVARIANT.data = $pSelf
            Local $_pProperty = DllStructGetData(DllStructCreate("ptr", Ptr($oIDispatch) + __AOI_GetPtrOffset("Properties")), 1)
            Local $_tProperty = DllStructCreate($tagProperty, $_pProperty)
            Local $_tProperty2 = DllStructCreate($tagProperty, $_tProperty.Next)
            VariantClear($_tProperty.Variant)
            VariantCopy($_tProperty.Variant, $tProperty.__setter)
            VariantClear($_tProperty2.Variant)
            VariantCopy($_tProperty2.Variant, $tDISPPARAMS.rgvargs)
            Local $fSetter = $oIDispatch.val
            VariantClear($_tProperty.Variant)
            VariantCopy($_tProperty.Variant, $tProperty.Variant)
            $oIDispatch.__seal()
            Local $mRet = Call($fSetter, $oIDispatch)
            Local $iError = @error, $iExtended = @extended
            VariantClear($tProperty.Variant)
            VariantCopy($tProperty.Variant, $_tProperty.Variant)
            $oIDispatch.ret = $mRet
            $_tProperty = DllStructCreate($tagProperty, $_tProperty.Next)
            VariantCopy($pVarResult, $_tProperty.Variant)
            $oIDispatch = 0
            Return ($iError <> 0) ? $DISP_E_EXCEPTION : $S_OK
            Return $S_OK
        EndIf

        Local $iLock = __AOI_GetPtrValue($pSelf + __AOI_GetPtrOffset("lock"), "BYTE")
        If BitAND($iLock, $__AOI_LOCK_UPDATE) > 0 Then Return $DISP_E_EXCEPTION

        $_tVARIANT = DllStructCreate($tagVARIANT, $tDISPPARAMS.rgvargs)
        VariantClear($tVARIANT)
        VariantCopy($tVARIANT, $_tVARIANT)
    EndIf
    Return $S_OK
EndFunc   ;==>Seubo_Invoke

 

 

 

34 minutes ago, genius257 said:

more details of what problem you're having.

No problem at all - I think I could work around everything using setters/getters and just accessing the properties directly.  I just see huge potential with this UDF and I want to make defining and calling "regular" methods more easy. That would also allow some kind of inheritance - or at least traits. This library deserves way more attention - but I feel like it need's to be more "accessible" and more generalized.

Edited by SEuBo
Link to post
Share on other sites
1 hour ago, SEuBo said:

It may be that I don't fully understand the library yet. I assumed that using an Accessor, I could only have one single parameter and could access other properties only by using the .parent-property. 

Here is an example for using getter as a object method

#include "AutoItObject_Internal.au3"
#include <Array.au3>

$oObject = IDispatch()

$oObject.key = "initial value of key"
$oObject.__defineGetter('key', getter)

$oObject.key
$oObject.key()
$oObject.key('A')
$oObject.key(123, 456)
$oObject.key('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','X','Y','Z')
ConsoleWrite($oObject.key&@CRLF)

Func getter($AccessorObject)
    Local Static $counter = 0

    Local $oArguments = $AccessorObject.arguments
    Local $iArguments = $oArguments.length
    Local $aArguments = $oArguments.values

    ConsoleWrite(StringFormat("getter invoked with %d number of parameters:\n", $iArguments))
    Local $i
    For $i = 0 To $iArguments - 1 Step +1
        ConsoleWrite(StringFormat("\targument [%02d]: (%s) %s\n", $i + 1, VarGetType($aArguments[$i]), $aArguments[$i]))
    Next

    Local $returnVal = $AccessorObject.val
    $counter += 1
    $AccessorObject.val = StringFormat('this property has been accessed for read %d times', $counter)
    Return $returnVal
EndFunc

 

1 hour ago, SEuBo said:

that really sounds like it could become troublesome.

Oh it already is :)

1 hour ago, SEuBo said:

If you could take a look at the following script and the custom Invoke and tell me how I could get the return Value of method1, I would be pleased.

On line 434:

VariantCopy($pVarResult, $tPropertyTarget)

Should be:

VariantCopy($pVarResult, $tPropertyTarget.Variant)

You were parsing in a struct, where a ptr was expected ;)

1 hour ago, SEuBo said:

That would also allow some kind of inheritance

I'm not sure, but maybe you need to look at __assign

Example:

#include <AutoItObject_Internal.au3>

$cFoo=IDispatch()

func cFoo_Method1($self)
;~ whatever we want to have shared as a method printing a property of the current object
ConsoleWrite($self.parent.Property1)
endfunc

$cFoo.Method1 = cFoo_Method1

$oFoo1=$cFoo

;~ Have independent propertyvalues
$oFoo1.Property1="Hello world 1"

$oFoo2=IDispatch()

$oFoo2.__assign($oFoo1)

$oFoo2.Property1="Hello world 2"

MsgBox(0, "", $oFoo1.Property1)
MsgBox(0, "", $oFoo2.Property1)

MsgBox(0, "", FuncName($oFoo1.Method1))
MsgBox(0, "", FuncName($oFoo2.Method1))

 

A side note: If you are looking into a more class like usage, I am working on another project for that au3Class (powered by AutoItObject_Internal). It does have the downside of requiring transpiling the code before running it, but allows for great overview. I am working on adding support for class extending, traits and interfaces :)

Link to post
Share on other sites
  • 8 months later...

Can someone show me a simple array and array 2d transfer between 2 scripts

Script 1:

#include "AutoItSharedData.au3"
Global $oShare = _AutoIt_SharedData_CreateOrAttach("mouseData")

Global $oShare.s_blue_arr[1][1] = [[$s[0],$s[1],$s[2],$s[3]] _
        , [$s_2[0],$s_2[1],$s_2[2],$s_2[3]]]


While 1
 sleep (10)
WEnd

 

Script 2:
 

#include "AutoItSharedData.au3"
Global $oShare = _AutoIt_SharedData_CreateOrAttach("mouseData")


While 1

    MsgBox (1,"",$oShare.s_blue_arr[0][0])

WEnd

 

Link to post
Share on other sites
5 hours ago, Dexter1993 said:

Can someone show me a simple array and array 2d transfer between 2 scripts

Script 1:

#include "AutoItSharedData.au3"
Global $oShare = _AutoIt_SharedData_CreateOrAttach("mouseData")

Global $oShare.s_blue_arr[1][1] = [[$s[0],$s[1],$s[2],$s[3]] _
        , [$s_2[0],$s_2[1],$s_2[2],$s_2[3]]]


While 1
 sleep (10)
WEnd

 

Script 2:
 

#include "AutoItSharedData.au3"
Global $oShare = _AutoIt_SharedData_CreateOrAttach("mouseData")


While 1

    MsgBox (1,"",$oShare.s_blue_arr[0][0])

WEnd

 

Hi @Dexter1993.

First of all, you seem to use AutoItSharedData. It is dependent on this library, but it seems a little off-topic in this thread maybe?

But anyhow, here is an example for you:

Script 1:

#include <AutoItObject_Internal.au3>
#include <AutoItObject_Internal_ROT.au3>

Global $oShare = IDispatch()
; AutoIt3 does not currently support "inline"/anonymous array creation, so we need to assign it to a variable before use.
Global $aArray = [[1,2,3,4],[5,6,7,8]]

$oShare.array = $aArray

_AOI_ROT_register($oShare, "mouseData")

While 1
    Sleep(10)
WEnd

Script 2:

#include <Array.au3>
#include <AutoItObject_Internal.au3>
#include <AutoItObject_Internal_ROT.au3>

Global $oShare = ObjGet("mouseData")
Global $aArray = $oShare.array

_ArrayDisplay($aArray)

; To access array inline from object, the property must be wrapped in parentheses
MsgBox(0, "", ($oShare.array)[0][0])

While 1
    Sleep(10)
WEnd

 

Edited by genius257
typo
Link to post
Share on other sites
  • 4 months later...

@genius257

Thank you, I can't express how great this is!

Using this, I wrote the below function to read in an INI file as an object. Do you see any memory issues with creating the IDispatch object in the loop? For example, should I call __destructor after each pass or will that be done automatically on the next "$oThisSection = IDispatch()"?


_objINI.au3

#include "AutoItObject_Internal.au3"

$oColors = _objINI_create("colors.ini")
ConsoleWrite($oColors.dark.black & @CRLF)

Func _objINI_create($filename)
    ; check if file exists
    If Not FileExists($filename) Then
        Return -1
    EndIf

    ; read in the section names
    $aSectionNames = IniReadSectionNames($filename)
    If @error Then
        Return -2
    EndIf

    ;create the main object
    Local $objINI = IDispatch()

    ;loop through section names. create IDispatch object for each section
    Local $sectionName, $oThisSection
    For $i = 1 To $aSectionNames[0]
        $sectionName = $aSectionNames[$i]

        $aSectionData = IniReadSection($filename, $sectionName)
        If @error Then
            Return -3
        EndIf

        ;section object
        $oThisSection = IDispatch()
        For $j = 1 To $aSectionData[0][0]
            ;add property to this section object
            $oThisSection.__set($aSectionData[$j][0], $aSectionData[$j][1])
        Next

        ;add this section to the main object
        $objINI.__set($sectionName, $oThisSection)
    Next

    Return $objINI
EndFunc   ;==>_objINI_create


colors.ini

[dark]
blue=#0000FF
black=#000000

[light]
yellow=#FFFF00
white=#FFFFFF

 

Link to post
Share on other sites

Hi @kurtykurtyboy.

You're welcome! I'm always happy to know people enjoy my projects :)

You don't need to call the __destructor method manually, it is all handled by AutoIt with the exception on script exit.

The object destructor function and object memory cleanup is invoked when no more references to the object exists. So for example if you overwrite your $oColors variable after your ConsoleWrite with something else, the object cleanup will run.

I see no issues with creating and assigning the objects within the loop, except you could end up allocating a lot of memory, if your ini file gets a lot bigger.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By sylremo
      I tried to implement the code in this topic:
      Firstly, i have no idea how these lines of code work but meanwhile i noticed that:
      ; Everytime autoit wants to call a method, get or set a property in a object it needs to go to ; IDispatch::GetIDsFromNames. This is our version of that function, note that by defining this ourselves ; we can fool autoit to believe that the object supports a lot of different properties/methods. Func __IDispatch_GetIDsFromNames($pSelf, $riid, $rgszNames, $cNames, $lcid, $rgDispId) ... EndFunc The problem is i ran into is that some object calls didn't go through IDispatch::GetIDsFromNames.
      Here is the code to replicate what i'm mentioning:
      I followed the example in the topic and tried to do the same thing with method .Documents (line 193) and .Open (line 194) but didn't get the same result because .Documents was being passed through __IDispatch_GetIDsFromNames while .Open didn't.
      $Au3_CallByName = 'Documents' Local $oDoc = $oAppl.Au3_CallByName $Au3_CallByName = 'Open' $oDoc = $oDoc.Au3_CallByName($sFilePath, $bConfirmConversions, $bReadOnly, $bAddToRecentFiles, $sOpenPassword, "", $bRevert, $sWritePassword, "", $iFormat) Console outputs:
      ==> The requested action with this object has failed.: $oDoc = $oDoc.Au3_CallByName($sFilePath, $bConfirmConversions, $bReadOnly, $bAddToRecentFiles, $sOpenPassword, "", $bRevert, $sWritePassword, "", $iFormat) $oDoc = $oDoc^ ERROR Is there any workarounds to solve this?

      Thank you!
    • By SEuBo
      Hi there,
      while I created an example script to generate and execute a function during runtime, I stumbled across a neat way to share data between running autoit scripts.
      This is done using the amazing magic of  AutoItObject_Internal . (You'll need at least Version 3.0.0 of AutoItObject_Internal)
      Using this UDF, you can create a shared data storage, basically an empty "AutoitObject_Internal-"Object which you can then use to write / read data Inline. no set/get methods, just
      #include "AutoItSharedData.au3" $oShare = _AutoIt_SharedData_CreateOrAttach("MyCustomID") $oShare.some_data = 'foo' and you're done. any other script accessing this data will have to do:
      #include "AutoItSharedData.au3" $oShare = _AutoIt_SharedData_CreateOrAttach("MyCustomID") ConsoleWrite($oShare.some_data & @LF)  
      Basically it's Larsj's Implementing IRunningObjectTable Interface, but you dont have a Dictionary, but an IDIspatch Object instead.
      There are already a bunch of IPC options available - and this is another one.
      AutoItSharedData.au3
       
      Example Script 1
       
      Example Script 2
      Output: 
      To test: run Example Script 1, Then run example Script 2.. or the other way around.
      Example Script 3
      Example_sharedata3.au3
      Example_sharedata3_Controlsend.au3
      Example_sharedata3_Tooltip.au3
      To test: run Example_sharedata3.au3.
      Output: 
       
       Example SharedData4:
      Output: 
      /Edit: Please note that there's a limitation with the Running object table :
      The Script accessing a variable first, will be the "server" for this variable. This means, access to that variable from other scripts should only be possible, as long the "server" script is running! Use appropriate Object Error handlers in case you don't want the surviving "clients" to crash.
      Feedback and/or improvements appreciated
       
      changelog
      version 2.0
      Removed need for AutoItObject, as AutoItObject_Internal now comes with ROT support Added UDF Header Fixed typo on "#include AutoItObjectInternal.au3" -> "#include AutoItObject_Internal.au3" Added ObjGet() after registering the object fails (in case 2 programs tried to register the same ID simultaneously) Updated Examples & zip archive. Cheers,
       
      AutoItSharedData.zip
    • By nacerbaaziz
      hello autoit team
      please
      i tried to create a SPVoice object 
      when i create the object and tried to use this function SetAlertBoundary
      it gave me an error
      please where is the problem?
      here is the code
      local $o_Sapi_OBJ = ObjCreate("SAPI.SpVoice") if IsObj($o_Sapi_OBJ) then $o_Sapi_OBJ.SetAlertBoundary("SPEI_PHONEME") endIf note i got the function name from microsoft web site
       
      https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms719784(v=vs.85)
      i have windows10
    • By Colduction
      Hi AutoIt Programmers!

      I've seen a code that gives Name of Group by writing it's group's SID, but this one response very slower than Windows Command-Line WMIC
       
      Func _GetLocalGroupName($sSID = 'S-1-5-18') $objWMIService = ObjGet ("winmgmts:\\" & @ComputerName & "\root\cimv2") $colItems = $objWMIService.ExecQuery('SELECT Name FROM Win32_Group where SID="' & $sSID & '"') For $GroupNames in $colItems MsgBox (0,"",$GroupNames.Name) ExitLoop Next EndFunc I don't want call and use any third-party programs even CMD, i just want use from Windows API, netapi32.dll or AutoIt Functions (Standalone).
      Do you have any idea to improve speed/performance of this code? I'll happy of your comments
       
       
       
      ====================== SOLOUTION by @Subz ======================
       
    • By xiantez
      This script used to work on an older version of AutoIT. Currently I am running AutoIT v3.3.14.5 and it's failing.
      Func PublicIP() ;Post public facing IP address Local $url = 'https://www.google.com/search?client=opera&q=what+is+my+ip&sourceid=opera&ie=UTF-8&oe=UTF-8' Local $getIPaddress = BinaryToString(InetRead($url)) Local $sStart = 'clamp:2">' Local $sEnd = '</div>' Local $ipaddress = _StringBetween($getIPaddress, $sStart, $sEnd For $i In $ipaddress MsgBox(0, 'External IP', "Your public IP address is " & $i) Next EndFunc ;==>PublicIP The console output shows:
      "C:\Users\user\Documents\AutoIT\Scripts\WSI Tools.au3" (197) : ==> Variable must be of type "Object".: For $i In $ipaddress For $i In $ipaddress^ ERROR ->14:12:16 AutoIt3.exe ended.rc:1 +>14:12:16 AutoIt3Wrapper Finished. >Exit code: 1 Time: 9.811
×
×
  • Create New...