We had our monthly FoxPro user group meeting last night, and, like always, there were some cool new things shown and talked about that I’ve now got to play with. Cathy Pountney was kind enough to drive over from the Grand Rapids area to do a session on extending VFP 9’s report writer through extensions and hooking into the generation process with listeners. She demo’d some code which added a new print dialog box which allowed the user to pick/configure the printer before printing, being able to print a document range (ex. 1-10, 11), “Print to Fit” which resizes a report to fit on 1 page, duplex printing, booklet printing, and being able to print multiple pages per sheet of paper. Really cool stuff. She’ll be giving this same presentation at Southwest Fox next week, so if you’re planning on going, don’t miss this session.
One of the “hey, I didn’t know about that command” that came up was SYS(2600). This command lets you pass in a integer (pointer) and then returns the memory pointed to by the pointer as a string. It can also write data into the memory point. This is pretty slick since it allows you to easily interface with win32 API calls that require you to pass in pointers to structures, or use API calls that return pointers to structures. By setting/getting this memory as a string, you can then easily parse apart the structure to get the data back.
To be able to do anything useful with this, you’re also going to need the ability to allocate/de-allocate some memory (and get a pointer to it). The easiest way to do this is through a few API calls:
#DEFINE GMEM_ZEROINIT 0x40 && Init memory contents to zero
DECLARE INTEGER GlobalAlloc IN kernel32.dll ;
INTEGER wFlags, ;
INTEGER dwBytes
DECLARE INTEGER GlobalFree IN kernel32.dll ;
INTEGER hMem
lnPointer = GlobalAlloc(GMEM_ZEROINIT, 110)
?lnPointer
IF lnPointer > 0
* You should see a a bunch of squares (nulls)
?SYS(2600, lnPointer, 110)
SYS(2600, lnPointer, 100, REPLICATE("X", 100))
* Now you should see 100 X's followed by 10 nulls
?SYS(2600, lnPointer, 110)
GlobalFree(lnPointer)
ENDIF
A side note: You may see some apps use LocalAlloc/LocalFree instead of GlobalAlloc/GlobalFree. They are essentially the same thing at this point (that is, there isn’t any difference between the two of them). This is one of those “backwards compatibility” things. If you want to know more: http://msdn2.microsoft.com/en-us/library/ms810603.aspx
There were a couple of other cool utilities/products that came up as well that I’ll be trying out/writing about.