Jump to content

AutoItObject UDF


ProgAndy
 Share

Recommended Posts

That would be correct (except for the line numbers). No additional files except AutoItObject.au3 are needed to be able to use AutoItObject functions, compiled or not.

DLLS are provided for three main reasons:

  • For debugging purposes, in cases when there would be some errors happening with the code.
  • As an alternative way of loading the engine.
  • Transparency policy.
Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

  • 2 weeks later...

Yes, We have one all-in one release, but there is no option to display that. I think, we should add a comment or use "all" although there is no linux support.

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

  • 4 weeks later...

Hi. First I'd just like to extend my thanks to all who have created AutoItObject. I haven't found a use for it until just recently when I've been experimenting with the IAccessible interface (awesome way of interacting with windows).

Anyway, there seems to be a limitation in AutoItObject in that 'VT_UNKNOWN' (type #13) isn't returned as anything but an empty string. I need this to return a pointer to the IUnknown object so that I can work on one method in particular.

The definition for the method is (and this is just an excerpt from the entire definition):

"accSelection hresult(variant*);"

This returns VT_UNKNOWN half the time (I was able to verify this by tweaking the return type), so I need that pointer ('punkVal' union member).

In case you'd like a MSDN link, here it is (ignore the 'get_' part - thats not actually part of the method name): IAccessible::get_accSelection Method

This part in particular is what I'm referring to (I can figure out the IEnumVARIANT interface - I just need the IUnknown ptr):

VT_UNKNOWN Multiple child objects are selected, and the punkVal member contains the address of the IUnknown interface. The client queries this interface for the IEnumVARIANT interface, which it uses to enumerate the selected objects.

Anyway - any idea on how I can go about getting the IUnknown*? Is this a current limitation of AutoItObject? I can send someone the code I have right now if you need to see it.

Thanks for any help!

*edit: I should mention that, although IAccessible is an IDispatch interface, AutoIt itself wont handle half the methods properly, so I've had to wrap it using '_AutoItObject_WrapperCreate($pObject,$dtagIAccessible,True)'

Edited by Ascend4nt
Link to comment
Share on other sites

You are very kind.

Send it to me.

The issue seems logical since that method get you variant and AutoIt can't (or shouldn't be able to) understand VT_UNKNOWN variant. My thinking is that workaround could be to ask for pointer

"accSelection hresult(ptr*);"

...and then read the value of the variant manually:

$tVARIANT = DllStructCreate($__Au3Obj_tagVARIANT, $pReturnedPointer)
$pUnknown = DllStructGetData($tVARIANT, "data") ;<- that

edit:

IAccessible is dual interface. That means that some methods are available thru IDispatch interface, not necessarily all. Usually those that aren't available are prefixed with something + underscore.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Thanks for looking into this.

edit:

IAccessible is dual interface. That means that some methods are available thru IDispatch interface, not necessarily all. Usually those that aren't available are prefixed with something + underscore.

Hmm, didn't think of that. Many of the 'get_' methods are available through IDispatch though, so that whole naming scheme on MSDN still confuses me.

By the way - your helps alot in looking at the methods. Maybe it can be tweaked to automatically generate interfaces? I used a combination of that and the Windows SDK header files to get the vtable order, since I wasn't sure if your program outputs every interface in vtable order?

Link to comment
Share on other sites

By the way - your helps alot in looking at the methods. Maybe it can be tweaked to automatically generate interfaces? I used a combination of that and the Windows SDK header files to get the vtable order, since I wasn't sure if your program outputs every interface in vtable order?

It's in correct order. They are put there that way.

It can be modified and would be shorter code than now, but still the main issue is to properly "convert" COM datatypes to AutoIt's. And besides that, everyone can often want to choose what type to use (e.g. ptr or idispatch or variant version depending on needs).

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Hello Forum :shifty:,

I'm currently bugging around with UAC :P, looking for a way to elevate a running process to Admin (and maybe back?). Read some articles on the forum of how this is not possible, but then stumbled over from way back...

"This is not possible with AutoIt. In Delphi, you need a Com-Object do to this..."

Well... and as we have AutoItObject now I thought maybe someone with deeper knowledge could regard this as a challenge :x, honestly I couldn't implement it (now, you live and you learn :nuke:). Here's also a start at stackoverflow.com.

Edit: Two more interesting links:

http://msdn.microsoft.com/en-us/library/ms679687%28VS.85%29.aspx

http://stackoverflow.com/questions/2439757/how-can-i-automatically-elevate-a-com-interface-used-for-automation

Regards

Edited by KaFu
Link to comment
Share on other sites

  • 2 weeks later...

I extended wraithdu's calltips to include the latest functions.

Open '...\AutoIt3\SciTE\api\au3.user.calltips.api' and paste the following into it:

_AutoItObject_AddDestructor($oObject, $sAutoItFunc) Adds a destructor to an AutoIt-object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_AddEnum($oObject, $sNextFunc, $sResetFunc [, $sSkipFunc]) Adds an Enum to an AutoIt-object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_AddMethod($oObject, $sName, $sAutoItFunc [, $fPrivate]) Adds a method to an AutoIt-object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_AddProperty($oObject, $sName, $iFlags, $vData) Adds a property to an AutoIt-object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_Class() AutoItObject COM wrapper function. (Requires: #Include "AutoItObject.au3")
_AutoItObject_CLSIDFromString($sString, $tCLSID) Converts a string to a CLSID-Struct (GUID-Struct). (Requires: #Include "AutoItObject.au3")
_AutoItObject_CoCreateInstance($rclsid, $pUnkOuter, $dwClsContext, $riid, $ppv) Creates a single uninitialized object of the class associated with a specified CLSID. (Requires: #Include "AutoItObject.au3")
_AutoItObject_Create([$oParent]) Creates an AutoIt-object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_DllOpen($sDll [, $sTag [, $iFlag]]) Creates an object associated with the specified dll. (Requires: #Include "AutoItObject.au3")
_AutoItObject_DllStructCreate($sTag [, $vParam]) Object wrapper for DllStructCreate and related functions. (Requires: #Include "AutoItObject.au3")
_AutoItObject_IDispatchToPtr($oIDispatch) Returns a pointer to AutoIt's object type. (Requires: #Include "AutoItObject.au3")
_AutoItObject_IUnknownRelease($vUnknown) Decrements the reference count of an IUnknown-Object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_IUnknownAddRef($pUnknown) Increments the reference count of an IUnknown-object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_ObjCreate($sID [, $sRefId [, $tagInterface]]) Creates a reference to a COM object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_ObjCreateEx($sModule, $sID [, $sRefId [, $tagInterface [, $fWrapp]]]) Creates a reference to a COM object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_ObjectFromDtag($sFunctionPrefix, $dtagInterface [, $fNoUnknown]) Creates a custom object defined with "dtag" interface description string. (Requires: #Include "AutoItObject.au3")
_AutoItObject_PtrToIDispatch($pIDispatch) Converts IDispatch pointer to AutoIt's object type. (Requires: #Include "AutoItObject.au3")
_AutoItObject_RemoveMember($oObject, $sMember) Removes a property or a function from an AutoIt-object. (Requires: #Include "AutoItObject.au3")
_AutoItObject_Startup([$fLoadDLL [, $sDll]]) Initializes an AutoItObject. (Requires: #Include "AutoItObject.au3")
_AutoItObject_Shutdown() Frees the AutoItObject DLL. (Requires: #Include "AutoItObject.au3")
_AutoItObject_VariantClear($pvarg) Clears the value of a variant. (Requires: #Include "AutoItObject.au3")
_AutoItObject_VariantCopy($pvargDest, $pvargSrc) Copies a VARIANT to another. (Requires: #Include "AutoItObject.au3")
_AutoItObject_VariantFree($pvarg) Frees a variant created by _AutoItObject_VariantSet. (Requires: #Include "AutoItObject.au3")
_AutoItObject_VariantInit($pvarg) Initializes a variant. (Requires: #Include "AutoItObject.au3")
_AutoItObject_VariantRead($pVariant) Reads the value of a VARIANT. (Requires: #Include "AutoItObject.au3")
_AutoItObject_VariantSet($pVar, $vVal, $iSpecialType) Sets the value of a variant or creates a new one. (Requires: #Include "AutoItObject.au3")
_AutoItObject_WrapperAddMethod($oWrapper, $sReturnType, $sName, $sParamTypes, $ivtableIndex) Adds additional methods to the Wrapper-Object, e.g, if you want alternative parameter types. (Requires: #Include "AutoItObject.au3")
_AutoItObject_WrapperCreate($pUnknown, $tagInterface) Creates an IDispatch-Object for COM-Interfaces normally not supporting it. (Requires: #Include "AutoItObject.au3")

Open the following: '...\AutoIt3\SciTE\Properties\au3.UserUdfs.properties' (You may have to create this file.)

Paste the following into the file:

au3.keywords.user.udfs=_autoitobject_adddestructor _autoitobject_addenum _autoitobject_addmethod _autoitobject_addproperty _autoitobject_class \
_autoitobject_clsidfromstring _autoitobject_cocreateinstance _autoitobject_create _autoitobject_dllopen _autoitobject_dllstructcreate _autoitobject_idispatchtoptr \
_autoitobject_iunknownaddref _autoitobject_iunknownrelease _autoitobject_objcreate _autoitobject_objcreateex _autoitobject_objectfromdtag _autoitobject_ptrtoidispatch \
_autoitobject_removemember _autoitobject_shutdown _autoitobject_startup _autoitobject_variantclear _autoitobject_variantcopy _autoitobject_variantfree _autoitobject_variantinit \
_autoitobject_variantread _autoitobject_variantset _autoitobject_wrapperaddmethod _autoitobject_wrappercreate

Those with UAC may have to provide administrative permission or just move the files onto the desktop, edit them, then move them back. :)

Link to comment
Share on other sites

@KaFu: Afaik you need a properly registered COM-Object in a DLL, so you can call it as an Out-of-Proc-Service. This is not possible when using only AutoIt and this UDF.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

ProgAndy, thanks for the feedback :). My search on Google did not return any pre-compiled (open-source) dlls to use for this... but I found two interesting articles describing another method, when I find some time ;)....

http://www.xtremevbtalk.com/showthread.php?t=289099

http://www.xtremevbtalk.com/showthread.php?t=281431

Edit: Reading ProgAndys reply above again this may not work either, but I'll check it out :idiot:.

Edited by KaFu
Link to comment
Share on other sites

  • 1 month later...

Hi everyone!

Since I have somewhat little experience with objects (and zero exp with AuO) I would like some advice on something. To understand how things work I've been converting one of my scripts to use objects, but I don't know how to handle the 2 dimensional array in a good way.

Take this script as an example:

Global $Array[2][150]

For $iX = 0 To UBound($Array, 2) -1
    $Array[0][$iX] = Random(0, 1, 1)
    $Array[1][$iX] = Random(0, 1, 1)
Next

$iTimer = TimerInit()
For $iX = 0 To UBound($Array, 2) -1
    If $Array[0][$iX] <> 0 Then
        If $Array[1][$iX] <> 0 Then
            ConsoleWrite("Matched " & $iX & @CRLF)
        EndIf
    EndIf
Next
ConsoleWrite(TimerDiff($iTimer) & @CRLF)

Quick and straightforward.

And my AuO:

#include "AutoItObject.au3"
#include "oLinkedList.au3"

_AutoItObject_Startup(False)

$oObject = _Create()

For $iX = 0 To 149
    $oObject.List0.add = Random(0, 1, 1)
    $oObject.List1.add = Random(0, 1, 1)
Next

$iTimer = TimerInit()
For $iX = 0 To $oObject.List0.size -1
    If $oObject.List0.at($iX) <> 0 Then
        If $oObject.List1.at($iX) <> 0 Then
            ConsoleWrite("Matched " & $iX & @CRLF)
        EndIf
    EndIf
Next
ConsoleWrite(TimerDiff($iTimer) & @CRLF)

Func _Create()
    Local $oSelf = _AutoItObject_Create()

    _AutoItObject_AddProperty($oSelf, "List0", $ELSCOPE_READONLY, LinkedList())
    _AutoItObject_AddProperty($oSelf, "List1", $ELSCOPE_READONLY, LinkedList())

    Return $oSelf
EndFunc

The problem? AuO script is over 900 times slower!

How would one go around at "fixing" this? The Enum functionality is neat, can you do that with multiple lists at the same time? Can you make something like Enumnext/EnumReset with Methods? You can't have an array as a Property can you?

Link to comment
Share on other sites

Arrays as properties are possible, but if you store strings in them, there will be memory leaks. This is a bug in AutoIt and not AuO.

In your case, I think you should use one linked list, and store objects as members.

Also, acces by index is extremely slow in linked lists, since you have to walk through all items until the index is reached. So try to use an Enum and For In if possible.

#include "AutoItObject.au3"
#include "oLinkedList.au3"

_AutoItObject_Startup(False)

$oObject = LinkedList()

For $i = 1 To 100
    $oObject.add(_CreateListItem(Random(0, 1, 1), Random(0, 1, 1)))
Next

$iTimer = TimerInit()
$iX = 0
For $oItem In $oObject
    If $oItem.Name <> 0 And $oItem.Value <> 0 Then
            ConsoleWrite("Matched " & $iX & @CRLF)
    EndIf
    $iX += 1
Next
ConsoleWrite(TimerDiff($iTimer) & @CRLF)

Func _CreateListItem($name, $value)
    Local $oSelf = _AutoItObject_Create()

    _AutoItObject_AddProperty($oSelf, "Name", $ELSCOPE_PUBLIC, $value)
    _AutoItObject_AddProperty($oSelf, "Value", $ELSCOPE_PUBLIC, $value)

    Return $oSelf
EndFunc

If you want to store only numbers, you can use arrays, too:

#include "AutoItObject.au3"
#include "oLinkedList.au3"

_AutoItObject_Startup(False)

$oObject = LinkedList()

For $i = 1 To 100
    Dim $temp[2] = [Random(0, 1, 1), Random(0, 1, 1)]
    $oObject.add($temp)
Next

$iTimer = TimerInit()
$iX = 0
For $aItem In $oObject
    If $aItem[0] <> 0 And $aItem[1] <> 0 Then
            ConsoleWrite("Matched " & $iX & @CRLF)
    EndIf
    $iX += 1
Next
ConsoleWrite(TimerDiff($iTimer) & @CRLF)
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

I probably should have said it before, the app I'm "converting" over to AuO is Codec-Control (see my sig).

It has a 3 dimensional array ($DShowEnum) containing CLSID's, display names, third thing (I just realised maybe doesn't need to be there) read from registry, so lots of strings.

Your first example works very well, I'll implement it and see what kind of speed I get in real world usage.

Edit: Edit

Edit2: Quick question, why are you using $ELSCOPE_PUBLIC here when we are only reading the values, shouldn't it be $ELSCOPE_READONLY? Is there any benefit by going public in this case?

Edited by AdmiralAlkex
Link to comment
Share on other sites

I just use public by default. If you define that the values are not allowed to be changed, use read only.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

CodecControl 2.2.3 released using AutoItObject.

<-- link

Thank you ProgAndy for your help. You have been credited in the source for _CreateListItem() :)

Link to comment
Share on other sites

  • 3 weeks later...

New version is available 1.2.3.0.

What's new? Two functions, _AutoItObject_RegisterObject and _AutoItObject_UnregisterObject.

New function are to be used for registering your objects with the ROT (Running Object Table). This objects are available system wide, meaning you can access them form other scripts or executables. That means that you can create scripts(au3, a3x, exe) that are COM servers.

This is some possible scenario:

- you have some script code whose functionality you want to share, but maybe you don't want to share the source.

- write that script using AutoItObject and OO principles and create one or more objects that export the functions and functionality of your script thru object's methods or properties

- register objects with the ROT using some identifier

- Voila!

Other scripts create (get reference) to your object by calling _AutoItObject_ObjCreate() function by prefixing your object identifier with "cbi:" moniker. For example if you have choosen identifier to be "{D07F2CEA-696F-47CD-99A9-D31E3641169A}", others would call it like this:

$oObject = _AutoItObject_ObjCreate("cbi:{D07F2CEA-696F-47CD-99A9-D31E3641169A}")

After that they work with your object like they would with any other object running in its own process ("Shell.Application" for example).

All in all, you have to try it to feel the new power. Most certainly you don't want to miss it. It's something completely unbelievable.

New level of AutoIt, take my word on it :)

New AutoItObject or check first post.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

New version is available 1.2.3.0.

What's new? Two functions, _AutoItObject_RegisterObject and _AutoItObject_UnregisterObject.

...

This sounds amazing. :) But I don't understand so much of it. :)

If the system wide object can have methods is there a copy of the AutoIt inerpreter included in the object?

Can the object continue to exist when the script which created is is closed?

How does this protect the AutoIt source or is that not what you meant?

Does this mean that a 32 bit script could create an object that could be accessed by a 64 bit process and visa versa?

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Create an account or sign in to comment

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

Create an account

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

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...