Is it possible to marshall LPDATAOBJECT or HGLOBAL from C++ to Managed Code (C#) ?

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
I have a piece of C++ that handles a drop event. I need to get a list of all the file names that were dragged from explorer, and pass them to managed code for asynchronous processing. Rather than pull all the file names out of the DataObject,
and then build an array of strings to pass to managed code, I was wondering whether I can marshal either the DatObject, or its derivates, HGLOBAL or HDROP (See code below) into the managed code and pull the file / directory names out using C# for processing.
The problem is COM marshalling is still rather new to me, and before I spend hours stumbling through trying to make it work, I was wondering :
1) Can this be done?
2) Even if it can be done, is this a good idea, or is it better to just suck it up and create the array of strings, or something similar, and pass that array to managed code ?
Id prefer to just pass the HDROP object in _DoDdrop_HDROP to the managed code, or even pass the DataObject to managed code in _DoDrop().
Here is the code I have that handles the drop. _DoDrop(LPDATAOBJECT) is called first from the IDropTarget::Drop method, which in turn calls _DoDROP_HDROP(HGLOBAL) to handle the data from Explorer.

<div style="color:Black;background-color:White; <pre>
<span style="color:Green; //pidlDropDest is the relative pidl to m_pidlPath
HRESULT CFolderViewImplFolder::_DoDrop(LPDATAOBJECT pDataObj ,
DWORD dwDropEffect ,
LPITEMIDLIST pidlDropDest ,
UINT <span style="color:Green; /* JIM iFmtIdx */)
{


HRESULT Hr = E_INVALIDARG;
STGMEDIUM stgmed;
FORMATETC fe1 = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
<span style="color:Blue; if( SUCCEEDED( pDataObj->GetData(&fe1, &stgmed) ) )
{
Hr = _DoDrop_HDROP(stgmed.hGlobal, dwDropEffect,pidlDropDest);
::ReleaseStgMedium(&stgmed);
<span style="color:Blue; return Hr;
}

<span style="color:Blue; return Hr;
}






HRESULT CFolderViewImplFolder::_DoDrop_HDROP(HGLOBAL hMem,
DWORD <span style="color:Green; /* JIM dwDropEffect */,
LPITEMIDLIST <span style="color:Green; /*JIM pidlDropDest */)
{

HRESULT Hr= S_OK;
HDROP hDrop = (HDROP) ::GlobalLock(hMem);
TCHAR szFileName[MAX_PATH]={0};
UINT nFiles = ::DragQueryFile(hDrop, (UINT) -1, NULL, 0);
<span style="color:Blue; for( UINT i=0; i<nFiles; i++ )
{
<span style="color:Green; // Get dragged filename

<span style="color:Blue; if( ::DragQueryFile(hDrop, i, szFileName, MAX_PATH)==0 )
{
<span style="color:Green; // m_PidlMgr.Delete(pidlComplexDest);
::GlobalUnlock(hMem);
<span style="color:Blue; return E_FAIL;
}


<span style="color:Blue; for(UINT i=0; i<nFiles; i++ )
{
<span style="color:Green; // Get dragged filename

<span style="color:Blue; if( ::DragQueryFile(hDrop, i, szFileName, MAX_PATH)==0 )
{
::GlobalUnlock(hMem);
<span style="color:Green; // I COULD CREATE AN ARRAY HERE, BUT ID RATHER NOT
<span style="color:Blue; return E_FAIL;
}

}

::GlobalUnlock(hMem);

<span style="color:Green; // INSTEAD I"D RATHER DO ManagedCode->ProcessDroppedData(HDROP),
<span style="color:Green; // OR SKIP THIS FUNCTION CALL ALL TOGETHER AND PASS THE DATAOBJECT TO
<span style="color:Green; // MANAGED CODE IN _DoDrop() above

<span style="color:Blue; return Hr;
}
[/code]

Im not sure how to receive this type of object in managed code, any advice on this topic would be greatly appreciated.

View the full article
 
Back
Top