FORMATETC, 描述OLE数据,target从IDATAOBJECT请求某种格式数据
STGMEDIUM,存储OLE数据,从IDATAOBJECT保存数据
IEnumFORMATETC::GetData()由target调用
EnumFormatEtc由IDropSource调用
DoDragDrop引发的操作:
1.
主要是生成一个IEnumFORMATETC对象
CDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
{
SCODE sc = S_OK;
FORMATETC fmtetc;
fmtetc.cfFormat = CF_TEXT;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.tymed = TYMED_HGLOBAL;
fmtetc.ptd = NULL;
fmtetc.lindex = -1;
if (dwDirection == DATADIR_GET){
*ppenumFormatEtc = new enumfetc2(1, &fmtetc);
if (*ppenumFormatEtc == NULL)
sc = E_OUTOFMEMORY;
} else if (dwDirection == DATADIR_SET){
// A data transfer object that is used to transfer data
// (either via the clipboard or drag/drop does NOT
// accept SetData on ANY format.
sc = E_NOTIMPL;
goto error;
} else {
sc = E_INVALIDARG;
goto error;
}
error:
return ResultFromScode(sc);
}
2.主要是复制对象
STDMETHODIMP
CDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
{
HGLOBAL hText;
LPSTR pszText;
pmedium->tymed = NULL;
pmedium->pUnkForRelease = NULL;
pmedium->hGlobal = NULL;
// This method is called by the drag-drop target to obtain the text
// that is being dragged.
if (pformatetc->cfFormat == CF_TEXT &&
pformatetc->dwAspect == DVASPECT_CONTENT &&
pformatetc->tymed == TYMED_HGLOBAL)
{
hText = GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT, sizeof(m_szBuffer)+1);
if (!hText)
return ResultFromScode(E_OUTOFMEMORY);
pszText = (LPSTR)GlobalLock(hText);
lstrcpy(pszText, m_szBuffer);
GlobalUnlock(hText);
pmedium->tymed = TYMED_HGLOBAL;
pmedium->hGlobal = hText;
return ResultFromScode(S_OK);
}
return ResultFromScode(DATA_E_FORMATETC);
}
target:
IDropTarget::DropEnter(LPDATAOBJECT pDataObj..)
IDropTarget::DropOver(LPDATAOBJECT pDataObj..)
这两个参数都是Source new出来的CDataObject对象
IDropTarget对象New出来后会被多次调用IDropTarget::Next()