void _ecore_win32_dnd_drop_source_free(void *drop_source)
{
   if (!drop_source)
     return;

   IDropSource *object = (IDropSource *)drop_source;
   object->Release();
}
void Explorerplusplus::OnAddressBarBeginDrag(void)
{
	IDragSourceHelper *pDragSourceHelper = NULL;
	IDropSource *pDropSource = NULL;
	HRESULT hr;

	hr = CoCreateInstance(CLSID_DragDropHelper,NULL,CLSCTX_ALL,
		IID_IDragSourceHelper,(LPVOID *)&pDragSourceHelper);

	if(SUCCEEDED(hr))
	{
		hr = CreateDropSource(&pDropSource,DRAG_TYPE_LEFTCLICK);

		if(SUCCEEDED(hr))
		{
			LPITEMIDLIST pidlDirectory = m_pActiveShellBrowser->QueryCurrentDirectoryIdl();

			FORMATETC ftc[2];
			STGMEDIUM stg[2];

			SetFORMATETC(&ftc[0],(CLIPFORMAT)RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR),
				NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL);

			HGLOBAL hglb = GlobalAlloc(GMEM_MOVEABLE,1000);

			FILEGROUPDESCRIPTOR *pfgd = static_cast<FILEGROUPDESCRIPTOR *>(GlobalLock(hglb));

			pfgd->cItems = 1;

			FILEDESCRIPTOR *pfd = (FILEDESCRIPTOR *)((LPBYTE)pfgd + sizeof(UINT));

			/* File information (name, size, date created, etc). */
			pfd[0].dwFlags			= FD_ATTRIBUTES|FD_FILESIZE;
			pfd[0].dwFileAttributes	= FILE_ATTRIBUTE_NORMAL;
			pfd[0].nFileSizeLow		= 16384;
			pfd[0].nFileSizeHigh	= 0;

			/* The name of the file will be the folder name, followed by .lnk. */
			TCHAR szDisplayName[MAX_PATH];
			GetDisplayName(pidlDirectory,szDisplayName,SHGDN_INFOLDER);
			StringCchCat(szDisplayName,SIZEOF_ARRAY(szDisplayName),_T(".lnk"));
			StringCchCopy(pfd[0].cFileName,SIZEOF_ARRAY(pfd[0].cFileName),szDisplayName);

			GlobalUnlock(hglb);

			stg[0].pUnkForRelease	= 0;
			stg[0].hGlobal			= hglb;
			stg[0].tymed			= TYMED_HGLOBAL;

			/* File contents. */
			SetFORMATETC(&ftc[1],(CLIPFORMAT)RegisterClipboardFormat(CFSTR_FILECONTENTS),
				NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL);

			hglb = GlobalAlloc(GMEM_MOVEABLE,16384);

			IShellLink *pShellLink = NULL;
			IPersistStream *pPersistStream = NULL;
			HRESULT hr;

			hr = CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,
				IID_IShellLink,(LPVOID*)&pShellLink);

			if(SUCCEEDED(hr))
			{
				TCHAR szPath[MAX_PATH];

				GetDisplayName(pidlDirectory,szPath,SHGDN_FORPARSING);

				pShellLink->SetPath(szPath);

				hr = pShellLink->QueryInterface(IID_IPersistStream,(LPVOID*)&pPersistStream);

				if(SUCCEEDED(hr))
				{
					IStream *pStream = NULL;

					CreateStreamOnHGlobal(hglb,FALSE,&pStream);

					hr = pPersistStream->Save(pStream,TRUE);
				}
			}

			GlobalUnlock(hglb);

			stg[1].pUnkForRelease	= 0;
			stg[1].hGlobal			= hglb;
			stg[1].tymed			= TYMED_HGLOBAL;

			IDataObject *pDataObject = NULL;
			POINT pt = {0,0};

			hr = CreateDataObject(ftc,stg,&pDataObject,2);

			pDragSourceHelper->InitializeFromWindow(m_hAddressBar,&pt,pDataObject);

			DWORD dwEffect;

			DoDragDrop(pDataObject,pDropSource,DROPEFFECT_LINK,&dwEffect);

			CoTaskMemFree(pidlDirectory);

			pDataObject->Release();
			pDropSource->Release();
		}

		pDragSourceHelper->Release();
	}
}
// The user started to move a link in the trace ctl
int POTraceCtl::OnLinkDragBegin(const String& strUrl)
{
	int nDragResult = dragNone;

	///////////////////////////////////////////////////////////
	// Allocate resource for the data to share between PngOptimizer and the target application
	// Here it will be some bytes to store a file path
	HGLOBAL  hgDrop = CreateDropFilesW(strUrl);
	/////////////////////////////////////////////////////////

	FORMATETC etc;
	etc.cfFormat = CF_HDROP;	// CLIPFORMAT
	etc.ptd = NULL;				// DVTARGETDEVICE*
	etc.dwAspect = DVASPECT_CONTENT;	// DWORD
	etc.lindex = -1;			// LONG
	etc.tymed = TYMED_HGLOBAL;	// DWORD

	STGMEDIUM med;
	med.tymed = TYMED_HGLOBAL;
	med.hGlobal = hgDrop;
	med.pUnkForRelease = NULL;

	IDataObject* pDataObject = new PlopDataObject;
	if( pDataObject )
	{
		pDataObject->SetData(&etc, &med, TRUE);
		
		IDropSource* pDropSource = new PlopDropSource; 
		if( pDropSource )
		{
			// Forbid drag-and-drop on ourself
			::DragAcceptFiles( ::GetParent(m_handle), FALSE);

			// DoDragDrop will manage the rest of the action and will return when a drag-and-drop action is done
			DWORD nEffect = 0;
			HRESULT hr = ::DoDragDrop(pDataObject, pDropSource, DROPEFFECT_MOVE | DROPEFFECT_COPY | DROPEFFECT_LINK, &nEffect);
		
			// Unless an optimization is in progress, enable again drag-and-drop on ourself
			if( !m_pApp->IsJobRunning() )
			{
				::DragAcceptFiles( ::GetParent(m_handle), TRUE);
			}

			if( hr == DRAGDROP_S_DROP )
			{
				// Testing proved that we cannot rely on the return code given by Windows to know the exact 
				// operation that occurred during DoDragDrop. It depends on the target application, 
				// it depends on the Windows version and maybe the position of the stars in the sky

				// So we check ourselves if DoDragDrop performed a copy or a move by testing if our file is still here

				if( !File::Exists(strUrl) )
				{
					// The source file does not exist anymore, then it was a move operation
					nDragResult = dragMove;
				}
				else
				{
					nDragResult = dragCopy;
				}
			}
			pDropSource->Release();
		}
		pDataObject->Release();
	}

	GlobalFree(hgDrop);

	return nDragResult;
}