Jump to content

StructBuilder


Zinthose
 Share

Recommended Posts

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

Link to comment
Share on other sites

  • 1 month later...

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()
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...