AutoHotkey Community

It is currently May 24th, 2012, 7:48 pm

All times are UTC [ DST ]




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

Joined: December 29th, 2004, 1:28 pm
Posts: 2537
Thanks :)

majkinetor wrote:
Now, imagine your functions to set and get the struct fields are called automaticaly by AHK upon API function enterence/exit. That would be awesome .... we would get the same structs as in C. What else to want.
This would be ideal if built in and would be great if we could assigin a value to a variable in a struct and have the struct automatically updated. The functionality you mentioned to simplify DllCall can currently be added using a wrapper for DllCall calls that are called multiple times in the code though. Here's an example.
Code:
#Include, %A_ScriptDir%\ahkstructlib2.ahk

StructCreate("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)
{
  Struct@(MEMORYSTATUS_STRUCT) ; dynamically called before
  DllCall("GlobalMemoryStatus", "Str", %MEMORYSTATUS_STRUCT%)
  Struct?(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  . "
"
)
}


majkinetor wrote:
I already explaind here how that can be acheived.
Thanks for the link. I seem to have missed that topic somehow. Could you please be a bit more specific on what you're suggesting? :)

Edit: MsgBox formatting in example


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 5th, 2007, 2:33 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Lets look at the usage:

Code:
StructCreate("POINT1", "x as long", "y as long")

point1?x := 5
point1?y := 10

Struct?("POINT1")
DllCall("GetCursorPos", "Str", POINT1)   
Struct@("POINT1")


Now, you have to prefix eatch call with those 2 functions or at least 1 depending on api func.

Now, I suggest updating ahk so to be able to recongise this:

Without adding new variable types fallowing should be changed

1. Ability to return structure from function via "return" keyword
Currently you can't do that
2. DllCall should recognise when it sees Struct? function in its argument list, and call Struct@ at the end ( I called this 2 functions Set & Get in my examples)

If this is changed. We can write above code like this

Code:
StructCreate("POINT1", "x as long", "y as long")

point1?x := 5
point1?y := 10

DllCall("GetCursorPos", "Str", Struct?("POINT1") )  ;you changed Struct? so to return pointer to C structure
;before returning from DllCall AHK calls Struct@ as it can see Struct? function among its arguments


IN C code :
Code:
POINT point1;

point1.x := 5
point1.y := 10

GetCursorPos(POINT1) 


So, the only difference would be that instead specifying struct variable directly, you use the adequate setter function.

Other even better approach is to call Struct? automaticaly but that is not big benefit and requires handling special "struct" variables

And, corrupt, please, don't do it with ? its very ugly. Use _

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2007, 4:27 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2537
Thanks for the additional details :) .

You may already be aware but, just for clarification, your example of the current usage is reversed. Currently Struct? will retrieve values from a struct and store the values in the local variables. Struct@ will take the values of the local variables and store them in the struct. This would change your example to look like:
Code:
StructCreate("POINT1", "x as long", "y as long")

point1?x := 5
point1?y := 10

Struct@("POINT1")
DllCall("GetCursorPos", "Str", POINT1)   
Struct?("POINT1")


majkinetor wrote:
And, corrupt, please, don't do it with ? its very ugly. Use _
I tend to agree that using ? isn't very appealing to look at but I likely won't make the change anytime soon unless the dot character becomes available for this purpose. One of the main reasons for not using the underscore character _ is that it is commonly used throughout code as a visual separator in variable names, labels, function names, etc... There were 2 main reasons for using the ? character. In most cases it's easier to parse in code since it's likely that a ? character will have a space before and/or after it when used for something other than a struct variable name. The other reason is that, with the keyboard layout that I use (US English), the ? character is physically close to the dot character on the keyboard.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2007, 8:50 am 
Offline

Joined: July 12th, 2005, 1:21 pm
Posts: 633
I really missed this great topic over all the years... (I think I might not have needed it until now).
Thanks corrupt!

Thalon

_________________
AHK-Icon-Changer
AHK-IRC
deutsches Forum


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2007, 9:36 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
2 corrupt
Well, it apperas you missed important part of the story and respond about unimportant details. Ofc, its not like you can do anything about suggestions...

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2007, 1:11 pm 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2537
majkinetor wrote:
2 corrupt
Well, it apperas you missed important part of the story and respond about unimportant details. Ofc, its not like you can do anything about suggestions...
I didn't miss the important part but since it's a suggestion for a change to AHK's code I wanted to try a couple workarounds (although unlikely to work efficiently) before responding ;) .


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2007, 1:15 pm 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2537
Thalon wrote:
I really missed this great topic over all the years... (I think I might not have needed it until now).
Thanks corrupt!

Thalon
Thanks for checking it out :) .


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 6th, 2007, 1:39 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Quote:
I didn't miss the important part but since it's a suggestion for a change to AHK's code I wanted to try a couple workarounds (although unlikely to work efficiently) before responding

You can contact me via IM if you would like to discuss it.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 11th, 2007, 1:14 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
Very interesting script. 8)

I do have one question... Is there any benefit to declaring and using 32 parameters over using a single comma-delimited list? IMO, a single string (containing a list) would make it more readable (or at least prettier.)

For example, instead of:
Code:
StructCreate("RECT", "Int", "Left", "Int", "Top", "Int", "Right", "Int", "Bottom")

you could have
Code:
StructCreate("RECT",
(
"   int Left,
    int Top,
    int Right,
    int Bottom"
))

or the uber-readable (using `n as a delimiter)
Code:
rectdef =
(
    int Left
    int Top
    int Right
    int Bottom
)
StructCreate("RECT", rectdef)

I suppose a parsing loop (to parse the parameter list) might be slightly slower than the loop you have, but I'd opt for readability. All those quote marks hurt my eyes. :shock:

Perhaps a better approach would be to "compile" a structure definition from a string (or strings), allowing the definition to be used for multiple structures. That might help (in particular) when a number of (the same) structures need to be instantiated, as you wouldn't need to parse any strings. 'think I might try coding it from that angle, after some sleep.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 11th, 2007, 1:30 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
I agree.
Performance part of this library is not about definition however so I doubt anything can cause harm here. The performance is important for Struct? and Struct@ functions.

BTW, I guess single string passed ByRef will perform better too. I am not quite sure how AHK function stack is implemented but if it simulates normal behavior, passing large number of arguments to the function may cause stack overflaw, and is ofc slower then passing reference.

One of the greatest speed achievent here would be an options for Struct setter and getter (@ and ?). Now they always fill every struct membrer regerdless if that is needed or not. Contrary to that, API structures you pass almost always contain just couple of memebers to fill, while others are not important.

If you have this in a loop, you get large number of unnecessary assigments.

Now, if this can be make so Struct?@ can work with optional parameter

Struct?@( strValuesToSet )

that can be used like
Code:
Struct@( "field1 field3")
API_SomeAPIFunction(....)
Struct?("field5")


for speed maximimzation.

You may argue that setting single elements will be slowed down by parsing the func argument, but that is possible not true. You will basicly need this only when you need to set 1 or 2 members for structs that have 10 or more members. Parsing 1 or 2 short strings is probably faster then assigment to 10 variables

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 11th, 2007, 2:40 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
majkinetor wrote:
Now they always fill every struct membrer regerdless if that is needed or not.

I'm leaning towards having the single struct variable*, and using get and set functions. (Get functions would return values, not set global variables...)

The get and set functions could be generated automatically for the specific structs, rather than using a generic function which would have to do more work parsing parameters. After all, a structure definition would rarely, if ever, need to change at run-time.

*Rather than having an AHK variable store the struct data, my idea is to use DllCall to allocate, read, write and release the memory, with an AHK variable as a pointer. This has two main benefits:
  • No zero-byte issues, meaning it can be returned by functions.
  • More control. For example, the struct could exist in another process' memory space. This would simplify tasks such as getting the text of a TreeView item (where you MUST pass an address to memory in the external process.)


It bothers me having all of the data duplicated - in the struct, and in each ?field variable. *Mumbles deliriously about data duplication and synchronicity issues.* On the other hand, the whole point of it is to make dealing with "structs" easier, and it does that quite well (I imagine--I haven't put it to practical use yet.) I suppose it wouldn't really be put to heavy use to the point that it mattered.

k, slp nw. :?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 11th, 2007, 2:46 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Quote:
On the other hand, the whole point of it is to make dealing with "structs" easier,

Right. So your points dont' stand. You can use extractinteger for that :D

Quote:
More control. For example, the struct could exist in another process' memory space. This would simplify tasks such as getting the text of a TreeView item (where you MUST pass an address to memory in the external process.)

That is limitation, but not a big one. How many ppl use remote process memory? 0. Correct.

For fancy stuff like that, you have to code structs yourself. RemoteBuffer class that I created can help. If you just want to grab TV data, see my TV functions that can grab most important TV data from other processes.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 12th, 2007, 2:02 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
majkinetor wrote:
Right. So your points dont' stand. You can use extractinteger for that :D

Insert/ExtractInteger is exactly what I want to get away from. I really don't see your logic, or which "points" you are referring to.

Quote:
That is limitation, but not a big one. How many ppl use remote process memory? 0. Correct.

I do. You do. Anyone else who needs to grab text from a remote TreeView does. What limitation are you referring to? Limitation of ahkstructlib?

I was falling asleep at the keyboard when I posted, but I later realised it would be easier not to support structs in remote process memory. It would require the use of different memory management/access functions, without providing any clear advantage. What I used for TreeView text is adequate:
  • Create the struct locally (in this case using InsertInteger), then
  • Allocate the remote memory and copy the entire struct over.
  • Do whatever needs to be done in the remote process (send a message in this case.)
  • Copy the entire struct back.
There is no need to modify the struct while it exists in remote process memory. :)

Quote:
For fancy stuff like that, you have to code structs yourself. RemoteBuffer class that I created can help. If you just want to grab TV data, see my TV functions that can grab most important TV data from other processes.

Is the point of ahkstructlib not to do that for you? I don't need to use your TV functions - I've already written some of my own. I should probably mention I'm a hobby programmer. I wrote the TreeView code more for fun than out of any necessity.

The original reason I wrote it was that I read an article on how to navigate to a registry key in regedit (programmatically). It used keystroke simulation (well, sent WM_CHAR messages.) I thought there must be a better way, so I went about figuring it out. :)

I think I'm getting a bit OT...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 12th, 2007, 4:29 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2537
lexikos wrote:
Very interesting script. 8)

I do have one question... Is there any benefit to declaring and using 32 parameters over using a single comma-delimited list? IMO, a single string (containing a list) would make it more readable (or at least prettier.)

For example, instead of:
Code:
StructCreate("RECT", "Int", "Left", "Int", "Top", "Int", "Right", "Int", "Bottom")

you could have
Code:
StructCreate("RECT",
(
"   int Left,
    int Top,
    int Right,
    int Bottom"
))
Thanks for the suggestion :) . Although it would clean up the look of the code a bit and allow more flexibilty to the number of members in a struct I'm not sure if there's enough benefit (or a need to exceed 32). Although I haven't timed the declaration process, I doubt there's much of a performance hit with the current method. The current method also allows variables to be used for dynamically creating structs - although the need for such usage is likely rare (maybe for specifying Int, 0 instead of str, "" in some cases?...). It's also possible to generate the string first based on variable values and/or concatenate in the function call of course but that could be even less readable. On the other hand, there's no reason why another function for declaring a struct couldn't be added to the set of functions if the result is compatible and/or improves functionality. You're probably aware, but the current function will also allow something like the following to improve readability:
Code:
StructCreate("RECT", "Left As Int", "Top As Int", "Right As Int", "Bottom As Int")


lexikos wrote:
It bothers me having all of the data duplicated - in the struct, and in each ?field variable. *Mumbles deliriously about data duplication and synchronicity issues.* On the other hand, the whole point of it is to make dealing with "structs" easier, and it does that quite well (I imagine--I haven't put it to practical use yet.) I suppose it wouldn't really be put to heavy use to the point that it mattered.
I agree but I'm not sure if there are many practical workarounds currently possible without additional functionality being built-in to AuthHotkey that will allow a working with struct members as regular variables. I'm open to suggestions... :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 12th, 2007, 5:07 am 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2537
majkinetor wrote:
One of the greatest speed achievent here would be an options for Struct setter and getter (@ and ?). Now they always fill every struct membrer regerdless if that is needed or not.
Not exactly. If you specify a specific member of a struct instead of the name of the struct only then only that member will be updated. If a specific member is updated frequently in a loop the main reason for loss of efficiency would likely be determined by which member needed to be updated as the function needs to loopup the name in the struct each time before it gets updated. The same is true for retrieving values. This method will likely change in the next version though in an attempt to speed things up a bit. Using separate global, reference variables would likely spped things up considerably (similar to version 1) but I was purposely trying to get away from using multiple global variables with this version.

majkinetor wrote:
Now, if this can be make so Struct?@ can work with optional parameter

Struct?@( strValuesToSet )

that can be used like
Code:
Struct@( "field1 field3")
API_SomeAPIFunction(....)
Struct?("field5")


for speed maximimzation.

You may argue that setting single elements will be slowed down by parsing the func argument, but that is possible not true. You will basicly need this only when you need to set 1 or 2 members for structs that have 10 or more members. Parsing 1 or 2 short strings is probably faster then assigment to 10 variables
Using the current methods, the speed here will also depend on which members need to be updated. I can see that this could help optimize repeatedly setting or retrieving only certain members in a struct in a loop but I'm not sure if there are many cases where this optimization would be necessary. Do you have any specific cases in mind that would benefit from this optimization?


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  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: SKAN and 13 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