Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[CLASS] DllStruct (AHK 1.1)


  • Please log in to reply
31 replies to this topic
just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Update on 2013-06-06: Readded class script.THX, polyethene for messing this post!

 

I know about HotKeyIt's Struct() script, but remaining with AHK Basic I could not use it, and (to tell the truth) I did (and do) not understand entirely, why it is working, so I never tried.

Things changed with AHK 1.1. Curious I started to play around with the new class syntax and after some times of struggle I got an idea of the new possibilities for scripting with AHK. So this is my attempt to design a class for structures. It does not have any advantages over HotKeyIt's function other than "better" readability. It supports "plain" structures only, it is less complete (but it's easy to comlete the WinTypes object), it may be less comfortable and may have less performance, but someone may find it usefull anyway or may take it as an example of the class syntax:

Spoiler


Sample script:
Spoiler

APIStructures.ahk (example of some predefined structures):
Spoiler


The class script is somewhat tested on WinXP and Vista (x86 / U32) and Win 7 (x64 / U64). It may be buggy, so if you find some bugs, report them here, please.

Have fun!


Update 2011-07-24[*:3h48yj5e]Windows data types are completed (at least I hope so)[*:3h48yj5e]Changed class name to "DllStruct" (some reminiscence of AutoIt)Update 2011-08-01[*:3h48yj5e]Added support for set/get fields with multiple occurrences as a whole passing/as an array[*:3h48yj5e]Changed sample scriptUpdate 2011-08-02[*:3h48yj5e]Fixed bug in Init() method (THX Lexikos)[*:3h48yj5e]Added support for named occurrences (e.g. "LONG rcWindow[4];".[*:3h48yj5e]Changed sample scriptUpdate 2011-08-28[*:3h48yj5e]Editorial revisionUpdate 2011-11-14[*:3h48yj5e]Added basic type alignment (hopefully like the VC/VC++ compilers will do by default)[*:3h48yj5e]Added type of fields which names are preceded with "*" will become "UPTR"Update 2011-11-22[*:3h48yj5e]Added structure padding[*:3h48yj5e]Added option "Align n;" to set the alignment from within the "StructString" parameter.Update 2011-12-07[*:3h48yj5e]Fixed broken structure initialization with NULL.Update 2011-12-09[*:3h48yj5e]Fixed erroneous alignment (hopefully).Update 2012-01-21[*:3h48yj5e]Added optional alignment for embedded structures.[*:3h48yj5e]Added option "pad n;" for explicit padding.[*:3h48yj5e]Changed error handling to provide more useful informations.[*:3h48yj5e]Changed structure parser to ignore linebreaks.[*:3h48yj5e]Changed APIStructures.ahk sample script.

 



maul.esel
  • Members
  • 790 posts
  • Last active: Jan 05 2013 09:26 PM
  • Joined: 28 Feb 2011
Great! Thank you! I needed some time to get it working, but now it does!

Tip: it would be cool if you could add string handling. I added "LPCWSTR" : "PTR" to WinTypes and assigned a pointer to the string.
I didn't look much in the internals of your class, but maybe you could do this "conversion" in the class.

Thanks again
maul.esel
Join the discussion on The future of AutoHotkey
Posted Image Visit me on github Posted Image
Win7 HP SP1 64bit | AHK_L U 64bit

just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011
*minor update*

just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011
*minor update*

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
I would like to commend you for your useful, well-written script. I have avoided using a certain other struct wrapper because although it works adequately, it seems like it would be a nightmare for anyone other than the original author to maintain. (There is another reason which I won't go into here.)

If I get time, I will review your script and see if I can offer any suggestions. For now...

Init() seems to assume all structures are 16 bytes:
DllCall("Kernel32\RtlZeroMemory", "Ptr", This._Ptr, "Ptr", [color=red]16[/color])
I suppose it should be This._Size.

just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011
Thank you very much indeed!

Of course you're right, the "16" is most likely a left-over from testing the DllCall with my beloved RECT structures and I've fixed this.

*minor update*

just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011
*minor upate - editorial revision*

just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

[*:22xz3tqp]Added basic type alignment (hopefully like the VC/VC++ compilers will do by default)


Dear C programmers,

I've read some stuff about structure alignment and padding on MSDN, but I'm not sure if I've got it right. For now I think that /Zp8 or #pragma pack(8) is the default, meaning

The alignment of a member will be on a boundary that is either a multiple of 8 or a multiple of the size of the member, whichever is smaller.

If my understanding is right, would it be useful to have an option like "Pack 4;" for the structure creation?

I've also read something about padding to fill up the structure to end on a special boundary, but didn't understand that. When is this necessary?

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
If a structure has a packing alignment of n, its total size must be a multiple of n. It's most important when you have a contiguous array of structs - since there may be padding between each struct - but can also be important in other cases. For instance, if some external code copies a struct into a pointer you provide, it may copy the padding as well; if the memory you've allocated doesn't include the padding, memory corruption may occur.

just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011
Thx, Lexikos,

padding the capacity can be done easily. But, does padding affect the size to be stored in the (e.g.) cbSize member of a structure?

Edit: Is a multiple of 8 the right default for both 32 as well as 64 bit environments?

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

But, does padding affect the size to be stored in the (e.g.) cbSize member of a structure?

If cbSize is supposed to contain the size of the structure, then by definition it must include any padding contained by the structure.

Edit: Is a multiple of 8 the right default for both 32 as well as 64 bit environments?

Read your earlier quote. Consider what "the size of the member" is and how it may (or may not) differ between 32- and 64-bit builds.

just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011
*minor update*

  • Guests
  • Last active:
  • Joined: --
How do I define a structure with a union?

This doesn't seem to be working. Thanks.
;http://msdn.microsoft.com/en-us/library/windows/desktop/bb773352%28v=vs.85%29.aspx
def_NOTIFYICONDATA := "
(LTrim Join
	DWORD cbSize;
	HWND  hWnd;
	UINT  uID;
	UINT  uFlags;
	UINT  uCallbackMessage;
	HICON hIcon;
	TCHAR szTip[64];
	DWORD dwState;
	DWORD dwStateMask;
	TCHAR szInfo[256];
	union {
	UINT uTimeout;
	UINT uVersion;
	};
	TCHAR szInfoTitle[64];
	DWORD dwInfoFlags;
	GUID  guidItem;
	HICON hBalloonIcon;
)"
_NOTIFYICONDATA := new DllStruct(def_NOTIFYICONDATA)
msgbox % _NOTIFYICONDATA.GetPtr()


  • Guests
  • Last active:
  • Joined: --
Having hard time using a rect structure. The script crashes. Am I using it correctly?
#include <Class_DllStruct>
def_Rect := "
(LTrim Join
	LONG left;
	LONG top;
	LONG right;
	LONG bottom;
)"	
_Rect := new DllStruct(def_Rect)	

Run, Notepad,,, OutputVarPID
WinWait Untitled - Notepad  

DllCall("GetWindowRect", Ptr, WinExist("ahk_pid " OutputVarPID), Ptr, &_Rect)  
MsgBox % "Left " . _Rect.Left . " Top " . _Rect.Top
    . " Right " . _Rect.Right . " Bottom " . _Rect.Bottom


  • Guests
  • Last active:
  • Joined: --
&_Rect is the address of the wrapper object. You want the address of the structure, which is _Rect.GetPtr().