This code demonstrates how to move binary data to and from global memory blocks. The source VFP string is copied into an allocated global memory block. Then content of this block is copied into the destination string. There is no direct usefulness in this code -- just a demonstration.
In some situations you need to pass to a structure (not to a function, that is easy) the 4-byte pointer to a string -- LPCSTR, or LPCTSTR.
As an example, to run some printer functions you must supply the DOCINFO structure:
Within this structure lpszDocName is not a string, but a pointer to a string with a defined document name -- e.g. "My Printer Job".
That means, you must allocate this string in memory and pass the pointer to the structure. Using global memory functions makes this task possible. At that time -- to my knowledge -- there is no regular function in VFP to return a pointer to a string.
If GMEM_FIXED being used instead of GMEM_MOVEABLE you can avoid using the GlobalLock and GlobalUnlock couple. With GMEM_FIXED you receive a pointer comparing to a handle to the memory object for the GMEM_MOVEABLE.
Hi! I'm using VFP 9 and played a little bit with the SYS(2600...) function. Pls have a look at the following code fragment. Maybe I'm wrong, but I think SYS(2600) is not exactly behaving like described in the docs!
DECLARE RtlMoveMemory IN kernel32 INTEGER, STRING @, INTEGER DECLARE INTEGER GlobalAlloc IN kernel32; INTEGER wFlags,; INTEGER dwBytes DECLARE INTEGER GlobalFree IN kernel32 INTEGER hMem
LOCAL hMem AS Integer && Memory handle returned by GlobalAlloc(GMEM_MOVEABLE,...) LOCAL lpVoid AS Long && Memory pointer returned by GlobalAlloc(GMEM_FIXED,...) and others LOCAL lcString AS String, lcString2 AS String, lnSize As Integer
*\\ Create some VFP strings. We don't have to zero-terminate ; them coz we do not process them any further using Win API ; calls written in C/C++ lcString = "This is a great VFP test string!" lcString2= "This is another VFP test string!" lnSize = LEN(m.lcString) && == LEN(m.lcString2) !! clear
*\\ allocate fixed memory #DEFINE GMEM_FIXED 0 lpVoid = GlobalAlloc(GMEM_FIXED, m.lnSize) ? "lpVoid", m.lpVoid && no handle but a pointer! *// *\\ move VFP's string into allocated memory block ? "RtlMoveMemory() : ", RtlMoveMemory(m.lpVoid, @m.lcString, m.lnSize) *// *\\ now get back our string content using VFP's SYS(2600) function ? SYS(2600, m.lpVoid, m.lnSize) *// *\\ free memory: GlobalFree() accepts a pointer in this case lpVoid = GlobalFree(m.lpVoid) ? "lpVoid after GlobalFree(): ", m.lpVoid *// ? "-------------------------------------" *\\ now, let's try something different: DECLARE INTEGER GlobalLock IN kernel32 INTEGER hMem DECLARE INTEGER GlobalUnlock IN kernel32 INTEGER hMem *\\ allocate moveable memory block #DEFINE GMEM_MOVEABLE 2 hMem = GlobalAlloc(GMEM_MOVEABLE, m.lnSize) ? "hMem ", m.hMem, "a handle" *// *\\ lock memory to get a pointer the starting address lpVoid = GlobalLock(m.hMem) ? "lpVoid", m.lpVoid, "a pointer" *// *\\ again, move the string into allocated memory block now using a VFP Fn() ? SYS(2600, m.lpVoid, m.lnSize, m.lcString2) && write string content to memory block *\\ Note the outcome of SYS(2600) above then read the online help for it! I thought; that SYS(2600) 1st reads (and returns) the addressed memory block then writes ; to it (if optional 4th argument is passed in). But that isn't true, obviously! *// *\\ get back our string content using VFP's SYS(2600) ? SYS(2600, m.lpVoid, m.lnSize) *// *\\ unlock memory before freeing it: GlobalUnlock() returns <0> if successful; this isn't really necessary here coz GlobalFree() unlocks the memory block anyway ? "GlobalUnlock()", GlobalUnlock(m.hMem) *// *\\ free memory: GlobalFree() accepts a handle in this case ; on success GlobalFree() returns <0>, otherwise the handle/pointer value passed in m.hMem = GlobalFree(m.hMem) *// ? "hMem after GlobalFree(): ", m.hMem
Credits: PHP (4.4.9), an HTML-embedded scripting language,
MySQL (5.1.55-log), the Open Source standard SQL database,
AceHTML Freeware
Version 4, freeware HTML Editor of choice. Hosted by Korax Online Inc.