 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
corrupt
Joined: 29 Dec 2004 Posts: 2485
|
Posted: Wed Jun 13, 2007 5:05 am Post subject: |
|
|
| 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 |
|
 |
corrupt
Joined: 29 Dec 2004 Posts: 2485
|
Posted: Sun Jun 01, 2008 5:14 pm Post subject: Re: ahkstructlib - Functions for use with Structures (versio |
|
|
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 |
|
 |
Joy2DWorld
Joined: 04 Dec 2006 Posts: 561 Location: Galil, Israel
|
Posted: Tue Jul 08, 2008 1:49 pm Post subject: |
|
|
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 |
|
 |
Guest
|
Posted: Tue Jul 08, 2008 6:19 pm Post subject: Re: ahkstructlib - Functions for use with Structures (versio |
|
|
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
|
Posted: Tue Jul 08, 2008 10:03 pm Post subject: Re: ahkstructlib - Functions for use with Structures (versio |
|
|
| 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 |
|
 |
corrupt
Joined: 29 Dec 2004 Posts: 2485
|
Posted: Sat Nov 22, 2008 11:27 pm Post subject: Re: ahkstructlib - Functions for use with Structures (versio |
|
|
| 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  |
|
| Back to top |
|
 |
corrupt
Joined: 29 Dec 2004 Posts: 2485
|
Posted: Sat Nov 22, 2008 11:28 pm Post subject: Re: ahkstructlib - Functions for use with Structures (versio |
|
|
| Joy2DWorld wrote: | | hey, nothing is bad if it works! |
 |
|
| Back to top |
|
 |
corrupt
Joined: 29 Dec 2004 Posts: 2485
|
Posted: Mon Nov 24, 2008 3:00 am Post subject: |
|
|
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
}
; *********************************
|
|
|
| Back to top |
|
 |
corrupt
Joined: 29 Dec 2004 Posts: 2485
|
Posted: Mon Nov 24, 2008 3:05 am Post subject: |
|
|
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 |
|
 |
Buddy
Joined: 09 Aug 2007 Posts: 11
|
Posted: Sun Jan 25, 2009 11:33 am Post subject: |
|
|
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 |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|