之前使用网上下载的CDataSource、CDataObject—等等类实现了 对文件拖放的目的。
然而,此类原码竟是VC++代码。并且拖放时,鼠标下文件图标的显示也并不能实现。因此,自己从收集到的资料BCB的原码。
拖放的原码网上比较多,且简单。因此在此说明一下对于显示图标的步骤:
首先,对于CDataObject类的SetData方法,不能把非TYMED_HGLOBAL数据排除在外。
HRESULT __stdcall cdataobject::SetData (FORMATETC *pFormatEtc, STGMEDIUM *pMedium, BOOL fRelease)
{
HRESULT res=FindFormatEtc(pFormatEtc,pMedium,true);
if (m_pStgMedium[res].tymed)
{
ReleaseStgMedium ( &m_pStgMedium[res] );
ZeroMemory (&m_pStgMedium[res], sizeof(STGMEDIUM) );
}
m_pStgMedium[res]=*pMedium;
m_pFormatEtc[res].tymed=m_pStgMedium[res].tymed;
if(m_pStgMedium[res].tymed==TYMED_HGLOBAL)
{
m_pStgMedium[res].hGlobal=DupMem(pMedium->hGlobal);//必须分配足够的内存空间和拷贝数据。
}
if(GetCanonicalIUnknown(m_pStgMedium[res].pUnkForRelease)==
GetCanonicalIUnknown(static_cast<IDataObject*>(this)))
{
m_pStgMedium[res].pUnkForRelease->Release();
m_pStgMedium[res].pUnkForRelease = NULL;
return S_OK;
}
return S_OK;
}
其次 ,在BragBegin中写入图形
IDataObject *pDataObject;
IDropSource *pDropSource;
DWORD dwEffect;
DWORD dwResult;
//
// STGMEDIUM TYMED_HGLOBAL
//
FORMATETC fmtetc = { CF_HDROP|CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stgmed = { TYMED_HGLOBAL, { 0 }, 0 };
HGLOBAL hMem = GlobalAlloc(GHND|GMEM_SHARE,(DWORD) (sizeof(DROPFILES)+_MAX_PATH+1));
LPDROPFILES pDropFiles= (LPDROPFILES)GlobalLock(hMem);
pDropFiles->pFiles = sizeof(DROPFILES);
pDropFiles->fWide=FALSE;
lstrcpy((LPSTR)((LPSTR)(pDropFiles)+sizeof(DROPFILES)),TEXT(filename));
((LPSTR)pDropFiles)[sizeof(DROPFILES)+strlen(filename)]=0;
GlobalUnlock(hMem);
stgmed.hGlobal=hMem;
CreateDropSource(&pDropSource);
CreateDataObject(&fmtetc,&stgmed,1,&pDataObject);
IDragSourceHelper *pDragSrcHlp=NULL;
CoCreateInstance(CLSID_DragDropHelper, NULL,CLSCTX_ALL
, IID_IDragSourceHelper, (LPVOID *)&pDragSrcHlp);
if(pDragSrcHlp)
{
SHDRAGIMAGE image={{50,50},{25,25},NULL,0xffffffff};
BYTE bits[50][50][4];
for(int n=0;n<50;n++)for(int m=0;m<50;m++)
{
bits[m][n][0]=m;
bits[m][n][1]=255-m*2;
bits[m][n][2]=255;
bits[m][n][3]=255;
}
image.hbmpDragImage = CreateBitmap(50, 50, 1, 32, bits);
pDragSrcHlp->InitializeFromBitmap(&image,pDataObject);
}
else pDragSrcHlp = 0;
DoDragDrop(pDataObject,pDropSource,DROPEFFECT_COPY|DROPEFFECT_MOVE,&dwEffect);
pDragSrcHlp->Release();
pDataObject->Release();
pDropSource->Release();
return true;
使用到MS的IDragSourceHelper类使写程序更方便,不过该类的具体操作还是不了解。
关键的一步就是pDragSrcHlp->InitializeFromBitmap,使数据写入STGMEDIUM结构中。
再次,在CDataObject的GetData方法里,需要对某些数据执行累加函数。
如:
case TYMED_ISTREAM:
pMedium->pstm->AddRef();
break;
case TYMED_ISTORAGE:
pMedium->pstg->AddRef();
break;
特别注意的一点是: 在拖文件时, 将文件名写入内存,在多文件的情况下,需要以两个字节结尾,即 '00'.否则有乱码
如果各位有些好的思路和想法,可以给我流言:EMAIL :programuser@citiz.net QQ:694796939