Jump to content

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

[Class _Struct]+[Func sizeof] ! updated 01.04.12 ! ++AHKv2


  • Please log in to reply
219 replies to this topic
HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

Note :!: You will need latest AutoHotkey_L or AutoHotkey_H to use these functions.
_Struct Documentation - Download _Struct.ahk - _Struct.ahk for AHKv2
sizeof() Documentation - Download sizeof.ahk - sizeof.ahk for AHKv2

 

If you use AutoHotkey_H also see AHKStructures.ahk

 

For compatibility with AHK_H build in Struct() function, save following function as Struct.ahk in your lib folder:
This will also allow to include _Struct function dynamically.
Struct.ahk:

#include <_Struct>
Struct(Structure,pointer:=0,init:=0){
return new _Struct(Structure,pointer,init)
}



Changes and up to date version available on github

Struct alows easy access to the world of structures. Simple to use using object syntax, dynamic structure resolution, pointers support and more.It's now so simple to use structures in AHK like never before.

Struct[""] contains pointer of structure so you can pass it to DllCall and SendMessage functions.
Also Struct.item[""] will return pointer to that item.


;Assign new pointer to a pointer item
MyStruct.mystring[""] := &variable
;To set pointer for main structure [] must be used !!!
MyStruct[]:=&memory

Do not forget to include the class :!:

#include <_Struct>

- LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,CHAR,UCHAR,TCHAR
_Struct get and set methods use StrGet for these data types, so you will need to use MyStruct.string[""] to get or set the pointer - PSTR,PCSTR,PTSTR,PCTSTR,PWSTR,PCWSTR,PCHAR,PUCHAR,PTCHAR
These are equivalent data types that do not use StrGet so you can get and set the pointer directly.

 

Enjoy wink.png

See also this threadfor more examples.

; Simple user defined structure (Use number for characters, so StrGet/StrSet will be used)
;typedef struct {
; TCHAR char[2];
; int code[2];
;} ASCIICharacter;
MyChar := Struct("TCHAR char[2],int code[2]") ;create structure, type for code could be omited
MyChar.char.1:="A"
MyChar.char.2:="a"
MyChar.code.1 :=Asc(MyChar.char.1)
MyChar.code.2 :=Asc(MyChar.char.2)
MsgBox % MyChar.char.1 " = " MyChar.code.1 "`n" MyChar.char.2 " = " MyChar.code.2
;_______________________________________________
; Simple array of 26 characters
String:=Struct("TCHAR char[26]")
Loop 26
string.char[A_Index]:=Chr(A_Index+64)
Loop 3
MsgBox % String.char[A_Index*2] ;show some characters
MsgBox % StrGet(string[]) ;get complete string
;_______________________________________________
; Array of structures
user:="LPTSTR Id, LPTSTR Name"
users := Struct("user[2]") ; array of structs
users.Alloc(4*A_PtrSize,400)
;~ users.Alloc("Name",2*A_PtrSize,80)
users.1.Id := "Id1", users.1.Name := "Name 1"
users.2.Id := "Id2", users.2.Name := "Name 2"
MsgBox % users.1.Id " " users.1.Name "`n" users.2.Id " " users.2.Name
;_______________________________________________
; Vector example
Vector:="a,b,c,d"
v:=Struct("Vector[2]") ;create an array of Vertors
v.1.a:=1 ;set some keys
v.2.c:=10 ;set some keys
MsgBox % v.1.a "`n" v.2.c ;show values

VarSetCapacity(newmem,sizeof(v)) ;resevere some memory for new structure
v[]:=&newmem ;set new memory address
MsgBox % v.1.a "`n" v.2.c ;show new structure
v.1.a:=1
v.2.c:=10
MsgBox % v.1.a "`n" v.2.c ;now values are filled
;_______________________________________________
; RECT example
;Example using RECT structure to move a window
Gui,+LastFound
hwnd:=WinExist() ;get window handle
_RECT:="left,top,right,bottom"
RC:=Struct(_RECT) ;create structure
Gui,Add,Text,,Press Escape to continue
Gui,Show,w200 h100 ;show window
DllCall("GetWindowRect","Uint",hwnd,"Uint",rc[]) ;get window position
rc.right := rc.right - rc.left ;Set rc.right to be the width
rc.bottom := rc.bottom - rc.top ;Set rc.bottom to be the height
While DllCall("GetCursorPos","Uint",rc[])
&& DllCall("MoveWindow","Uint",hwnd
,"int",rc.left,"int",rc.top,"int",rc.right,"int",rc.bottom,"Int",1)
Sleep, 10
GuiClose:
Escape::
Gui,Destroy
rc:=""
;_______________________________________________
; FindFirstFile && FindNextFile && FileTimeToSystemTime
_FILETIME := "dwLowDateTime,dwHighDateTime"
_SYSTEMTIME := "WORD wYear,WORD wMonth,WORD wDayOfWeek,WORD wDay,WORD wHour,WORD wMinute,WORD wSecond,WORD Milliseconds"
_WIN32_FIND_DATA := "dwFileAttributes,_FILETIME ftCreationTime,_FILETIME ftLastAccessTime,_FILETIME ftLastWriteTime,nFileSizeHigh,nFileSizeLow,dwReserved0,dwReserved1,TCHAR cFileName[260],TCHAR cAlternateFileName[14]"

file:=Struct("_WIN32_FIND_DATA[2]")
time:=Struct("_SYSTEMTIME")

DllCall("FindFirstFile","Str",A_ScriptFullPath,"Uint",file.1[""])
DllCall("FindFirstFile","Str",A_AhkPath,"UInt",file.2[""])
MsgBox % StrGet(file.1.cFileName[])
MsgBox % "A_ScriptFullPath:`t" StrGet(file.1.cFileName[""]) "`t" StrGet(file.1.cAlternateFileName[""]) "`nA_AhkPath:`t" StrGet(file.2.cFileName[""]) "`t" StrGet(file.2.cAlternateFileName[""])

handle:=DllCall("FindFirstFile","Str","C:\*","Uint",file.2[""])
Loop {
If !DllCall("FindNextFile","Uint",handle,"Uint",file.2[""])
break
DllCall("FileTimeToSystemTime","Uint",file.2.ftLastWriteTime[""],"Uint",time[""])
ToolTip % StrGet(file.2.cFileName[""]) "`n" StrGet(file.2.cAlternateFileName[""]) "`n" file.2.nFileSizeHigh " - " file.2.nFileSizeLow
. "`n" time.wYear . "-" time.wMonth . "-" time.wDay
. "`n" time.wDayOfWeek
. "`n" time.wHour . ":" time.wMinute . ":" time.wSecond . ":" time.Milliseconds
Sleep, 200
}
DllCall("CloseHandle","Uint",handle)
;_______________________________________________
; Predefinition of structures
MyStruct:=Struct("a,b,c,d")
MyStruct.a:=1
MsgBox % MyStruct.a
; C/C++ like syntax
NewStruct:="
(
TCHAR char[11]; // Array of 11 characters
TCHAR char2[11]; // Another array of 11 characters
LPTSTR string; // String pointer
Int integer; // Integer
PTR pointer; // Pointer
)"

MyStruct:=Struct(NewStruct)
MyStruct.Alloc("string",A_PtrSize,100)
MyStruct.char.1:="A" ;set first char
MyStruct.char2.1:="ABC" ;here all 3 characters will be writter to the array char2
MyStruct.string := "New String"
MyStruct.integer := 100
MyStruct.pointer := &MyStruct

MsgBox % MyStruct.char.1 "`n"
. StrGet(MyStruct.char2[""]) "`n"
. MyStruct.String "`n"
. MyStruct.integer "`n"
. MyStruct.pointer "`n"
;_______________________________________________
;Pointer example
;Create a variable containing a string
var:="AutoHotKey"
;Create a pointer that will point to the variable/string
VarSetCapacity(v,4),NumPut(&var,v)

s:=Struct("*Uint p",&v)
MsgBox % StrGet(s.p[])

;assign another pointer
anothervar:="AutoHotkey_L"
s.p[""]:=&anothervar
MsgBox % StrGet(s.p[])

;Using LPTSTR you can assign a string directly
s:=Struct("LPTSTR p"),s.Alloc("p",A_PtrSize,100)
s.p:="String"
MsgBox % s.p
NumPut(&var,s.p[""],0,"PTR") ; change address in p
MsgBox % s.p
;_______________________________________________
; PROCESSENTRY32
MAX_PATH:=260
_PROCESSENTRY32:="
(
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
ULONG_PTR th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
LONG pcPriClassBase;
DWORD dwFlags;
TCHAR szExeFile[" MAX_PATH "];
)"
VarSetCapacity(string,260)
pEntry:= Struct(_PROCESSENTRY32)
pEntry.dwSize := sizeof(_PROCESSENTRY32)
hSnapshot:=DllCall("CreateToolhelp32Snapshot","UInt",TH32CS_SNAPALL:=0x0000001F,"PTR",0)
DllCall("Process32First" (A_IsUnicode?"W":""),"PTR",hSnapshot,"PTR",pEntry[""])
While % (A_Index=1 || DllCall("Process32Next" (A_IsUnicode?"W":""),"PTR",hSnapshot,"PTR",pEntry[""])) {
ToolTip % pEntry.cntUsage "`n" pEntry.th32ProcessID
. "`n" pEntry.th32DefaultHeapID "`n" pEntry.th32ModuleID
. "`n" pEntry.cntThreads "`n" pEntry.th32ParentProcessID
. "`n" pEntry.pcPriClassBase "`n" pEntry.dwFlags "`n" StrGet(pEntry.szExeFile[""])
Sleep, 200
}
;_______________________________________________
; MODULEENTRY32
MAX_PATH:=260
MAX_MODULE_NAME32:=255
_MODULEENTRY32:="
(
DWORD dwSize;
DWORD th32ModuleID;
DWORD th32ProcessID;
DWORD GlblcntUsage;
DWORD ProccntUsage;
BYTE *modBaseAddr;
DWORD modBaseSize;
HMODULE hModule;
TCHAR szModule[" MAX_MODULE_NAME32 + 1 "];
TCHAR szExePath[" MAX_PATH "];
)"

ListProcessModules(DllCall("GetCurrentProcessId"))
ExitApp

ListProcessModules(dwPID)
{
global _Struct
static TH32CS_SNAPMODULE:=0x00000008,INVALID_HANDLE_VALUE:=-1
hModuleSnap := Struct("HANDLE")
me32 := Struct("_MODULEENTRY32")

; Take a snapshot of all modules in the specified process.
hModuleSnap := DllCall("CreateToolhelp32Snapshot","UInt", TH32CS_SNAPMODULE,"PTR", dwPID )
if( hModuleSnap = INVALID_HANDLE_VALUE )
{
MsgBox % "CreateToolhelp32Snapshot (of modules)"
return FALSE
}

; Set the size of the structure before using it.
me32.dwSize := sizeof("_MODULEENTRY32")

; Retrieve information about the first module,
; and exit if unsuccessful

if( !DllCall("Module32First" (A_IsUnicode?"W":""),"PTR", hModuleSnap,"PTR", me32[""] ) )
{
MsgBox % "Module32First" ; // Show cause of failure
DllCall("CloseHandle","PTR", hModuleSnap ) ; // Must clean up the snapshot object!
return FALSE
}

;// Now walk the module list of the process,
;// and display information about each module
while(A_Index=1 || DllCall("Module32Next" (A_IsUnicode?"W":""),"PTR",hModuleSnap,"PTR", me32[""] ) )
{
ToolTip % "`tMODULE NAME`t=`t" StrGet(me32.szModule[""])
. "`n`texecutable`t=`t" StrGet(me32.szExePath[""])
. "`n`tprocess ID`t=`t" me32.th32ProcessID
. "`n`tref count (g)`t=`t" me32.GlblcntUsage
. "`n`tref count (p)`t=`t" me32.ProccntUsage
. "`n`tbase address`t=`t" me32.modBaseAddr[""]
. "`n`tbase size`t=`t" me32.modBaseSize
Sleep, 200
}

;// Do not forget to clean up the snapshot object.
DllCall("CloseHandle","PTR",hModuleSnap)
return TRUE
}

Update
Latest changes available on github

03.10.2012

- Fixed #Warn messages
02.09.2012
- Struct() function for compatibility with AHK_H build in Struct() function.
20.06.2012
- declared local variables as local, otherwise they could get in conflict with globals in v1
01.04.2012
- small fix in sizeof() when calculating offset.
18.02.2012
- _Struct works now fully dynamically (no objects in objects)
- - for this reason no automatic string allocation is done.
- - you will need to use Alloc to allocate memory or assign a pointer.
- Added several methods, Type(),AhkType(),IsPointer,Size(),SizeT(),Alloc(),Capacity(),Offset() see docs.
- Released AHKv2 version.
10.08.2011
- Fixed StrPut for CHAR,TCHAR,UCHAR.
05.08.2011
- Rewritten _Struct and redesigned to class
- now initialization of items is possible
13.11.2010
- Fixed pointer offset
06.112010
- Struct was completely revised
- Struct constructor
04.08.2010 - Fix - Structure in Structure
- New - instead struct[""] you can use struct[] as well04.08.2010 - Fix - structure parameters containing _ were not working02.08.2010 - Fix - Structure memory is filled with 'null character'
- Fix - Offset for Structure in Structure20.07.2010 - Fixed creating array of structures, e.g. vector example was not working correct.01.07.2010- Implemented Global variable structure definition and named structure definition
- Implemented Union, see AHKStructures example
- Implemented Pointer in Pointer and Structure in Structure, see pointer and AHKStructures example27.06.2010 - Fix for Int6425.06.2010 - Struct("definition",pointer) will use existing structure
- Fixed memory issue (thanks Lexikos)



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

However, there's a problem with this:
[color=red]Structure[/color]._SetCapacity([color=red]Structure[/color],size*Structure1)
Since AutoHotkey_L currently doesn't handle cyclic references, that object will always have a non-zero reference count. Its memory won't be freed until the process terminates. (I think that's only used for arrays of structs?)

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Thanks m8 ;)

I see, so if I change it to something like this, it should be okay than?
Structure._SetCapacity("`n",size*Structure1)

Edit:
It fixes memory issue, thank you very much Lexikos :D

ddk
  • Members
  • 43 posts
  • Last active: Oct 12 2010 11:03 PM
  • Joined: 28 Dec 2009
AHH.. This is what I've been waiting so long 8) 8) Thank you, exactly what I needed.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

AHH.. This is what I've been waiting so long 8) 8) Thank you, exactly what I needed.

I'm glad you like it ;)

Fixed memory issue, thanks Lexikos ;)


Edit:
You can occupy existing structure now as well, pass its pointer in second parameter when creating structure.
VarSetCapacity(test,40)
NumPut(100,test,12)
Struct:=new _Struct("a[10]",&test)
MsgBox % struct[""] "`n" (&test)
MsgBox % struct[4].a


HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

- Implemented Global variable structure definition and named structure definition
- Implemented Union, see AHKStructures example
- Implemented Pointer in Pointer and Structure in Structure, see pointer and AHKStructures example

Many thanks Lexikos for your support ;)

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007

- Implemented Global variable structure definition and named structure definition
- Implemented Union, see AHKStructures example

Fantastic.

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
Thanks for this library. Nicely done and very useful. Structs are finally the way it should be.

As related, here is alternative for AHK & AHKL: S function.
Posted Image

Joy2DWorld
  • Members
  • 562 posts
  • Last active: Jun 30 2014 07:48 PM
  • Joined: 04 Dec 2006

Thanks for this library. Nicely done and very useful. Structs are finally the way it should be.

As related, here is alternative for AHK & AHKL: S function.


OK, so i go look at link and neat doc set.

but where is link there to dload/review the code itself ?


ie., all I get to is instructions...


also @HotkeyIt, (if helpful) post is not clear if this is only for _L fork or also vers for normal AHK. [I know this is clear enough to you and I, but] Maybe this will confuse some/many. just a suggest to make explicit for not so experienced users, etc...
Joyce Jamce

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Thanks, I've added a note about AHK_L.
You can find S() here: FrameWork

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
... or directly via repository here
Posted Image

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

Minor bugfix when creating arrays of structures :!:

That one costed me weeks to fix :x :evil:
Fortunately I didn't give up and got it finally working :twisted:

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

- Structure memory is filled with 'null character' now.
- Offset for Structure in Structure
EDIT
- _ in field name works now (like is_byref in AHKFuncParam)



HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

- You can use [] to get structure its pointer now ([""] is works as well of course) requires AHK_L53++

RC:=Struct("RECT")
pRC:=[color=red]RC[][/color] ;returns pointer to structure
- Fixed AHKLine structure.



HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
I finally finished an upgrade for Struct() :)

- Structure() supports all AHK and Windows Data Types now.
- Struct("") returns constructor object that can be used to define and create structures
- - Constructor supports comments and multiple definitions like TCHAR a,b,c;

struct:=Struct("") ;get constructor object
struct.MyStruct:="TCHAR a,b,c; //some comments"
s:=struct.MyStruct ;create a structure
s.a:="A"
s.b:="B"
s.c:="C"
MsgBox % s.a s.b s.c

;another example
Struct:=Struct("")
struct.InputBoxType:=" ;structure definition, constructor will clean, convert and create a global variable for Struct function
(
   LPTSTR title; // Title of Input Box   
   LPTSTR text; //...
   int width;
   int height;
   int xpos;
   int ypos;
   AHKVar *output_var;
   TCHAR password_char;
   LPTSTR default_string;
   DWORD timeout;
   HWND hwnd;
   HFONT font;
)"
IBox:=struct.InputBoxType ;create new structure and assign to IBox
IBox.title:="Title"
IBox.text:="Text"
IBox.timeout:=100
MsgBox % StrGet(IBox.title) "`n" StrGet(IBox.text) "`n" IBox.timeout
- Arrays support improved
s:=Struct("TCHAR[2]")
s.1:="A"
MsgBox % s.1

s:=Struct("TCHAR a[2],TCHAR b[2]")
s.a.1:="A"
s.b.2:="B"
MsgBox % s.a.1 s.b.2


Here is a list of supported Data Types and according AHK types.
;AHK Data Types
PTR:=A_PtrSize
UPTR:=PTR
SHORT:=2
USHORT:=SHORT
INT:=4
UINT:=INT
INT64:=8
UINT64:=INT64
DOUBLE:=INT64
FLOAT:=INT
CHAR:=1
UCHAR:=CHAR
;Windows Data Types
TBYTE:=A_IsUnicode?"USHORT":"UCHAR"
TCHAR:=A_IsUnicode?"USHORT":"UCHAR"
HALF_PTR:=A_PtrSize=8?"INT":"SHORT"
UHALF_PTR:=A_PtrSize=8?"UINT":"USHORT"
BOOL:="Int"
INT32:="Int"
LONG:="Int"
LONG32:="Int"
LONGLONG:="Int64"
LONG64:="Int64"
USN:="Int64"
HFILE:="PTR"
HRESULT:="PTR"
INT_PTR:="PTR"
LONG_PTR:="PTR"
POINTER_64:="PTR"
POINTER_SIGNED:="PTR"
SSIZE_T:="PTR"
WPARAM:="PTR"
BOOLEAN:="UCHAR"
BYTE:="UCHAR"
COLORREF:="UInt"
DWORD:="UInt"
DWORD32:="UInt"
LCID:="UInt"
LCTYPE:="UInt"
LGRPID:="UInt"
LRESULT:="UInt"
PBOOL:="UInt"
PBOOLEAN:="UInt"
PBYTE:="UInt"
PCHAR:="UInt"
PCSTR:="UInt"
PCTSTR:="UInt"
PCWSTR:="UInt"
PDWORD:="UInt"
PDWORDLONG:="UInt"
PDWORD_PTR:="UInt"
PDWORD32:="UInt"
PDWORD64:="UInt"
PFLOAT:="UInt"
PHALF_PTR:="UInt"
UINT32:="UInt"
ULONG:="UInt"
ULONG32:="UInt"
DWORDLONG:="UInt64"
DWORD64:="UInt64"
UINT64:="UInt64"
ULONGLONG:="UInt64"
ULONG64:="UInt64"
DWORD_PTR:="UPTR"
HACCEL:="UPTR"
HANDLE:="UPTR"
HBITMAP:="UPTR"
HBRUSH:="UPTR"
HCOLORSPACE:="UPTR"
HCONV:="UPTR"
HCONVLIST:="UPTR"
HCURSOR:="UPTR"
HDC:="UPTR"
HDDEDATA:="UPTR"
HDESK:="UPTR"
HDROP:="UPTR"
HDWP:="UPTR"
HENHMETAFILE:="UPTR"
HFONT:="UPTR"
HGDIOBJ:="UPTR"
HGLOBAL:="UPTR"
HHOOK:="UPTR"
HICON:="UPTR"
HINSTANCE:="UPTR"
HKEY:="UPTR"
HKL:="UPTR"
HLOCAL:="UPTR"
HMENU:="UPTR"
HMETAFILE:="UPTR"
HMODULE:="UPTR"
HMONITOR:="UPTR"
HPALETTE:="UPTR"
HPEN:="UPTR"
HRGN:="UPTR"
HRSRC:="UPTR"
HSZ:="UPTR"
HWINSTA:="UPTR"
HWND:="UPTR"
LPARAM:="UPTR"
LPBOOL:="UPTR"
LPBYTE:="UPTR"
LPCOLORREF:="UPTR"
LPCSTR:="UPTR"
LPCTSTR:="UPTR"
LPCVOID:="UPTR"
LPCWSTR:="UPTR"
LPDWORD:="UPTR"
LPHANDLE:="UPTR"
LPINT:="UPTR"
LPLONG:="UPTR"
LPSTR:="UPTR"
LPTSTR:="UPTR"
LPVOID:="UPTR"
LPWORD:="UPTR"
LPWSTR:="UPTR"
PHANDLE:="UPTR"
PHKEY:="UPTR"
PINT:="UPTR"
PINT_PTR:="UPTR"
PINT32:="UPTR"
PINT64:="UPTR"
PLCID:="UPTR"
PLONG:="UPTR"
PLONGLONG:="UPTR"
PLONG_PTR:="UPTR"
PLONG32:="UPTR"
PLONG64:="UPTR"
POINTER_32:="UPTR"
POINTER_UNSIGNED:="UPTR"
PSHORT:="UPTR"
PSIZE_T:="UPTR"
PSSIZE_T:="UPTR"
PSTR:="UPTR"
PTBYTE:="UPTR"
PTCHAR:="UPTR"
PTSTR:="UPTR"
PUCHAR:="UPTR"
PUHALF_PTR:="UPTR"
PUINT:="UPTR"
PUINT_PTR:="UPTR"
PUINT32:="UPTR"
PUINT64:="UPTR"
PULONG:="UPTR"
PULONGLONG:="UPTR"
PULONG_PTR:="UPTR"
PULONG32:="UPTR"
PULONG64:="UPTR"
PUSHORT:="UPTR"
PVOID:="UPTR"
PWCHAR:="UPTR"
PWORD:="UPTR"
PWSTR:="UPTR"
SC_HANDLE:="UPTR"
SC_LOCK:="UPTR"
SERVICE_STATUS_HANDLE:="UPTR"
SIZE_T:="UPTR"
UINT_PTR:="UPTR"
ULONG_PTR:="UPTR"
ATOM:="Ushort"
LANGID:="Ushort"
WCHAR:="Ushort"
WORD:="Ushort"

Please test it extensively and report any bugs.