Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

prblems with GlobalFree in drag and drop

Status
Not open for further replies.

dima2

Programmer
Jan 20, 2002
85
0
0
LB
hi,
I'm trying to implement drag and drop property in my dialog based application,
by using COleDropTarget and COleDataSource.
OnBeginDrag I allocate global memory, cache global data and call DoDragDrop

HANDLE hdata = GlobalAlloc ( GPTR, sizeof ( TVITEM ) ) ;
TVITEM *pItem = ( TVITEM* ) ::GlobalLock ( hdata ) ;
::GlobalUnlock ( hdata ) ;
//here I fill the pItem fields
COleDataSource m_coledatasource ;
m_coledatasource.CacheGlobalData ( MY_REGISTERED_FORMAT, hdata ) ;

DROPEFFECT dropeffect = m_coledatasource.DoDragDrop( DROPEFFECT_COPY | DROPEFFECT_MOVE ) ;


in the OnDrop function I handle the dropping and call GlobalFree

BOOL CMyOleDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point )
{
HANDLE hGlobal = pDataObject -> GetGlobalData ( MainDlg->contact_cp_format ) ;
TVITEM *pItem = ( TVITEM* ) GlobalLock ( hGlobal ) ;
//do the actual dropping
GlobalUnlock ( hGlobal ) ;
GlobalFree(hGlobal);
}

The problem I'm facing is when I try to call GlobalFree(hdata)
after the DoDragDrop returns with the DROPEFFECT_NONE

the problem appears only when I start to drag a certain item then cancel the drop, then if i try to drag and drop the same item again
exceptions occur when I try to access the pItem fields in the OnDrop function.

this behaviour disappears if I remove the GlobalFree(hdata).

what am i missing?
how does the global alloc and free work?
is it freeing something related to my item?

I also noticed that "always" the handle retuned by GetGlobalData is not the same one that was returned when GlobalAlloc was called. Is that normal for CacheGlobalData and GetGlobalData?

any help would be greatly apreciated
 
One possibility is that you should only perform the GlobalUnlock in the OnDrop method since the data is cached in OnBeginDrag and then accessed when processing another notification message (specifically dropping) and therefore the data needs to be valid for the lifetime of multiple notification messages. If you unlock hData in OnBeginDrag by calling GlobalUnlock and the lock count goes to zero, by the time the OnDrop message is called the cached data block will no longer be valid potentially causing all sorts of problems.

You should then make the hData a global/member variable in case the user aborts the drag and drop procedure by dropping outside of the window (hData would need to be a global/member variable so you could call GlobalUnlock on it.)


Another possibility is that you should fill in the pItem fields, cache the data THEN unlock the handle.

In other words:

TVITEM *pItem = ( TVITEM* ) ::GlobalLock ( hdata ) ;
//here I fill the pItem fields
COleDataSource m_coledatasource ;
m_coledatasource.CacheGlobalData ( MY_REGISTERED_FORMAT, hdata ) ;
::GlobalUnlock ( hdata ) ;

instead of:

TVITEM *pItem = ( TVITEM* ) ::GlobalLock ( hdata ) ;
::GlobalUnlock ( hdata ) ;
//here I fill the pItem fields
COleDataSource m_coledatasource ;
m_coledatasource.CacheGlobalData ( MY_REGISTERED_FORMAT, hdata ) ;


Remember in either case that once the lock count on a block of memory goes to zero the opearting system is free to remove the block at its discretion. GlobalUnlock decrements this lock count.


I apologize for the vagueness but I have not done much with dragging and dropping.

Hope this helps! Happy coding. :)
*~-> EOR Candy <-~*
 
thanks for your help,
however I tried both solutions and none of them solved the problem.

As a matter of fact I also noticed that whether I free the data or not all calls to GlobalAlloc return the same handle (the same pointer is always returned by GlobalLock)
is it possible for the system to re-allocate memory that has not been freed, Or is there something that's somehow freeing the data without my intervention?
I'm stuck on this!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top