AutoHotkey Community

It is currently May 26th, 2012, 8:52 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 70 posts ]  Go to page Previous  1, 2, 3, 4, 5
Author Message
 Post subject:
PostPosted: June 13th, 2007, 6:05 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
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...


Report this post
Top
 Profile  
Reply with quote  
PostPosted: June 1st, 2008, 6:14 pm 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 8th, 2008, 2:49 pm 
Offline

Joined: December 4th, 2006, 10:35 am
Posts: 561
Location: Galil, Israel
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


Report this post
Top
 Profile  
Reply with quote  
PostPosted: July 8th, 2008, 7:19 pm 
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...


Report this post
Top
  
Reply with quote  
PostPosted: July 8th, 2008, 11:03 pm 
Offline

Joined: December 4th, 2006, 10:35 am
Posts: 561
Location: Galil, Israel
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


Report this post
Top
 Profile  
Reply with quote  
PostPosted: November 23rd, 2008, 12:27 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
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 :)


Report this post
Top
 Profile  
Reply with quote  
PostPosted: November 23rd, 2008, 12:28 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
Joy2DWorld wrote:
hey, nothing is bad if it works!
:D


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 24th, 2008, 4:00 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
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 :)

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
}
; *********************************


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 24th, 2008, 4:05 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
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
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 25th, 2009, 12:33 pm 
Offline

Joined: August 9th, 2007, 10:18 am
Posts: 11
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


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 70 posts ]  Go to page Previous  1, 2, 3, 4, 5

All times are UTC [ DST ]


Who is online

Users browsing this forum: fusion1920, Stigg, tomL and 7 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group