Jump to content
Sign in to follow this  
Zinthose

StructBuilder

Recommended Posts

Zinthose

Arrays vs DllStructs

I want to create a position data type I can use to adjust/create a GUI window with that allows for some fancy work. My first idea was to use a "Scrippting.Dictionary" object but decided against it. Then I looked into using an Array to house my data but then the AutoIt documentation smacked me on the back of the head yelling, NO!

It was said that an Array contains only one datatype of the same type. But technically speaking, a Variant in AutoIt can contain anything from a number to a boolean value. So an AutoIt-Array could also contain different types, even other Arrays:

$Array[0]=1

$Array[1]=true

$Array[2]="Text"

$Array[3]=$AnotherArray

This has not been strictly forbidden in AutoIt. However, it is NOT ADVISABLE to mix different datatypes in an Array. Especially the use of an Array inside another Array will severely affect the execution speed of your script.

So I looked into the DLLStruct functions and think I have my answer and have posted my solution for my AutoIt peers to critique and use in thier scripts. ;)

; <StructBuilder.au3>

#Region - Example Script
    Dim $Position = _StructBuild( _
        "Left", 130, _
        "Top", Default, _
        "Width", "100%", _
        "Height", 0)
    
    MsgBox(4096, "_StructBuild", "Left = " & _StructGetData($Position, "Left"))
    MsgBox(4096, "_StructBuild", "Top = " & _StructGetData($Position, "Top"))
    MsgBox(4096, "_StructBuild", "Width = " & _StructGetData($Position, "Width"))
    MsgBox(4096, "_StructBuild", "Height = " & _StructGetData($Position, "Height"))
#EndRegion


; #FUNCTION# ====================================================================================================================
; Name...........: _StructBuild
; Description ...: Build a data structure from supplied data.
; Syntax.........: _StructBuild ( "Name", "Value"[, "Name1", "Value1" [, "Name n", "Value n"]] )
; ===============================================================================================================================
Func _StructBuild($Name1, $Value1, $Name2 = Default, $Value2 = Default, $Name3 = Default, $Value3 = Default, $Name4 = Default, $Value4 = Default, $Name5 = Default, $Value5 = Default, $Name6 = Default, $Value6 = Default, $Name7 = Default, $Value7 = Default, $Name8 = Default, $Value8 = Default, $Name9 = Default, $Value9 = Default, $Name10 = Default, $Value10 = Default, $Name11 = Default, $Value11 = Default, $Name12 = Default, $Value12 = Default, $Name13 = Default, $Value13 = Default, $Name14 = Default, $Value14 = Default, $Name15 = Default, $Value15 = Default, $Name16 = Default, $Value16 = Default)
    Local $i, $Value, $Type, $Struct = "", $Name
    
    If Mod(@NUMPARAMS, 2) <> 0 Then Return SetError(1, 0, 0)
    
    ;## Build the DLL Struct
    For $i = 1 to @NUMPARAMS / 2
        $Value = Eval("Value" & $i)
        $Name = Eval("Name" & $i)
        
        $Type = VarGetType($Value)
        
        If $Struct <> "" Then $Struct &= ";"
        
        ;## Identify the value data type and add to the Structure string
        Switch $Type
            Case "Int32"
                $Struct &= "int " & $Name
            Case "Int64"
                $Struct &= "int64 " & $Name
            Case "Keyword"
                $Struct &= "char " & $Name & "[" & StringLen(String($Value)) + 10 & "]"
            Case "String"
                $Struct &= "char " & $Name & "[" & StringLen(String($Value)) * 3 & "]"
            Case "Double"
                $Struct &= "double " & $Name
            Case "Bool"
                $Struct &= "int " & $Name
            Case "Array"
                ConsoleWriteError("! _StructBuild: Arrays are not Supported at this time. " & $Name & "[" & $Type & "]=" & $Value & @CRLF)
                Return SetError(2, 0, 0)
            Case "Ptr"
                If IsHWnd($Value) Then
                    $Struct &= "hwnd " & $Name
                Else
                    $Struct &= "ptr " & $Name
                EndIf
            Case "Binary"
                ConsoleWriteError("! _StructBuild: Binary is not Supported at this time. " & $Name & "[" & $Type & "]=" & $Value & @CRLF)
                Return SetError(2, 0, 0)
            Case "DllStruct"
                $Struct &= "ptr " & $Name
            Case Else
                ConsoleWriteError("! _StructBuild: Unknown Parameter value type supplied. " & $Name & "[" & $Type & "]=" & $Value & @CRLF)
                Return SetError(2, 0, 0)
        EndSwitch
    Next
    
    $Struct = DllStructCreate($Struct)
    $Err = @error
    If $Err Then 
        ConsoleWriteError('! _StructBuild: [' & $Err & ']Unable to create Struct. "' & $Struct & '"' & @CRLF)
        Return SetError(4, $Err, 0)
    EndIf
    
    ;## Populate the DLLStruct with Data
    For $i = 1 to @NUMPARAMS / 2
        $Value = Eval("Value" & $i)
        $Name = Eval("Name" & $i)
        $Type = VarGetType($Value)
        
        ;## Handle any special data conversion
        Switch $Type
            Case "Keyword"
                $Value = Chr(2) & String($Value)
            Case "Bool"
                $Value = Int($Value)
        EndSwitch
        
        ;## Set the value in the structure
        DllStructSetData($Struct, $Name, $Value)
        $Err = @error
        If $Err Then 
            ConsoleWriteError('! _StructBuild: [' & $Err & ']Unable to assign Struct value. ' & $Name & '=' & $Value & @CRLF)
            Return SetError(5, $Err, 0)
        EndIf
    Next
    
    ;## Structure creation/population completed successfully!
    Return $Struct
EndFunc


; #FUNCTION# ====================================================================================================================
; Name...........: _StructGetData
; Description ...: Gets the data from a previously built structure.
; Syntax.........: _StructGetData ( Struct, Element [, Index]] )
; ===============================================================================================================================
Func _StructGetData($Struct, $Element, $Index = Default)
    Local $Value, $Type
    
    If $Index = Default Then
        $Value = DllStructGetData($Position, $Element)
    Else
        $Value = DllStructGetData($Position, $Element, $Index)
    EndIf
    
    $Err = @error
    If $Err Then 
        ConsoleWriteError('! _StructGetData: [' & $Err & ']Get struct value. ' & $Element & '[' & $Index & ']' & @CRLF)
        Return SetError(1, $Err, 0)
    EndIf
    
    $Type = VarGetType($Value)
    
    Switch $Type
        Case "String"
            If StringMid($Value, 1, 1) = Chr(2) Then $Value = Execute(StringMid($Value, 2))
;~      Case Else 
;~          ConsoleWriteError('! _StructGetData: TODO - Add additional type convertors' & @CRLF)
    EndSwitch
    
    Return $Value
EndFunc

--- TTFN

Share this post


Link to post
Share on other sites
WeMartiansAreFriendly

Very interesting concept!

But I have to ask what benefits this has over Arrays..? Is it faster, Is there no size limit?

.. However, it is NOT ADVISABLE to mix different datatypes in an Array. Especially the use of an Array inside another Array will severely affect the execution speed of your script.

Hmm.. :P

[Edit]

This does vastly simplify the process of creating dllstructs at least.

Edited by mrRevoked

Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()

Share this post


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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.