|
From: RedLars on 7 May 2008 06:17 Hello, In an application I'm involved with we're trying to get a drag-and- drop functionality to work between a mfc dialog and a .NET forms within the same process. Here is an slightly abbreviate code snippet from mfc part: COleDataSource * pDataSource = new COleDataSource; // fill-in code pDataSource->CacheGlobalData(...); pDataSource->DoDragDrop (); This code works! The correct data is transferred to the destination! The problem now is cleaning up. Adding a delete pDataSource causes an access violation in destination code. What I've noticed is that pDataSource->m_dwRef is increment to 1 on creation and increased to 3 if OnDragEnter\OnDragDrop or OnDragEnter \OnDragLeave occurs in destination code. Seen some code example use the following pattern: pDataSource->DoDragDrop (); if ( pDataSource->m_dwRef <= 1) delete pDataSource; else pDataSource->ExternalRelease(); Does this make sense? After a bit of digging I found out that COleDataSource (actually CCmdTarget ) contains several sort of similar methods: * InternalRelease * ExternalRelease * ExternalDisconnect What is the difference between Internal and External Release? What is the difference between Release and Disconnect? Thanks for any help.
From: Giovanni Dicanio on 7 May 2008 06:57 "RedLars" <Liverpool1892(a)gmail.com> ha scritto nel messaggio news:4463e7a9-21aa-4fec-af81-3d666dfae6ae(a)c65g2000hsa.googlegroups.com... > COleDataSource * pDataSource = new COleDataSource; > // fill-in code > pDataSource->CacheGlobalData(...); > pDataSource->DoDragDrop (); > > This code works! The correct data is transferred to the destination! > The problem now is cleaning up. > > Adding a delete pDataSource causes an access violation in destination > code. > > What I've noticed is that pDataSource->m_dwRef is increment to 1 on > creation and increased to 3 if OnDragEnter\OnDragDrop or OnDragEnter > \OnDragLeave occurs in destination code. Those OLE objects are reference counted, so I would not call 'delete' on them... I would "respect" their contract of AddRef/Release (these are methods present in IUknown, the root interface for COM/OLE objects). > Seen some code example use the following pattern: > > pDataSource->DoDragDrop (); > if ( pDataSource->m_dwRef <= 1) > delete pDataSource; > else > pDataSource->ExternalRelease(); I would just call ->ExternalRelease (or InternalRelease, if there is no aggregation). I think that the difference between External and Internal is about aggregation: External methods like ExternalRelease are to properly manage aggregation. pDataSource->DoDragDrop(); pDataSource->ExternalRelease(); // or // pDataSource->InternalRelease(); // if there's no aggregation I believe that Internal/ExternalRelease will decrement the reference count, and call C++ 'delete' if reference count is 0. However, I'm not sure about that, and I would prefer experimenting with some real code, also considering that you are mixing MFC and managed world of ..NET here... (I think that computer science is an "experimental" science :) we need compilers, debuggers, log files, etc. to diagnose things and try to find solutions to bug.) BTW: I would also post this question in the ATL group. There is a COM very expert there whose name is Igor (T.): he knows a lot about COM and OLE and I believe he will give you a detailed answer... Giovanni
From: Giovanni Dicanio on 7 May 2008 07:23 "Giovanni Dicanio" <giovanni.dicanio(a)invalid.com> ha scritto nel messaggio news:ebcrVFDsIHA.1236(a)TK2MSFTNGP02.phx.gbl... > I would just call ->ExternalRelease (or InternalRelease, if there is no > aggregation). > > I think that the difference between External and Internal is about > aggregation: External methods like ExternalRelease are to properly manage > aggregation. > > pDataSource->DoDragDrop(); > pDataSource->ExternalRelease(); > // or > // pDataSource->InternalRelease(); > // if there's no aggregation > > I believe that Internal/ExternalRelease will decrement the reference > count, and call C++ 'delete' if reference count is 0. I stepped into source code of CCmdTarget::ExternalRelease, and it calls InternalRelease, which in turns calls OnFinalRelease virtual method if reference count reaches value of 0. OnFinalRelease does a 'delete this' as last statement. Giovanni
From: RedLars on 7 May 2008 08:26 On 7 Mai, 12:57, "Giovanni Dicanio" <giovanni.dica...(a)invalid.com> wrote: > "RedLars" <Liverpool1...(a)gmail.com> ha scritto nel messaggionews:4463e7a9-21aa-4fec-af81-3d666dfae6ae(a)c65g2000hsa.googlegroups.com... > > > COleDataSource * pDataSource = new COleDataSource; > > // fill-in code > > pDataSource->CacheGlobalData(...); > > pDataSource->DoDragDrop (); > > > This code works! The correct data is transferred to the destination! > > The problem now is cleaning up. > > > Adding a delete pDataSource causes an access violation in destination > > code. > > > What I've noticed is that pDataSource->m_dwRef is increment to 1 on > > creation and increased to 3 if OnDragEnter\OnDragDrop or OnDragEnter > > \OnDragLeave occurs in destination code. > > Those OLE objects are reference counted, so I would not call 'delete' on > them... > I would "respect" their contract of AddRef/Release (these are methods > present in IUknown, the root interface for COM/OLE objects). > > > Seen some code example use the following pattern: > > > pDataSource->DoDragDrop (); > > if ( pDataSource->m_dwRef <= 1) > > delete pDataSource; > > else > > pDataSource->ExternalRelease(); > > I would just call ->ExternalRelease (or InternalRelease, if there is no > aggregation). So you are saying this would be a good solution: if ( pDataSource->m_dwRef <= 1) pDataSource->InternalRelease(); else pDataSource->ExternalRelease(); > I think that the difference between External and Internal is about > aggregation: External methods like ExternalRelease are to properly manage > aggregation. > > pDataSource->DoDragDrop(); > pDataSource->ExternalRelease(); > // or > // pDataSource->InternalRelease(); > // if there's no aggregation > > I believe that Internal/ExternalRelease will decrement the reference count, > and call C++ 'delete' if reference count is 0. > > However, I'm not sure about that, and I would prefer experimenting with some > real code, also considering that you are mixing MFC and managed world of > .NET here... (I think that computer science is an "experimental" science :) > we need compilers, debuggers, log files, etc. to diagnose things and try to > find solutions to bug.) > Will continue to experiment. > BTW: I would also post this question in the ATL group. > There is a COM very expert there whose name is Igor (T.): he knows a lot > about COM and OLE and I believe he will give you a detailed answer... > > Giovanni Will post it there aswell. Thanks for your help.
From: Giovanni Dicanio on 7 May 2008 08:55 "RedLars" <Liverpool1892(a)gmail.com> ha scritto nel messaggio news:b55f0e7b-abc4-4f7b-8ab8-692b95059a0e(a)p25g2000hsf.googlegroups.com... > So you are saying this would be a good solution: > > if ( pDataSource->m_dwRef <= 1) > pDataSource->InternalRelease(); > else > pDataSource->ExternalRelease(); No, I would just do: pDataSource->InternalRelease(); (or pDataSource->ExternalRelease() if you are using aggregation.) Internal/ExternalRelease will do 'delete this' if reference count is 0. Giovanni
|
Next
|
Last
Pages: 1 2 3 Prev: Zoom buttons in toolbar Next: communication between C# dll and C++ dll ??? |