Code: Select all
Rect := makeRect(10, 10, 200, 200)
MsgBox % "left: " NumGet(Rect.Ptr, 0, "Int")
. "`ntop: " NumGet(Rect.Ptr, 4, "Int")
. "`nright: " NumGet(Rect.Ptr, 8, "Int")
. "`nbottom: " NumGet(Rect.Ptr, 12, "Int")
makeRect(x1, y1, x2, y2) {
Rect := BufferAlloc(16)
NumPut(x1, Rect.Ptr, 0, "Int")
NumPut(y1, Rect.Ptr, 4, "Int")
NumPut(x2, Rect.Ptr, 8, "Int")
NumPut(y2, Rect.Ptr, 12, "Int")
return Rect
}
BufferAlloc(Size) {
return new BufferObject(Size)
}
class BufferObject
{
static HEAP_ZERO_MEMORY := 0x00000008
static hDefaultHeap := BufferObject.__GetProcessHeap()
Ptr := ""
Size_ := ""
Size[]
{
get {
return this.Size_
}
set {
this.__AssertSizeValid(value, "BufferObject Size[] Set")
this.Ptr := this.__HeapReAlloc(value)
this.Size_ := this.__HeapSize()
return value
}
}
__New(Size) {
this.__AssertSizeValid(Size, "BufferAlloc")
this.Ptr := this.__HeapAlloc(Size)
this.Size_ := this.__HeapSize()
}
__Delete() {
this.__HeapFree()
}
__AssertSizeValid(Size, caller) {
if Size is not number
this.__Error(caller, "Invalid parameter #1: NaN")
if (Size < 0)
this.__Error(caller, "Invalid parameter #1: Negative number")
}
__GetProcessHeap() {
if !hDefaultHeap := DllCall("GetProcessHeap", "Ptr")
this.__Error("GetProcessHeap")
return hDefaultHeap
}
__HeapAlloc(dwBytes) {
if !pMem := DllCall("HeapAlloc", "Ptr", this.hDefaultHeap, "UInt", this.HEAP_ZERO_MEMORY, "UPtr", dwBytes, "Ptr")
{
; If the function fails, it does not call SetLastError.
; An application cannot call GetLastError for extended error information.
this.__Error("HeapAlloc", "", false)
}
return pMem
}
__HeapReAlloc(dwBytes) {
if !pMem := DllCall("HeapReAlloc", "Ptr", this.hDefaultHeap, "UInt", this.HEAP_ZERO_MEMORY, "Ptr", this.Ptr, "UPtr", dwBytes, "Ptr")
{
; If the function fails, it does not call SetLastError.
; An application cannot call GetLastError for extended error information.
this.__Error("HeapReAlloc", "Original memory not freed, original pointer still valid", false)
}
return pMem
}
__HeapSize() {
return DllCall("HeapSize", "Ptr", this.hDefaultHeap, "UInt", 0, "Ptr", this.Ptr, "UPtr")
}
__HeapFree() {
if !this.Ptr
this.__Error("HeapFree", "Pointer to memory block was NULL")
if !DllCall("HeapFree", "Ptr", this.hDefaultHeap, "UInt", 0, "Ptr", this.Ptr, "Int")
this.__Error("HeapFree")
}
__Error(calledFunc, extraInfo := "", showLastErr := true) {
static ERROR_TEMPLATE := "
(LTrim
{} failed{}
Error Level: {}
{}
)"
errorMsg := Format(ERROR_TEMPLATE
, calledFunc
, (extraInfo != "") ? " (" extraInfo ")" : "."
, ErrorLevel
, showLastErr ? "Last Error: " A_LastError : "")
throw Exception(errorMsg, -4)
}
}