AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

ahkstructlib - Functions for use with Structures (version 2)
Goto page Previous  1, 2, 3, 4, 5
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
corrupt



Joined: 29 Dec 2004
Posts: 2485

PostPosted: Wed Jun 13, 2007 5:05 am    Post subject: Reply with quote

Titan wrote:
It is much slower and more complex than simple variable assignments.
It's actually very straight forward and mainly only consists of simple variable assignments but likely looks like it's doing more than it does. The main loss in speed is currently a lookup on the name to determine the offset that should be used. If the next version goes as planned though, it will likely perform a lot faster for member name lookups .

Titan wrote:
corrupt wrote:
What functionality is lost?
Pseudo array functions like Sort, Parsing loops, StringSplit and enumerations for example.
Nothing should end up being lost with this method vs the other method(s) available. These functions still create/modify the same struct format as the other methods. The output can be used the same way. You can actually mix and match methods if you feel the need to. Could you please give a specific example of something that you'd like to be able to do tat's not currently possible?

Titan wrote:
corrupt wrote:
CMDret and a few others will be updated to use the new numspagetti and numnuts functions, callbacks and other...
Great, they'll be useful examples to learn from.
Hopefully. There's always the chance that they'll end up being good examples on what not to learn from too though. The next (possibly final) version of CMDret should be interesting though...
Back to top
View user's profile Send private message Visit poster's website
corrupt



Joined: 29 Dec 2004
Posts: 2485

PostPosted: Sun Jun 01, 2008 5:14 pm    Post subject: Re: ahkstructlib - Functions for use with Structures (versio Reply with quote

Updated to version 2.02
- fixed a bug with the "As" syntax that would cause a struct to be created with an incorrect size in some cases - Thanks usernSC
Back to top
View user's profile Send private message Visit poster's website
Joy2DWorld



Joined: 04 Dec 2006
Posts: 561
Location: Galil, Israel

PostPosted: Tue Jul 08, 2008 1:49 pm    Post subject: Reply with quote

cool stuff.

minor suggests,

like keeping all functions within the "struct_" domain,

avoiding "?" (a function itself),

etc..


if helpful for anyone (save as struct.ahk in lib directory, no need to worry about '#includes').
Code:
; *********************************
; w/ tiny mods as to naming... J2DW
;
; AHK Function Library - Structures
; Version 2.02
; - by Corrupt
; - Updated June 1, 2008
; *********************************
;
; *********************************
;  Comments, suggestions, etc... welcome :)
; *********************************
;
; *********************************
; Create a new structure
; *********************************
; Params: "Structure Name", "VarType", "VarName", "Type", "Name", etc...
; - Currently a maximum of 32 variables in a structure is supported
;   (to add support for more, add to the list below)
;
; Optional alternate syntax allowed: "Structure Name", "VarName As Type", "VarName As Type", ...
; - mixing of the 2 different syntax styles in the same call is not currently supported
; *********************************
Struct_Build(struct_name ,s_type1, s_var1 ,s_type2="", s_var2="" ,s_type3="", s_var3=""
   ,s_type4="" , s_var4=""  ,s_type5="" , s_var5=""  ,s_type6="" , s_var6=""  ,s_type7="" , s_var7=""
   ,s_type8="" , s_var8=""  ,s_type9="" , s_var9=""  ,s_type10="", s_var10="" ,s_type11="", s_var11=""
   ,s_type12="", s_var12="" ,s_type13="", s_var13="" ,s_type14="", s_var14="" ,s_type15="", s_var15=""
   ,s_type16="", s_var16="" ,s_type17="", s_var17="" ,s_type18="", s_var18="" ,s_type19="", s_var19=""
   ,s_type20="", s_var20="" ,s_type21="", s_var21="" ,s_type22="", s_var22="" ,s_type23="", s_var23=""
   ,s_type24="", s_var24="" ,s_type25="", s_var25="" ,s_type26="", s_var26="" ,s_type27="", s_var27=""
   ,s_type28="", s_var28="" ,s_type29="", s_var29="" ,s_type30="", s_var30="" ,s_type31="", s_var31=""
   ,s_type32="", s_var32="") {
  Global
  Local struct_sizeA, struct_sizeB, struct_temp1, struct_temp2, struct_temp3, struct_temp4
      , struct_temp40, struct_temp41, struct_temp42, struct_temp5, struct_temp6, struct_templast
  struct_sizeA = 0
  If (!A_AhkScriptProcessID) {
    Process, Exist
    A_AhkScriptProcessID = %ErrorLevel%i
  }
  struct_temp3 = %struct_name%_%A_AhkScriptProcessID%
  %struct_name%= init
  %struct_name%=
  ; Process elements
  Loop, 32 {
    struct_temp42 := s_type%A_Index%
    struct_temp41 := s_var%A_Index%
    struct_temp5 = 1
    ; check for As syntax
    StringReplace, struct_temp42, struct_temp42, %A_Tab%, %A_Space%, All
    If (InStr(struct_temp42, " as ")) {
      StringReplace, struct_temp42, struct_temp42, %A_Space%As%A_Space%, `,
      struct_temp4 = %struct_temp42%
      StringSplit, struct_temp4, struct_temp4, `,, %A_Space%
      struct_temp4 := s_var%A_Index%
      struct_temp5 = 2
    }
    Loop, %struct_temp5%
    {
      If (A_Index = "2") {
        struct_temp41 = %struct_temp4%
        StringReplace, struct_temp41, struct_temp41, %A_Tab%, %A_Space%, All
        StringReplace, struct_temp41, struct_temp41, %A_Space%As%A_Space%, `,
        struct_temp4 = %struct_temp41%
        StringSplit, struct_temp4, struct_temp4, `,, %A_Space%
      }
      ; Check Type (u - unsigned, p - pointer)
      If (struct_temp42="Int" OR struct_temp42="long")
        struct_temp2 = 4
      Else If (struct_temp42="UInt" OR struct_temp42="dword" OR struct_temp42="hwnd")
        struct_temp2 = 4u
      Else If (struct_temp42="Str")
        struct_temp2 = 4up
      Else If (struct_temp42="Short")
        struct_temp2 = 2
      Else If (struct_temp42="UShort" OR struct_temp42="word")
        struct_temp2 = 2u
      Else If (struct_temp42="UChar" OR struct_temp42="byte")
        struct_temp2 = 1u
      Else If (struct_temp42="Char")
        struct_temp2 = 1
      Else If (struct_temp42="Int64")
        struct_temp2 = 8
      Else If (struct_temp42="UInt64")
        struct_temp2 = 8u
      Else
        struct_temp2 = 4p
      If struct_temp41=
      {
        struct_temp6 = 1
        break
      }
      ; ** Create variables **
      ;
      struct_temp1 := "#" . struct_temp41
      If (!InStr(struct_temp2, "p"))
        %struct_name%%struct_temp1% = 0
      Else {
        %struct_name%%struct_temp1%=init
        %struct_name%%struct_temp1%=
      }
      ; ** Create reference **
      %struct_temp3% := %struct_temp3% . struct_temp2 . ":" . struct_temp41 "|"
      struct_sizeA += struct_temp2
    }
    If (struct_temp6)
      break
  }
  VarSetCapacity(%struct_name%, struct_sizeA, 0)
Return, True
}


; *********************************
; Retrieve a value from the structure
; *********************************
; Params: struct_name or struct#varname
; - specifying struct_name will retrieve/update values for all variables in the structure
; - specifying struct#varname will retrieve/update only the variable specified   
; *********************************
struct_get(s_query)
{
  Global
  Local struct_sizeA, struct_sizeB, struct_temp1, struct_temp2, struct_temp3, struct_temp4, struct_temp5,struct_temp6, struct_temp0, struct_temp00, struct_temp01, struct_temp02
  StringSplit, struct_temp, s_query, #
  struct_temp3 = %struct_temp1%_%A_AhkScriptProcessID%
  If (!%struct_temp3%) {
    VarSetCapacity(%struct_temp3%, 0)
    ErrorLevel = Invalid_Struct
    Return
  }
  struct_sizeA = 0
  Loop, Parse, %struct_temp3%, |
  {
    StringSplit, struct_temp0, A_LoopField, :
    If struct_temp00 = 0
      break
    struct_sizeA += struct_temp01
    struct_temp4 := !InStr(struct_temp01, "u")
    struct_sizeB = %struct_temp01%
    EnvAdd, struct_temp01, 0
    If (struct_temp02 = struct_temp2 OR struct_temp2 = "") {
      struct_temp5 := Struct_ExtractIntegerSL(%struct_temp1%, (struct_sizeA - struct_temp01), !InStr(struct_temp01, "u"), struct_temp01)
      If (InStr(struct_sizeB, "p"))
        DllCall("lstrcpyA", "Str", %struct_temp1%#%struct_temp02%, "UInt", struct_temp5)
      Else
        %struct_temp1%#%struct_temp02% = %struct_temp5%
      If (struct_temp02 = struct_temp2)
        Return, %struct_temp1%#%struct_temp02%
    }
  }
  Return
}

; *********************************
; Send a value to the structure
; *********************************
; Params: struct_name or struct#varname
; - specifying struct_name will send/update values from all variables in the structure
; - specifying struct#varname will send/update only the variable specified   
; *********************************

struct_set(s_modify, s_value="")
{
  Global
  Local struct_sizeA, struct_sizeB, struct_temp1, struct_temp2, struct_temp3, struct_temp4, struct_temp0
  StringSplit, struct_temp, s_modify, #
  struct_temp3 = %struct_temp1%_%A_AhkScriptProcessID%
  If (!%struct_temp3%) {
    VarSetCapacity(%struct_temp3%, 0)
    ErrorLevel = Invalid_Struct
    Return
  }
  struct_sizeA = 0
  Loop, Parse, %struct_temp3%, |
  {
    Loop, Parse, A_LoopField, :
    {
      If (A_Index = "1") {
        struct_sizeA += A_LoopField
        struct_sizeB = %A_LoopField%
        struct_temp4 = %A_LoopField%
        EnvAdd, struct_sizeB, 0
      }
      Else {
        If (A_LoopField = struct_temp2 OR struct_temp2="") {
          If struct_temp2<>
            %struct_temp1%#%A_LoopField% = %s_value%
          If (InStr(struct_temp4, "p"))
            Struct_InsertIntegerSL(&%struct_temp1%#%A_LoopField%, %struct_temp1%, (struct_sizeA - struct_sizeB),struct_sizeB)
          Else
            Struct_InsertIntegerSL(%struct_temp1%#%A_LoopField%, %struct_temp1%, (struct_sizeA - struct_sizeB),struct_sizeB)
        }
      }
    }
  }
Return
}

; *********************************
; Required functions - ExtractInteger, InsertInteger
; - original versions from Version 1.0.44.06 of the AutoHotkey help file
; by Chris Mallett
; // Renamed in case someone is using a modified version of these functions
; // somewhere else in their code
; *********************************
Struct_ExtractIntegerSL(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
; pSource is a string (buffer) whose memory area contains a raw/binary integer at pOffset.
; The caller should pass true for pSigned to interpret the result as signed vs. unsigned.
; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int).
; pSource must be ByRef to avoid corruption during the formal-to-actual copying process
; (since pSource might contain valid data beyond its first binary zero).
{
   Loop %pSize%  ; Build the integer by adding up its bytes.
      result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1)
   if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
      return result  ; Signed vs. unsigned doesn't matter in these cases.
   ; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
   return -(0xFFFFFFFF - result + 1)
}
; *********************************
Struct_InsertIntegerSL(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; The caller must ensure that pDest has sufficient capacity.  To preserve any existing contents in pDest,
; only pSize number of bytes starting at pOffset are altered in it.
{
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
      DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
}
; *********************************


with struct_set and struct_get inplace of struct? and struct@. (if you go back and read code months after written, small stuff like that can make difference sometimes.


if helpful the cool demo with changed funct. naming:

Code:
;
; Chalkboard demo
; - hold down mouse1 to draw on the window
; - click mouse3 to clear
; *********************************
Gui, Show, w400 h400, Chalkboard Demo
Gui + LastFound
g1 := WinExist()
Struct_Build("Rect", "Int", "Left", "Int", "Top", "Int", "Right", "Int", "Bottom")
CoordMode, Mouse, Relative
OnMessage(0x200, "WM_MOUSEMOVE")
OnMessage(0x204, "WM_RBUTTONDOWN")
HS_DIAGCROSS := 5
Return

WM_RBUTTONDOWN(wParam, lParam)
{
  WinSet, Redraw
}

GuiClose:
ExitApp

WM_MOUSEMOVE(wParam, lParam)
{
  Global
  MouseGetPos, POINTAPI#X, POINTAPI#Y, OutputVarWin
  If (OutputVarWin = g1 AND GetKeyState("LBUTTON", "P"))
  {
    Rect#Left := POINTAPI#X - 5
    Rect#Top := POINTAPI#Y - 30
    Rect#Right := POINTAPI#X + 5
    Rect#Bottom := POINTAPI#Y - 20
    struct_set("Rect")
    hDC := DllCall("GetDC", "UInt", g1)
    hBrush := DllCall("CreateHatchBrush", "UInt", HS_DIAGCROSS, "UInt", 0xFF00CC)
    DllCall("FillRect", "UInt", hDC, "Str", Rect, "UInt", hBrush)
    DllCall("ReleaseDC", "UInt", g1, "UInt", hDC)
    DllCall("DeleteObject", "UInt", hBrush)
  }
  Return
}

_________________
Joyce Jamce
Back to top
View user's profile Send private message
Guest






PostPosted: Tue Jul 08, 2008 6:19 pm    Post subject: Re: ahkstructlib - Functions for use with Structures (versio Reply with quote

corrupt...ExtractIntegerSL -> NumGet & InsertIntegerSL -> NumPut???...or do your functions still really do something different than the new built-ins?

Is this the most current way to handle structs?

What about structs that DON'T use the default 4-byte/bit DWORD but use 2-byte/bit WORD?

What about structs-in-structs or unions-in-structs?...(wtf is a union anyway? {I know, I'll go Google now})...

Is lexikos's solution better?

Also...struct@ -> struct_set, struct? -> struct_get...abusing AutoHotkey's loose var/function naming is bad...we need ? for ternary (& not <space><question-mark><space> ternary)...not sure if we need @ for something, but I'd keep vars/functions limited to whatever works in JavaScript...
Back to top
Joy2DWorld



Joined: 04 Dec 2006
Posts: 561
Location: Galil, Israel

PostPosted: Tue Jul 08, 2008 10:03 pm    Post subject: Re: ahkstructlib - Functions for use with Structures (versio Reply with quote

Anonymous wrote:

Also...struct@ -> struct_set, struct? -> struct_get...abusing AutoHotkey's loose var/function naming is bad..


hey, nothing is bad if it works!

having lib function that is self contained.. ie. all functions & vars within the lib ahk all start with LIBNAME_ gives 100% assurance that ALL libs will not interfere with any other Lib...
_________________
Joyce Jamce
Back to top
View user's profile Send private message
corrupt



Joined: 29 Dec 2004
Posts: 2485

PostPosted: Sat Nov 22, 2008 11:27 pm    Post subject: Re: ahkstructlib - Functions for use with Structures (versio Reply with quote

Anonymous wrote:
corrupt...ExtractIntegerSL -> NumGet & InsertIntegerSL -> NumPut???...or do your functions still really do something different than the new built-ins?
No, but they accept params a bit differently that will require additional modifications...

Anonymous wrote:
What about structs that DON'T use the default 4-byte/bit DWORD but use 2-byte/bit WORD?
Specify word instead of dword for word params? or please explain...

Anonymous wrote:
What about structs-in-structs or unions-in-structs?...(wtf is a union anyway? {I know, I'll go Google now})...
Structs in structs are supported. The struct param. inside a larger struct is a reference (pointer to the other struct).

Anonymous wrote:
Also...struct@ -> struct_set, struct? -> struct_get...
This has been changed in the next version - which I'll likely release soon in case anyone finds it useful.

Thanks for the feedback Smile
Back to top
View user's profile Send private message Visit poster's website
corrupt



Joined: 29 Dec 2004
Posts: 2485

PostPosted: Sat Nov 22, 2008 11:28 pm    Post subject: Re: ahkstructlib - Functions for use with Structures (versio Reply with quote

Joy2DWorld wrote:
hey, nothing is bad if it works!
Very Happy
Back to top
View user's profile Send private message Visit poster's website
corrupt



Joined: 29 Dec 2004
Posts: 2485

PostPosted: Mon Nov 24, 2008 3:00 am    Post subject: Reply with quote

Beta version 2.03

- NumGet/NumPut used instead of Insert/Extract Integer functions
- internal changes to type/size formatting (not compatible to mix/match with functions from previous versions)
- function names changed (future compatibility?)
- Std library compatible
- other misc. changes...

Syntax changes
cStruct_Create() - same functionality as previous StructCreate()
cStruct_Get() - same functionality as previous Struct?()
cStruct_Set() - same functionality as previous Struct@()
cStruct_Enum() - same functionality as previous Struct_enum()

The usage of this version should be the same as the previous version with the exception of the function name changes.

As always, feedback, suggestions, bug reports, etc... welcome Smile

To try this version you can either Download version 2.03 or copy/paste the following code (Suggested filename: cStruct.ahk)
Code:
; *********************************
; version 2.03
; - November 23, 2008 - corrupt
; *********************************
; Create a new struct
; *********************************
; Params: "Structure Name", "VarType", "VarName", "Type", "Name", etc...
; - Currently a maximum of 32 variables in a structure is supported
;   (to add support for more, add to the list below)
;
; Optional alternate syntax allowed: "Structure Name", "VarName As Type", "VarName As Type", ...
; - mixing of the 2 different syntax styles in the same call is not currently supported
; *********************************

cStruct_Create(struct_name ,s_type1, s_var1 ,s_type2="", s_var2="" ,s_type3="", s_var3=""
,s_type4="" , s_var4=""  ,s_type5="" , s_var5=""  ,s_type6="" , s_var6=""  ,s_type7="" , s_var7=""
,s_type8="" , s_var8=""  ,s_type9="" , s_var9=""  ,s_type10="", s_var10="" ,s_type11="", s_var11=""
,s_type12="", s_var12="" ,s_type13="", s_var13="" ,s_type14="", s_var14="" ,s_type15="", s_var15=""
,s_type16="", s_var16="" ,s_type17="", s_var17="" ,s_type18="", s_var18="" ,s_type19="", s_var19=""
,s_type20="", s_var20="" ,s_type21="", s_var21="" ,s_type22="", s_var22="" ,s_type23="", s_var23=""
,s_type24="", s_var24="" ,s_type25="", s_var25="" ,s_type26="", s_var26="" ,s_type27="", s_var27=""
,s_type28="", s_var28="" ,s_type29="", s_var29="" ,s_type30="", s_var30="" ,s_type31="", s_var31=""
,s_type32="", s_var32=""){
  Global
  Local struct_sizeA, struct_sizeB, struct_temp1, struct_temp2, struct_temp3, struct_temp4
  , struct_temp40, struct_temp41, struct_temp42, struct_temp5, struct_temp6, struct_templast
  struct_sizeA = 0
  Local Static Int = 4
  Local Static UInt = 4
  Local Static Str = 4
  Local Static Short = 2
  Local Static Ushort = 2
  Local Static Uchar = 1
  Local Static Char = 1
  Local Static Int64 = 8
  Local Static UInt64 = 8 

  If (!A_AhkScriptProcessID) {
    Process, Exist
    A_AhkScriptProcessID = %ErrorLevel%i
  }
  struct_temp3 = %struct_name%_%A_AhkScriptProcessID%
  %struct_name%= init
  %struct_name%=
  ; Process elements
  Loop, 32 {
    struct_temp42 := s_type%A_Index%
    struct_temp41 := s_var%A_Index%
    struct_temp5 = 1
    ; check for As syntax
    StringReplace, struct_temp42, struct_temp42, %A_Tab%, %A_Space%, All
    If (InStr(struct_temp42, " as ")) {
      StringReplace, struct_temp42, struct_temp42, %A_Space%As%A_Space%, `,
      struct_temp4 = %struct_temp42%
      StringSplit, struct_temp4, struct_temp4, `,, %A_Space%
      struct_temp4 := s_var%A_Index%
      struct_temp5 = 2
    }
    Loop, %struct_temp5%
    {
      If (A_Index = "2") {
        struct_temp41 = %struct_temp4%
        StringReplace, struct_temp41, struct_temp41, %A_Tab%, %A_Space%, All
        StringReplace, struct_temp41, struct_temp41, %A_Space%As%A_Space%, `,
        struct_temp4 = %struct_temp41%
        StringSplit, struct_temp4, struct_temp4, `,, %A_Space%
      }
      ; Check Type (u - unsigned, p - pointer)
      If (struct_temp42="Int" OR struct_temp42="long" OR struct_temp42="4")
        struct_temp2 = Int
      Else If (struct_temp42="dword" OR struct_temp42="hwnd" OR struct_temp42="4u")
        struct_temp2 = UInt
      Else If (struct_temp42="4up")
        struct_temp2 = Str
      Else If (struct_temp42="2")
        struct_temp2 = Short
      Else If (struct_temp42="word" OR struct_temp42="2u")
        struct_temp2 = Ushort
      Else If (struct_temp42="byte" OR struct_temp42="1u")
        struct_temp2 = Uchar
      Else If (struct_temp42="1")
        struct_temp2 = Char
      Else If (struct_temp42="8")
        struct_temp2 = Int64
      Else If (struct_temp42="8u")
        struct_temp2 = UInt64
      Else
        struct_temp2 = %struct_temp42%
      If struct_temp2 =
        struct_temp2 = Int
      If struct_temp41=
      {
        struct_temp6 = 1
        break
      }
      ; ** Create variables **
      struct_temp1 := "?" . struct_temp41
      If (!InStr(struct_temp2, "p"))
        %struct_name%%struct_temp1% = 0
      Else {
        %struct_name%%struct_temp1%=init
        %struct_name%%struct_temp1%=
      }
      ; ** Create reference **
      %struct_temp3% := %struct_temp3% . struct_temp2 . ":" . struct_temp41 "|"
      struct_sizeA += (%struct_temp2%)
    }
    If (struct_temp6)
      break
  }
  VarSetCapacity(%struct_name%, struct_sizeA, 0)
Return, True
}


; *********************************
; Retrieve a value from the structure
; *********************************
; Params: struct_name or struct?varname
; - specifying struct_name will retrieve/update values for all variables in the structure
; - specifying struct?varname will retrieve/update only the variable specified   
; *********************************
cStruct_Get(s_query)
{
  Global
  Local struct_sizeA, struct_sizeB, struct_temp1, struct_temp2, struct_temp3, struct_temp4, struct_temp5, struct_temp6
  , struct_temp0, struct_temp00, struct_temp01, struct_temp02
  Local Static Int = 4
  Local Static UInt = 4
  Local Static Str = 4
  Local Static Short = 2
  Local Static Ushort = 2
  Local Static Uchar = 1
  Local Static Char = 1
  Local Static Int64 = 8
  Local Static UInt64 = 8
  Local Static df_lstrcpyA 
  If !(df_lstrcpyA)
    df_lstrcpyA := DllCall("GetProcAddress", uint, DllCall("GetModuleHandle", str, "kernel32"), str, "lstrcpyA")
  StringSplit, struct_temp, s_query, ?
  struct_temp3 = %struct_temp1%_%A_AhkScriptProcessID%
  If (!%struct_temp3%) {
    VarSetCapacity(%struct_temp3%, 0)
    ErrorLevel = Invalid_Struct
    Return
  }

  struct_sizeA = 0
  Loop, Parse, %struct_temp3%, |
  {
    StringSplit, struct_temp0, A_LoopField, :
    If struct_temp00=
      break
    struct_sizeA += (%struct_temp01%)
    struct_sizeB :=  (%struct_temp01%)
    struct_temp4 = %struct_temp01%
    EnvAdd, struct_temp01, 0
    If (struct_temp02 = struct_temp2 OR struct_temp2 = "") {
      struct_temp5 := NumGet(%struct_temp1%, (struct_sizeA - struct_sizeB), %struct_temp01%)
      If (InStr(struct_temp4, "Str")) {
        DllCall(df_lstrcpyA, "Str", %struct_temp1%?%struct_temp02%, "UInt", struct_temp5)
      }
      Else
        %struct_temp1%?%struct_temp02% = %struct_temp5%
      If (struct_temp02 = struct_temp2)
        Return, %struct_temp1%?%struct_temp02%
      struct_temp02=
    }
  }
  Return
}

; *********************************
; Send a value to the structure
; *********************************
; Params: struct_name or struct?varname
; - specifying struct_name will send/update values from all variables in the structure
; - specifying struct?varname will send/update only the variable specified   
; *********************************

cStruct_Set(s_modify, s_value="")
{
  Global
  Local struct_sizeA, struct_sizeB, struct_temp1, struct_temp2, struct_temp3, struct_temp4, struct_temp0
  Local Static Int = 4
  Local Static UInt = 4
  Local Static Str = 4
  Local Static Short = 2
  Local Static Ushort = 2
  Local Static Uchar = 1
  Local Static Char = 1
  Local Static Int64 = 8
  Local Static UInt64 = 8 
  StringSplit, struct_temp, s_modify, ?
  struct_temp3 = %struct_temp1%_%A_AhkScriptProcessID%
  If (!%struct_temp3%) {
    VarSetCapacity(%struct_temp3%, 0)
    ErrorLevel = Invalid_Struct
    Return
  }
  struct_sizeA = 0
  Loop, Parse, %struct_temp3%, |
  {
    Loop, Parse, A_LoopField, :
    {
      If (A_Index = "1") {
        struct_sizeA += (%A_LoopField%)
        struct_sizeB := (%A_LoopField%)
        struct_temp4 = %A_LoopField%
        EnvAdd, struct_sizeB, 0
      }
      Else {
        If (A_LoopField = struct_temp2 OR struct_temp2="") {
          If struct_temp2<>
            %struct_temp1%?%A_LoopField% = %s_value%
          If (InStr(struct_temp4, "Str"))
            NumPut(&(%struct_temp1%?%A_LoopField%), %struct_temp1%, (struct_sizeA - struct_sizeB), struct_sizeB)
          Else
            NumPut(%struct_temp1%?%A_LoopField%, %struct_temp1%, (struct_sizeA - struct_sizeB), struct_sizeB)
       }
      }
    }
  }
Return
}

; *********************************
; Debug plugin
; *********************************
; AHK Function Library - Structures
; Version 2.03
; November 23, 2008 - corrupt
; *********************************

; *********************************
; Retrieve a list of all variable names and values in a structure
; *********************************
; "StructName", "DelimChar", "V"
; - DelimChar may be character(s) to use to separate variable and value
; - The info for each variable is separated by a `n character
; - This function retrieves the values stored in the structure by default.
; "V" can be specified as the 3rd param to retrieve the values from the
; associated variables instead.
; *********************************
cStruct_Enum(s_query, struct_delim2="", struct_local="")
{
  Global
  Local struct_sizeA, struct_sizeB, struct_temp1, struct_temp2, struct_temp3, struct_temp4, struct_temp5, struct_temp6
  , struct_temp0, struct_temp00, struct_temp01, struct_temp02, struct_temp7, struct_temp8
  Local Static Int = 4
  Local Static UInt = 4
  Local Static Str = 4
  Local Static Short = 2
  Local Static Ushort = 2
  Local Static Uchar = 1
  Local Static Char = 1
  Local Static Int64 = 8
  Local Static UInt64 = 8
  Local Static df_RtlMoveMemory
  If !(df_RtlMoveMemory)
    df_RtlMoveMemory := DllCall("GetProcAddress", uint, DllCall("GetModuleHandle", str, "kernel32"), str, "RtlMoveMemory")
  StringSplit, struct_temp, s_query, ?
  struct_temp3 = %struct_temp1%_%A_AhkScriptProcessID%
  If (!%struct_temp3%) {
    VarSetCapacity(%struct_temp3%, 0)
    ErrorLevel = Invalid_Struct
    Return
  }
  If struct_delim2=
    struct_delim2 = `=
  struct_sizeA = 0
  Loop, Parse, %struct_temp3%, |
  {
    StringSplit, struct_temp0, A_LoopField, :
    If struct_temp00 = 0
      break
    struct_sizeA += (%struct_temp01%)
    struct_sizeB :=  (%struct_temp01%)
    struct_temp4 = %struct_temp01%
    EnvAdd, struct_temp01, 0
    If struct_local = V
      struct_temp5 := %struct_temp1%?%struct_temp02%
    Else {
      struct_temp5 := NumGet(%struct_temp1%, (struct_sizeA - struct_sizeB), %struct_temp01%)
      If (InStr(struct_temp4, "Str")) {
                struct_temp7 = %struct_temp5%
        struct_temp8 := DllCall("lstrlen", "UInt", struct_temp7)
        VarSetCapacity(struct_temp5, struct_temp8, 0)
        DllCall("RtlMoveMemory", "Str", struct_temp5, "UInt", struct_temp7, "Int", struct_temp8)
      }
    }
    struct_temp6 = %struct_temp6%`n%struct_temp02%%struct_delim2%%struct_temp5%
  }
  Return, struct_temp6
}
; *********************************
Back to top
View user's profile Send private message Visit poster's website
corrupt



Joined: 29 Dec 2004
Posts: 2485

PostPosted: Mon Nov 24, 2008 3:05 am    Post subject: Reply with quote

Updated demo scripts:
Code:

; *********************************
; GlobalMemoryStatus Demo
; *********************************

cStruct_Create("MEMORYSTATUS"
, "dwLength         as long"
, "dwMemoryLoad      as long"
, "dwTotalPhys      as long"
, "dwAvailPhys      as long"
, "dwTotalPageFile   as long"
, "dwAvailPageFile   as long"
, "dwTotalVirtual   as long"
, "dwAvailVirtual   as long")

MsgBox, 64, Memory Stats, % GlobalMemoryStatus("MEMORYSTATUS")
Return


; ***************************************************************
; here's a wrapper for the wrapper to further simplify multiple
; calls throughout the code if necessary...
; ***************************************************************
GlobalMemoryStatus(MEMORYSTATUS_STRUCT)
{
  cStruct_set(MEMORYSTATUS_STRUCT) ; dynamically called before
  DllCall("GlobalMemoryStatus", "Str", %MEMORYSTATUS_STRUCT%)
  cStruct_get(MEMORYSTATUS_STRUCT) ; dynamically called and after DllCall line
  ; calculate and format the output for this example (optional past this line)
  %MEMORYSTATUS_STRUCT%?dwTotalPhys       :=   Round(%MEMORYSTATUS_STRUCT%?dwTotalPhys / 1024 / 1024, 2)
  %MEMORYSTATUS_STRUCT%?dwAvailPhys       :=   Round(%MEMORYSTATUS_STRUCT%?dwAvailPhys / 1024 / 1024, 2)
  %MEMORYSTATUS_STRUCT%?dwTotalPageFile   :=   Round(%MEMORYSTATUS_STRUCT%?dwTotalPageFile / 1024 / 1024, 2)
  %MEMORYSTATUS_STRUCT%?dwAvailPageFile   :=   Round(%MEMORYSTATUS_STRUCT%?dwAvailPageFile / 1024 / 1024, 2)
  %MEMORYSTATUS_STRUCT%?dwTotalVirtual    :=   Round(%MEMORYSTATUS_STRUCT%?dwTotalVirtual / 1024 / 1024, 2)
  %MEMORYSTATUS_STRUCT%?dwAvailVirtual    :=   Round(%MEMORYSTATUS_STRUCT%?dwAvailVirtual / 1024 / 1024, 2)
Return, 
(
"System Memory Status:" . "
 
Memory Load:" . A_TAB . %MEMORYSTATUS_STRUCT%?dwMemoryLoad . "`%" . "
Total Physical:" . A_TAB . %MEMORYSTATUS_STRUCT%?dwTotalPhys . A_TAB . "MB" . "
Available Physical:" . A_TAB . %MEMORYSTATUS_STRUCT%?dwAvailPhys . A_TAB . "MB" . "
Total Pagefile:" . A_TAB . %MEMORYSTATUS_STRUCT%?dwTotalPageFile . A_TAB . "MB" . "
Available Pagefile:" . A_TAB . %MEMORYSTATUS_STRUCT%?dwAvailPageFile . A_TAB . "MB" . "
Total Virtual:" . A_TAB . %MEMORYSTATUS_STRUCT%?dwTotalVirtual . A_TAB . "MB" . "
Available Virtual:" . A_TAB . %MEMORYSTATUS_STRUCT%?dwAvailVirtual . A_TAB . "MB" . A_TAB  . "
"
)
}

Code:

; *********************************
; Chalkboard demo
; - hold down mouse1 to draw on the window
; - click mouse3 to clear
; *********************************

df_GetDC := DllCall("GetProcAddress", uint, DllCall("GetModuleHandle", str, "user32"), str, "GetDC")
df_CreateHatchBrush := DllCall("GetProcAddress", uint, DllCall("GetModuleHandle", str, "gdi32"), str, "CreateHatchBrush")
df_FillRect := DllCall("GetProcAddress", uint, DllCall("GetModuleHandle", str, "user32"), str, "FillRect")
df_ReleaseDC := DllCall("GetProcAddress", uint, DllCall("GetModuleHandle", str, "user32"), str, "ReleaseDC")
df_DeleteObject := DllCall("GetProcAddress", uint, DllCall("GetModuleHandle", str, "gdi32"), str, "DeleteObject")

Gui, Show, w400 h400, Chalkboard Demo
Gui + LastFound
g1 := WinExist()
cStruct_Create("Rect", "Int", "Left", "Int", "Top", "Int", "Right", "Int", "Bottom")
CoordMode, Mouse, Relative
OnMessage(0x200, "WM_MOUSEMOVE")
OnMessage(0x204, "WM_RBUTTONDOWN")
Return

WM_RBUTTONDOWN(wParam, lParam)
{
  WinSet, Redraw
}

GuiClose:
ExitApp

WM_MOUSEMOVE(wParam, lParam)
{
  Global
  Static HS_DIAGCROSS := 5
  MouseGetPos, POINTAPI?X, POINTAPI?Y, OutputVarWin
  If (OutputVarWin = g1 AND GetKeyState("LBUTTON", "P"))
  {
    Rect?Left := POINTAPI?X - 5
    Rect?Top := POINTAPI?Y - 30
    Rect?Right := POINTAPI?X + 5
    Rect?Bottom := POINTAPI?Y - 20
    cstruct_set("Rect")
    hDC := DllCall(df_GetDC, "UInt", g1)
    hBrush := DllCall(df_CreateHatchBrush, "UInt", HS_DIAGCROSS, "UInt", 0xFF00CC) 
    DllCall(df_FillRect, "UInt", hDC, "Str", Rect, "UInt", hBrush)
    DllCall(df_ReleaseDC, "UInt", g1, "UInt", hDC)
    DllCall(df_DeleteObject, "UInt", hBrush)
  }
  Return
}
Back to top
View user's profile Send private message Visit poster's website
Buddy



Joined: 09 Aug 2007
Posts: 11

PostPosted: Sun Jan 25, 2009 11:33 am    Post subject: Reply with quote

Great work, i really find it very useful.

To support the struct-in-struct scenario, could you expand the cStruct_get() function to allow for an address?varname or address?offset parameter input ?
An address is that what you get, when pulling an imbedded struct from its hosting struct.

Thx
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3, 4, 5
Page 5 of 5

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group