The ot4xb structure objects (gwst subclasses) can work using a internal Xbase++ character buffer or using true memory pointers.
When you instantiate a gwst class, the internal buffer of the object contains initially NIL. The first time the buffer is needed if the buffer still not exist gwst will call automatically to the method ::_zeromemory_() in order to create the required character buffer. So you can assign/retrieve a member value or pass the gwst object as a param of nFpCall() (or any other ot4xb call functions) without take care of initializing the internal buffer.
local oRect := RECT():New()
@user32:GetWindowRect( hWnd , oRect)
nFpCall() will lock the Xbase++ internal memory pointer before perform the call and release it after the function returns.
When that we need to handle is a provided memory pointer, gwst provide 2 methods ::_link_() and ::_unlink() to attach or detach a memory pointer to our structure.
case nMsg == WM_GETMINMAXINFO
// lParam will contain a pointer to a MINMAXINFO structure
oMinMax := MINMAXINFO():New():_link_( lParam , .F. )
oMinMax:ptMaxSize.x := 800
oMinMax:ptMaxSize.y := 600
oMinMax:ptMinSize.x := 640
oMinMax:ptMinSize.y := 480
return 0
Sometimes our structure pointer must survive outside of the function call boundary, in this case we need to allocate memory for our structure. gwst provides 2 methods to do it ::_alloc_() and ::_free_()
In the following example we need to attach some info to a window property and retrieve it later.
BEGIN STRUCTURE MyCustomStruct
MEMBER HWND hWndClient;
MEMBER LONG nLastStatus;
// ... more members
END STRUCTURE
The first we have define a custom structure to manage our data
function MyStartFunction(hWnd,hWndClient)
local oSt := MyCustomStruct():New()
oSt will contain now a instance of our gwst objec. The buffer is still uninitialized until you access its members or pass the object to an ot4xb *FpCall function.
oSt:_alloc_() // allocate _xgrab() memory to hold the structure
Now we create memory for our structure.
// oSt:_alloc_() is equivalent to oSt:_link_( _xgrab( oSt:_sizeof_() ) )
oSt:hWndClient := hWndClient
oSt:nLastStatus := 1
After assigning our values we store the pointer to our structure inside a window property to retrieve it later.
@user32:SetPropA(hWnd,"pMyCustomData", oSt )
// this is equivalen to @user32:SetPropA(hWnd,"pMyCustomData", oSt:_addressof_() )
return NIL
function JustAnotherFunction(hWnd)
local pData := @user32:GetPropA(hWnd,"pMyCustomData") // Retrieve the pointer
The first we need to get the memory pointer.
local oSt
if pData == 0
return .F.
end
If the pointer is valid we create a gwst object for our structure and link the memory pointer to it.
oSt := MyCustomStruct():New():_link_(pData,.F.) // link the gwst object
DoSomethingWith( hWnd , oSt:hWndClient , @oSt:nLastStatus )
return .T.
And finally we must release the allocated memory when not needed anymore.
// --------------------------------------------------------------
function OnDestroy( hwnd )
local pData := @user32:GetPropA(hWnd,"pMyCustomData")
if pData == 0
return .F.
end
@user32:RemovePropA(hWnd,"pMyCustomData")
_xfree(pData)
// or MyCustomStruct():New():_link_(pData,.F.):_free_(.F.)
return .T.
// --------------------------------------------------------------