Navigation:  Tutorial >

Managing memory pointers with gwst objects

Previous pageReturn to chapter overviewNext page

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.

// --------------------------------------------------------------