Jump to content


Photo

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


  • Please log in to reply
126 replies to this topic

#1 HotKeyIt

HotKeyIt
  • Fellows
  • 6132 posts

Posted 24 June 2010 - 09:41 PM

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){ ; For AHK_L v2 replace this line with 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
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)



#2 Lexikos

Lexikos
  • Administrators
  • 8845 posts

Posted 24 June 2010 - 10:10 PM

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?)

#3 HotKeyIt

HotKeyIt
  • Fellows
  • 6132 posts

Posted 24 June 2010 - 10:19 PM

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

#4 ddk

ddk
  • Members
  • 43 posts

Posted 24 June 2010 - 10:32 PM

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

#5 HotKeyIt

HotKeyIt
  • Fellows
  • 6132 posts

Posted 24 June 2010 - 10:55 PM

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


#6 HotKeyIt

HotKeyIt
  • Fellows
  • 6132 posts

Posted 01 July 2010 - 10:09 PM

- 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 ;)

#7 tinku99

tinku99
  • Members
  • 560 posts

Posted 02 July 2010 - 02:31 AM

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

Fantastic.

#8 majkinetor

majkinetor
  • Fellows
  • 4511 posts

Posted 02 July 2010 - 03:02 AM

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.

#9 Joy2DWorld

Joy2DWorld
  • Members
  • 562 posts

Posted 06 July 2010 - 09:31 AM

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...

#10 HotKeyIt

HotKeyIt
  • Fellows
  • 6132 posts

Posted 06 July 2010 - 04:41 PM

Thanks, I've added a note about AHK_L.
You can find S() here: FrameWork

#11 majkinetor

majkinetor
  • Fellows
  • 4511 posts

Posted 06 July 2010 - 08:51 PM

... or directly via repository here

#12 HotKeyIt

HotKeyIt
  • Fellows
  • 6132 posts

Posted 20 July 2010 - 11:16 PM

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:

#13 HotKeyIt

HotKeyIt
  • Fellows
  • 6132 posts

Posted 02 August 2010 - 08:07 PM

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



#14 HotKeyIt

HotKeyIt
  • Fellows
  • 6132 posts

Posted 25 September 2010 - 11:32 AM

- 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.



#15 HotKeyIt

HotKeyIt
  • Fellows
  • 6132 posts

Posted 07 November 2010 - 12:51 AM

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.