Library | Low-Level Win32 Routines ver 0.0.1 |
Aurthor | Jordah Ferguson |
Contacts | jorfergie03@yahoo.com |
Date | Thursday, July 25, 2002 |
This library holds a set of routines i have found very useful in win32 programming. My routines are designed to be safe and will save you a lot of time during the course of your win32 programming. This is all you will be needing to start programming in API or even using low-level win32lib.
By default, incase an error is encountered a message box pops-up explaining the error. However you can suppress any error message by calling SetErrorWarning(0). To later allow errors to be displayed then you call SetErrorWarning(1)
Memory Routines:
Memory calls are made using kernel32 API calls. The reason i choose to do this is because they are more OS friendly as they return freed memory back to the OS for the other programs to use. When you allocate memory using Euphoria calls, the memory when freed is not actually returned to the OS but is reserved for the next allocation. The only problem with this method is that if you have a computer low on memory and free disk-space and you allocate large chunks of memory, the OS will either deny other programs chance to run due to lack of memory or the OS will cause you program to be closed.
I have wrapped some kernel heap functions and made them global just incase you need to create your own private memory heaps. see Creating your Custom Memory Heaps
A default heap is automatically created for you when you include llrtn.ew in your program. The default heap has an intial size of 16384 bytes of physical storage, if you application requests more than that, then the OS allocates extra virtual memory.
To allocate memory from the default heap you'll have to use Alloc,AllocString,Free,FreeAllMem. Using these functions is all you'll need but just incase you need to create your own custom heap for some reason then see Creating your Custom Memory Heaps
I would like to thank Matt Lewis and Derek for once explaining the heap functions to me and Mario Steele and Lucius Hilley for chatting with me about the Pros and Cons of the functions
Function | Description |
Alloc | Allocates n bytes of contiguous bytes of memory. Using the Default Heap |
AllocString | Allocate space for string sequence s. Using the Default heap |
Free | Free previously allocated memory from the Default heap |
FreeAllMem | Frees all memory in the default heap and destroys the heap |
lstrlen | This function returns the length of a null-terminating string in memory |
PeekString | This function returns a null-terminating string from memory |
SafePeek2s | Return a signed word(2-byte) in the range -32768 to 32767 from a memory address |
SafePeek2u | Return a unsigned word(2-byte) in the range 0 to 65535 from a memory address |
SafePeek4s | Return a 4-byte (32-bit) signed value in the range -2147483648 to +2147483647 from a memory address |
SafePeek4u | Return a 4-byte (32-bit) unsigned value in the range 0 to 4294967295 from a memory address |
SafePeeks | Return a single signed byte value in the range -128 to 127 from a memory address |
SafePeeku | Return a single unsigned byte value in the range 0 to 255 from a memory address |
SafePoke | write a single byte value to a memory address |
SafePoke2 | write a 2-byte value(word) to amemory address |
SafePoke4 | write a 4-byte (32-bit) value to a memory address |
All the above routines are just wrap-ups of the C functions below, they are very sufficient and you'll find almost no need to create custom made heaps but just incase you need to; here is how you do it.
Step1: Create the Actual heap
you will have to supply the initial size of the heap
example:
atom myheap
myheap = HeapCreate(4096) -- Creates a
heap with 4096 bytes of intial hysical storage
Step2:After creating the heap
you can now allocate and free memory using HeapAlloc and HeapFree.
Remember the heap is growable so you can even allocate 20000
bytes from the above heap, it would only commit virtual memory
pages to cover-up your needs
example:
atom memaddr,junk
memaddr = HeapAlloc(myheap,20) --
Allocate 20 bytes of memory
junk = HeapFree(myheap,memaddr) --
Free memaddr from the heap
example2:
Incase you wanted to allocate a string in memory you would do it
like this
atom addr,len_,junk
sequence eu eu = "Euphoria 2.3"
len_ = length(eu)
addr = HeapAlloc(myheap,len_+1)
if addr then
SafePoke(addr,eu)
SafePoke(addr+len_,0)
end if
junk = HeapFree(myheap,addr)
Step3:This is not compulsory,
but is good practice. It is usually good to call HeapValidate() after HeapFree() or HeapAlloc()
example
atom junk,memaddr
memaddr = HeapAlloc(myheap,20) --
Allocate 20 bytes of memory
junk = HeapValidate(myheap,memaddr)
if not HeapFree(myheap,addr) then
end if
junk = HeapValidate(myheap,0)
Step4:Once you are done with
the heap then simply destroy it to free all the previous memory
allocations and destroy the heap. After a heap is destroyed you
can get an exception if you attempt to allocate or free memory
from a destroyed heap
example:
junk = HeapDestroy(myheap)
C Function | Description |
HeapCreate | This function allocates a private heap object. |
HeapAlloc | The HeapAlloc function allocates a block of memory from a heap. |
HeapFree | The HeapFree function frees a memory block(pointer) allocated from a heap by the HeapAlloc |
HeapDestroy | The HeapDestroy function destroys the specified heap object. |
HeapValidate | The HeapValidate function attempts to validate a specified heap or memory pointer |
Structure Handling Routines
Before i
start the tutorial on my structure handling routines i would like
to Credit Chris Bensler for the original idea and Bernie Ryan for all the
knowledge of structures i picked up from winapi20.zip. Thanx Chris Bensler bensler@mail.com also i would like to thank Jason
Mirwald for listening to my suggestions and giving me a
few suggestions.
Routine | Description |
defineStructure | Declares a Structure and returns internal structure information needed for use with other structure routines |
AllocateStructure | Allocates memory of a structure based on its size and returns the structure modified to reflect change |
FreeStructure | Deallocates the memory of the structure and returns the structure modified to reflect change |
AssociatePointer | Associates a structure pointer given by windows with a structure |
addressOf | Returns the memory pointer of a structure or the memory pointer of a structure element |
sizeOf | Returns the number of bytes the structure covers. It returns an integer specifying the amount of RAM the structure needs |
Store | This function fills the structure elements with information |
Fetch | Returns the contents of a structure |
Ok, now lets get on with the show. I'm going to explain how to declare and peek or Poke from the structure. Just like the way you have to declare a C function or Procedure, using my structure routines you have to declare your structure before you can put it into use, you do this by using the defineStructure() function. The return value is a sequence containing the structure defination needed when poking and peeking.
Declaring a Structure
s = defineStructure({{name,C constant}})
The second parameter where C
constant is placed can also be a structure defination in which
case the Internal Data will be linked. It can also be in the form
{C constant,repeat}
The Storing and fetching of structure information all depends on
the C constant you specify for example C_WORD when storing uses
SafePoke2 and when Fetching uses SafePeek2s while C_UWORD when
storing uses SafePoke2 but when fetching uses SafePeek2u. If the
C constant you specify is C_LPSZ then when storing you can simply
supply the String, Conversion is Automatic, you can also specify
an integer in which case it will allocate a buffer especially
when Fetching data from a C routine.
example 1:
Below is the how i link the C structure
RECT.
In C,
typedef struct _RECT { // rc
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT;
Using defineStructure;
-------------------[ RECT STRUCTURE
]-------------------
global sequence RECT
RECT = defineStructure({
{"left" ,C_LONG},
{"top" ,C_LONG},
{"right" ,C_LONG},
{"bottom",C_LONG}
})
example 2
In C, here is how the drawitemstruct looks like
typedef struct tagDRAWITEMSTRUCT { //
dis
UINT CtlType;
UINT CtlID;
UINT itemID;
UINT itemAction;
UINT itemState;
HWND hwndItem;
HDC hDC;
RECT rcItem; -----------------> This points to a RECT
structure
DWORD itemData;
} DRAWITEMSTRUCT;
Using defineStructure here is how u would link it. It also requires you had declared the rect structure like in example 1
-------------------[ DRAWITEMSTRUCT
]-------------------
global sequence
DRAWITEMSTRUCT
DRAWITEMSTRUCT = defineStructure({
{"CtlType" ,C_UINT},
{"CtlID" ,C_UINT},
{"itemID" ,C_UINT},
{"itemAction",C_UINT},
{"itemState" ,C_UINT},
{"hwndItem" ,C_LONG},
{"hDC" ,C_LONG},
{"rcItem" ,RECT },-->
Links/embends the RECT structure defination intoDRAWITEMSTRUCT
{"itemData" ,C_DWORD}
})
Example3
In C, here is an example of the PAINTSTRUCT
typedef struct tagPAINTSTRUCT { // ps
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32]; --> reserve 32 bytes
} PAINTSTRUCT;
using defineStructure.
-------------------[ PAINTSTRUCT
]-------------------
global sequence PAINTSTRUCT
PAINTSTRUCT = defineStructure({
{"hdc" ,C_LONG },
{"fErase" ,C_BOOL },
{"RECT" ,RECT },
{"fRestore" ,C_BOOL },
{"fIncUpdate" ,C_BOOL },
{"rgbReserved",{C_BYTE,32}}
})
Example4
In C here is the TC_ITEM structure
typedef struct _TC_ITEM {
UINT mask;
UINT lpReserved1;
UINT lpReserved2;
LPSTR pszText;
int cchTextMax;
int iImage;
LPARAM lParam;
} TC_ITEM;
using defineStructure
-------------------[ TC_ITEM Structure
]-------------------
global sequence TC_ITEM
TC_ITEM = defineStructure({
{"mask", C_UINT},
{"reserved1", C_UINT},
{"reserved2", C_UINT},
{"pszText", C_LPSZ},
{"cchTextMax", C_INT },
{"iImage", C_INT },
{"lParam", C_LONG}
})
Structures and
Memory Management
When you
declare a structure no memory is allocated for it, this is
because you will find out that in windows programming you can
either pass a structure pointer to a C function or receive a
structure pointer. when you receive a structure pointer from
windows for example the lParam from within a WM_NOTIFY message
always points to the NMHDR structure. Trying to free that
structure pointer can cause an exception, that is why i have
devised two ways of linking structure pointers to a structure.
1) Passing a Strutucture to a C
function.
If you routines are required to pass C structure pointers to C
functions then you allocate a stucture using AllocateStructure().
AllocateStructure always checks the structure you are passing to
it and if it has any previous allocated memory it is freed before
the new memory is allocated. You can deallocate memory from a structure using
FreeStrucuture function. FreeStructure should be
used when the memory was allocated using AllocateStructure.
Example
-------------------[ RECT STRUCTURE
]-------------------
global sequence RECT
RECT = defineStructure({
{"left" ,C_LONG},
{"top" ,C_LONG},
{"right" ,C_LONG},
{"bottom",C_LONG}
})
RECT = AllocateStructure(RECT)
-- This allocates memory for RECT structure and returns the RECT
structure with the internal data -- modified to reflect new
Changes.
RECT = FreeStructure(RECT)
-- This deallocates memory of the RECT structure and returns the
RECT structure with the
--Internal data modified to reflect changes
2) Receiving a structure pointer
from a Windows Message
During the course of your win32 programming you will notice there
are times windows returns to you a structure pointer from which
you can extract your desired data. the best example i can think
of at the moment is when you process the WM_NOTIFY message. the
lParam always points to the NMHDR structure. for such occasions
you need not allocate your declared structure but instead
Associate the memory pointer(lparam) with it. Below is an example
of how i declare the NMDHR structure and how i process the
WM_NOTIFY message
-------------------------------------------------------
global sequence NMHDR
NMHDR =
defineStructure({
{"hwndFrom",C_ULONG},
{"idFrom" ,C_UINT },
{"code" ,C_LONG }
})
---<snip> Here is how i
process the WM_NOTIFY message in my WndProc
elsif
iMsg =
WM_NOTIFY then
NMHDR =
AssociatePointer(NMHDR,lParam)
id = Fetch(NMHDR,"hwndFrom")
iMsg = Fetch(NMHDR,"code")
---<snip>
AddressOf and sizeOf
When Passing a structure to a C-routine, you have to know use the memory pointer. using llrtns.ew you use addressOf() function to find out the address of structure or the pointer to an element of a structure. example:
global atom aRECT
-------------------[ RECT STRUCTURE
]-------------------
global sequence RECT
RECT = defineStructure({
{"left" ,C_LONG},
{"top" ,C_LONG},
{"right" ,C_LONG},
{"bottom",C_LONG}
})
RECT = AllocateStructure(RECT)
aRECT= addressOf(RECT)
-------------------[ General
Function ]-------------------
global function getClientRect(atom id)
sequence
rect
atom
hdc
rect = repeat(0,4)
if id = Screen then
hdc = getDC(id)
rect[3] = c_func(zGetDeviceCaps,{hdc,HORZRES})
rect[4] = c_func(zGetDeviceCaps,{hdc,VERTRES})
releaseDC(id,hdc)
else
if not c_func(zGetClientRect,{id,aRECT}) then
puts(1,"getClientRect() failed")
end if
rect = Fetch(RECT,{})
end if
return
rect
end function
-- also incase i wanted to manually
obtain the addressOf the "top" element of the structure
-- i would do it like this
atom topAddr
topAddr =
addressOf({RECT,"top"})
During the course of your win32 programming you'll also find out some C functions require that you specify the size of the structure. The size of a structure is the number of bytes of RAM it uses. Microsoft came up with this method for compatibility reasons varing from platform to platform of windows. For example in win95, the structure MENUITEMINFO is one element smaller than that in windows 98. if you don't specify the size, the OS won't know what exactly you want to do and whatever function needs the structure address as a parameter fails. Below is an example that shows how to obtain the size of a bitmap object
-------------------[ BITMAP Structure
]-------------------
global sequence BITMAP
BITMAP =
defineStructure({
{"bmType", C_LONG},
{"bmWidth", C_LONG},
{"bmHeight", C_LONG},
{"bmWidthBytes" ,C_LONG},
{"bmPlanes", C_WORD},
{"bmBitsPixel", C_WORD},
{"bmBits", C_LONG}})
BITMAP =
AllocateStructure(BITMAP)
-------------------[ Size of a
bitmap ]-------------------
global function
GetBitmapSize(atom bitmap)
integer
void
void = c_func(zGetObject,{bitmap,sizeOf(BITMAP),addressOf(BITMAP)})
return Fetch(BITMAP,{"bmWidth","bmHeight"})--returns width and height of the bitmap handle
end function
In order to store data to a structure you use, Store(STRUCTURE,{{element,value}}). you can also use Store(Structure,{}) to erase all the contents of a structure(it does mem_set(addressOfStructure,0,sizeOf(Structure)). If you want to only store a value to one element you can use this notation for convinance. Store(RECT,{"top",200}). Below are a few examles that show you how store data.
-------------------[ TC_ITEM Structure
]-------------------
global sequence TC_ITEM
TC_ITEM = defineStructure({
{"mask", C_UINT},
{"reserved1", C_UINT},
{"reserved2", C_UINT},
{"pszText", C_LPSZ},
{"cchTextMax", C_INT },
{"iImage", C_INT },
{"lParam", C_LONG}
})
TC_ITEM = AllocateStructure(TC_ITEM)
---------------------------------------------------------
--Function:GetTabText(atom tabctl,integer tabitem)
--Use :It retrieves Text from a TabItem label
--Return :{} or TabText
---------------------------------------------------------
global function GetTabText(atom tabctl,integer tabitem)
integer
junk
sequence
InternalString
Store(TC_ITEM,
{{"mask",TCIF_TEXT },
{"pszText" ,128 },-- This creates a buffer to hold the string.
Read more on C_LPSZ
{"cchTextMax",128 }})
junk = sendMessage(tabctl,TCM_GETITEM,tabitem,addressOf(TC_ITEM))
InternalString = Fetch(TC_ITEM,"pszText")
return
InternalString
end function
example2: Shows the WinMain() of window.exw that comes with Eu2.3
-------------------[ WNDCLASSEX
STRUCTRURE ]------------
sequence
WNDCLASSEX
WNDCLASSEX = defineStructure({
{"cbSize" ,C_UINT },
{"style" ,C_UINT },
{"lpfnWndProc" ,C_POINTER},
{"cbClsExtra" ,C_INT },
{"cbWndExtra" ,C_INT },
{"hInstance" ,C_LONG },
{"hIcon" ,C_LONG },
{"hCursor" ,C_LONG },
{"hbrBackground",C_LONG },
{"lpszMenuName" ,C_POINTER},
{"lpszClassName",C_PTR },
{"hIconSm" ,C_LONG }
})
WNDCLASSEX = AllocateStructure(WNDCLASSEX)
atom
my_title,aWNDCLASS
my_title = AllocString("Euphoria for WIN32")
aWNDCLASS = addressOf(WNDCLASSEX)
procedure WinMain()
-- main routine
atom
szAppName
atom
hwnd
atom
WndProcAddress
atom
class
integer
id
atom
icon_handle,Cursor,Bk
szAppName = AllocString("HelloWin")
id = routine_id("WndProc")
if id = -1 then
puts(1, "routine_id failed!\n")
abort(1)
end if
WndProcAddress = call_back(id) -- get 32-bit address for callback
icon_handle = c_func(LoadIcon, {instance(), allocate_string("exw")})
Cursor = c_func(LoadCursor, {NULL, IDC_ARROW})
Bk = c_func(GetStockObject, {WHITE_BRUSH})
Store(WNDCLASSEX,{}) -- Similar to
mem_set() and filling with zeros
Store(WNDCLASSEX,{
{"cbSize" ,sizeOf(WNDCLASS)},
{"style" ,or_bits(CS_HREDRAW,
CS_VREDRAW)},
{"lpfnWndProc",WndProcAddress},
{"cbClsExtra" ,NULL },
{"cbWndExtra" ,NULL },
{"hInstance" ,instance() },
{"hIcon" ,icon_handle},
{"hCursor" ,Cursor },
{"hbrBackground",Bk },
{"lpszMenuName",NULL },
{"lpszClassName",szAppName},
{"hIconSm" ,icon_handle}
})
class =
c_func(RegisterClassEx, {aWNDCLASS})
if
class =
0 then
puts(1, "Couldn't register class\n")
abort(1)
end if
hwnd = c_func(CreateWindow, {
0, -- extended style
szAppName, -- window class name
my_title, -- window caption
WS_OVERLAPPEDWINDOW, -- window style
CW_USEDEFAULT, -- initial x position
CW_USEDEFAULT, -- initial y position
CW_USEDEFAULT, -- initial x size
CW_USEDEFAULT, -- initial y size
NULL, --
parent window handle
NULL, --
window menu handle
0 , --hInstance // program instance handle
NULL}) -- creation
parameters
if hwnd
= 0 then
puts(1, "Couldn't CreateWindow\n")
abort(1)
end if
c_proc(ShowWindow, {hwnd, SW_SHOWNORMAL})
c_proc(UpdateWindow, {hwnd})
WNDCLASSEX = FreeStructure(WNDCLASSEX)
Free(szAppName)
Free(my_title)
while c_func(GetMessage, {aMSG, NULL, 0, 0}) do-- aMSG is
addressOF MSG structure
c_proc(TranslateMessage, {aMSG})
c_proc(DispatchMessage, {aMSG})
end while
end procedure
WinMain()
You can fetch data from a
Structure using the Fetch() function. Fetch(Structure,{{element1,...}})
incase you need to Fetch more all the data from the
structure you can use Fetch(Structure,{}). It returns a sequence
containing all the peeked data in the same order you declared the
structure. For examples
1) Look at GetTabText(atom tabctl,integer tabitem) example above
2)Look at the GetBitmapSize(atom bitmap) example above
3)Look at the getClientRect(atom id) example above
With the above structure functions you will find out programming in API or low-level win32lib is just iece of cake.
Routines | Description |
LOWORD | The LOWORD macro retrieves the low-order word from the given 32-bit value. |
HIWORD | The HIWORD macro retrieves the high-order word from the given 32-bit value. |
MAKELONG | The MAKELONG macro creates an unsigned 32-bit value by concatenating two given 16-bit values. |
MAKEWORD | The MAKEWORD macro creates an unsigned 16-bit integer by concatenating two given unsigned character values. |
or_all() | applies or_bits on bits in a given sequence |
Syntax: include llrtns.ew a = Alloc(i) Description: Allocate i contiguous bytes of memory. Return the address of the block of memory, or return 0 if the memory can't be allocated. The address returned will be at least 4-byte aligned. Extra: The memory returned is automatically intialized to zero for you In Eu you would have to use mem_set() to initialize you memory to zero example: atom mem mem = Alloc(24)-- allocates 24 bytes of memory
See also AllocString,Free,FreeAllMem
Syntax: include llrtns.ew a = AllocString(s) Description: Allocate space for string sequence s. Copy s into this space along with a 0 terminating character. This is the format expected for C strings. The memory address of the string will be returned. If there is not enough memory available, 0 will be returned. The allocated memory is also initialized to Zero. This is Particularly helpful especially during time of peeking the string from memory.
example: atom pstr pstr = AllocString("Eu is the Bomb")-- returns a pointer to the string
See also Alloc,Free,FreeAllMem,PeekString,lstrlen
Syntax: include llrtns.ew Free(a)
Description: Free up a previously allocated block of memory by specifying the address of the start of the block, i.e. the address that was returned by Alloc() or AllocString().
Freed memory is returned to the OS. so other programs can also use the freed memory. if you forget to free your memory or you forget to call FreeAllMem() at the end of your program then there is no need to worry as the heap is automatically destroyed by the OS when the process terminates.
example: atom pstr pstr = AllocString("Eu is the Bomb")-- returns a pointer to the string Free(pstr)
See also AllocString,Alloc,FreeAllMem
Syntax: include llrtns.ew FreeAllMem()
Description: Calling this function Frees all the Allocated memory in the Heap and Destroys the Heap. Calling Alloc,Free,AllocString after this call will cause an exception.
Note The best place for this function in your program is after a call to WinMain()
Example: WinMain(MyWin,Normal) FreeAllMem()
See also AllocString,Free,Alloc
Syntax: include llrtns.ew a = HeapAlloc(atom heap,atom size)
Description: The HeapAlloc function allocates a block of memory from a heap. The allocated memory is not movable.
If HeapAlloc succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual size of the allocated block, use the HeapSize function.
To free a block of memory allocated by HeapAlloc, use the HeapFree function. The allocated memory is initialized to zero.
Returns 0 on failure or pointer to allocated memory
See Also HeapFree,HeapCreate,HeapDestroy,HeapValidate,Creating your Custom Memory Heaps
Syntax: include llrtns.ew a = HeapCreate(size)
Description: This function allocates a private heap object.The function reserves a contiguous block in the virtual address space of the process and allocates an initial physical storage block of size bytes.
Notes: The HeapCreate function creates a private heap object from which the calling process can allocate memory blocks by using the HeapAlloc function. The memory of a private heap object is accessible only to the process that created it. if you allocate more than size bytes the heap grows to suit your needs but uses virtual memory.
All heap functions need that you specify a handle to the heap object.
See also HeapAlloc,HeapFree,HeapValidate,HeapDestroy,Creating your Custom Memory Heaps
Syntax: include llrtns.ew
i = HeapDestroy(heap)
Description:
The HeapDestroy function destroys the specified heap object.
HeapDestroy decommits and
releases all the pages of a private heap object, and it
invalidates the handle of the heap.
it returns 1 if successfull or 0 if failed
See also HeapAlloc,HeapCreate,HeapFree,HeapValidate,Creating your Custom Memory Heaps
Syntax: include llrtns.ew i = HeapFree(atom heap, atom pointer)
Description: The HeapFree function frees a memory block(pointer) allocated from a heap by the HeapAlloc it returns 1 if successfull or 0 if it failed
See also HeapAlloc,HeapCreate,HeapDestroy,HeapValidate,Creating your Custom Memory Heaps
Syntax: include llrtns.ew
i = HeapValidate()
Description:
The HeapValidate function attempts to validate a specified
heap. The function scans all the memory blocks in the heap, and
verifies that the heap control structures maintained by the
operating system's heap manager are in a consistent state. You
can also use the HeapValidate function to validate a single
memory block within a specified heap, without checking the
validity of the entire heap.
See Also HeapFree,HeapCreate,HeapDestroy,HeapAlloc,Creating your Custom Memory Heaps
Syntax: include llrtns.ew i = lstrlen(a)
Description: This function returns the length of a null-terminating string in memory a. It is mainly needed when peeking a string from memory. It is faster to use this then peek to get a string from memory.
example: 1) atom mem,len mem = AllocString("Euphoria") len = lstrlen(mem) -- len is 8 sequence answer answer = peek({mem,len})-- answer is "Euphoria" 2) Here is an example function where i use it, however you should simply use PeekString()
global function GetWindowText(atom id) integer len_,mem_len_,ret_len sequence buffer len_ = c_func(zGetWindowTextLength,{id}) len_+=1 mem_len_ = Alloc(len_) ret_len = c_func(zGetWindowText,{id,mem_len_,len_}) if ret_len+1!=len_ then puts(1,"GetWindowText Failed to return text") end if buffer = peek({mem_len_,lstrlen(mem_len_)}) Free(mem_len_) return buffer end function
see also AllocString,PeekString
Syntax: include llrtns.ew s = PeekString(a)
Description: This function returns a null-terminating string from memory a. It uses SafePeeku() and lstrlen(). So the above examples can be
example: 1) atom mem,len mem = AllocString("Euphoria") sequence answer answer = PeekString(mem)-- answer is "Euphoria"
2) Here is an example function where i use it, however you should simply use PeekString()
global function GetWindowText(atom id) integer len_,mem_len_,ret_len sequence buffer len_ = c_func(zGetWindowTextLength,{id}) len_+=1 mem_len_ = Alloc(len_) ret_len = c_func(zGetWindowText,{id,mem_len_,len_}) if ret_len+1!=len_ then puts(1,"GetWindowText Failed to return text") end if buffer = PeekString(mem_len_) Free(mem_len_) return buffer end function See also lstrlen,AllocString
Syntax: include llrtns.ew i = SafePeek2s(a1) or s = SafePeek2s({a1,i})
Description: Return a signed word(2-byte) in the range -32768 to 32767 from machine address a1, or return a sequence containing i consecutive 2-byte signed values starting at address a1 in memory.
Note: This is also a missing function in Standard Euphoria that is needed a lot in Win32 API. It tests for Read-Access before actaully peeking the signed word
See also SafePoke2,SafePeek2u
Syntax: include llrtns.ew i = SafePeek2u(a1) or s = SafePeek2u({a1,i})
Description: Return a unsigned word(2-byte) in the range 0 to 65535 from machine address a1, or return a sequence containing i consecutive 2-byte unsigned values starting at address a1 in memory.
Note: This is also a missing function in Standard Euphoria that is needed a lot in Win32 API. It tests for Read-Access before actaully peeking the unsigned word
See also SafePeek2s,SafePoke2
Syntax: a2 = SafePeek4s(a1) or ... s = SafePeek4s({a1, i})
Description: Return a 4-byte (32-bit) signed value in the range -2147483648 to +2147483647 from machine address a1, or return a sequence containing i consecutive 4-byte signed values starting at address a1 in memory.
Note: This function is identical to that one found in Std Eu only that This one checks for read-access. For more information read about peek4s
See also SafePeek4u,SafePoke4
Syntax: a2 = SafePeek4u(a1) or ... s = SafePeek4u({a1, i})
Description: Return a 4-byte (32-bit) unsigned value in the range 0 to 4294967295 from machine address a1, or return a sequence containing i consecutive 4-byte unsigned values starting at address a1 in memory.
Note: This function is identical to that one found in Std Eu only that This one checks for read-access. For more information read about peek4u See also SafePeek4s,SafePoke4
Syntax: include llrtns.ew a = SafePeeks(a) or s = SafePeeks({a,i})
Description: Return a single signed byte value in the range -128 to 127 from machine address a, or return a sequence containing i consecutive byte values starting at address a in memory.
Note: This function is missing with standard Euphoria. It also uses safe peeking by testing memory for Read Access before actually reading the signed byte from memory.
See also SafePeeku,SafePoke
Syntax: include llrtns.ew i = SafePeeku(a) or s = SafePeeku({a,i})
Description: Return a single unsigned byte value in the range 0 to 255 from machine address a, or return a sequence containing i consecutive byte values starting at address a in memory.
Note: This is a safer version of Euphoria peek(). It works the same as peek but is safer as in it tests if read access is allowed for the byte it is going to read. For more information check out Euphorias peek()
See also SafePeeks,SafePoke
Syntax: include llrtns.ew SafePoke(a, x)
Description: If x is an atom, write a single byte value to memory address a.
If x is a sequence, write a sequence of byte values to consecutive memory locations starting at location a.For more read about Euphorias poke()
Note: Similar to Euphorias poke but tests if write - access to the memory is permitted before poking.
See also SafePeeku,SafePeeks
Syntax: SafePoke2(a, x)
Description: If x is an atom, write a 2-byte value(word) to memory address a.
If x is a sequence, write a sequence of 2-byte values to consecutive memory locations starting at location a. It checks if write-access is permitted to a, before poking
See also SafePeek2s,SafePeek2u
Syntax: SafePoke4(a, x)
Description: If x is an atom, write a 4-byte (32-bit) value to memory address a.
If x is a sequence, write a sequence of 4-byte values to consecutive memory locations starting at location a. Notes It checks if write-access is permitted to a, before poking. For more information check out poke4 that comes with Std Eu See also SafePeek4s,SafePeek4u
-- Distribution Status -- ------------------- -- This software is being contributed to the Public Domain. -- Feel free to use it, abuse it, and/or modify it for any purpose. -- Send bug reports or feature requests to: -- jorfergie03@yahoo.com -- -- -- Disclaimer -- ---------- -- I am in no way responsible for any damage, data loss, or any other -- adverse effects resulting from the use/abuse/etc. of this library.