Здравствуйте OlegO, Вы писали:
OO>Привиди пример кода, для начала как ты данные CF_HDROP формируешь и передаешь при запросе GetData.
весь проект лежит на
ftp://194.44.16.56/pub/flyview/FlyView.rar, а сама реализация IDataObject следующая:
/****************************************************************************************************/
class CDataSourceRoot;
typedef CComObject<CDataSourceRoot> CDataSource;
typedef set<string> string_set;
class CDataSourceRoot :
public CComObjectRoot,
public IDataObject
{
public:
static int CF_FLYVIEW;
CComPtr<IDataAdviseHolder> m_spDataAdviseHolder;
BEGIN_COM_MAP(CDataSourceRoot)
COM_INTERFACE_ENTRY(IDataObject)
END_COM_MAP()
vector<char> m_Data;
DWORD m_PreferredEffect;
DWORD m_PerformedEffect;
DWORD m_PasteSucceeded;
CDataSourceRoot()
{
m_PreferredEffect = 0;
m_PerformedEffect = 0;
m_PasteSucceeded = 0;
}
~CDataSourceRoot()
{
ATLTRACE("~CDataSourceRoot\n");
}
static HRESULT Create(const string_set & names, DWORD effect, CDataSource ** pp)
{
HRESULT hr = CDataSource::CreateInstance(pp);
if(FAILED(hr))
return hr;
CComPtr<CDataSource> p = *pp;
for(string_set::const_iterator i=names.begin(); i!=names.end(); i++)
{
string name = *i;
p->m_Data.insert(p->m_Data.end(), name.begin(), name.end());
p->m_Data.insert(p->m_Data.end(), '\0');
}
p->m_Data.insert(p->m_Data.end(), '\0');
p->m_Data.insert(p->m_Data.end(), '\0');
p->m_Data.insert(p->m_Data.end(), '\0');
p->m_Data.insert(p->m_Data.end(), '\0');
p->m_PreferredEffect = effect;
hr = CreateDataAdviseHolder(&p->m_spDataAdviseHolder);
if(FAILED(hr))
return hr;
ATLTRACE("Create\n");
p->InternalAddRef();
return S_OK;
}
STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
HRESULT res = QueryGetData(pformatetcIn);
if(res!=S_OK)
{
ATLTRACE("GetData: error %x\n", res);
return res;
}
pmedium->pUnkForRelease = 0;
pmedium->tymed = TYMED_HGLOBAL;
memset(pmedium, 0, sizeof(STGMEDIUM));
if(pformatetcIn->cfFormat == CF_HDROP)
{
ATLTRACE("GetData: CF_HDROP: %d\n", m_Data.size());
pmedium->hGlobal = GlobalAlloc(GPTR, m_Data.size()+sizeof(DROPFILES)+5);
if(!pmedium->hGlobal)
{
ATLTRACE("GetData: Out of memory\n");
return E_OUTOFMEMORY;
}
DROPFILES * d = (DROPFILES*)GlobalLock(pmedium->hGlobal);
d->pFiles = sizeof(DROPFILES);
d->fNC = true;
d->fWide = false;
d->pt = CPoint(0,0);
memcpy(((BYTE*)d)+sizeof(DROPFILES), m_Data.begin(), m_Data.size());
GlobalUnlock(pmedium->hGlobal);
ATLTRACE("GetData: %d files\n", DragQueryFile((HDROP)pmedium->hGlobal, -1, 0, 0));
return S_OK;
}
{
char buf[255];
GetClipboardFormatName(pformatetcIn->cfFormat, buf, 255);
ATLTRACE("GetData: required format %s\n", buf);
}
return DV_E_FORMATETC;
}
STDMETHOD(GetDataHere)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
ATLTRACE("GetDataHere\n");
return E_NOTIMPL;
}
STDMETHOD(SetData)(FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease)
{
return E_NOTIMPL;
}
STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* pformatectIn, FORMATETC* pformatetcOut)
{
ATLTRACE("GetCanonicalFormatEtc\n");
return DATA_S_SAMEFORMATETC;
}
STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
{
CEnum * p;
CEnum::Create(dwDirection, &p);
*ppenumFormatEtc = p;
return S_OK;
}
STDMETHOD(QueryGetData)(FORMATETC* pformatetc)
{
for(vector<FORMATETC>::iterator i = CEnumRoot::s_Get.begin(); i!=CEnumRoot::s_Get.end(); i++)
{
if(pformatetc->cfFormat == i->cfFormat)// && pformatetc->cfFormat != CF_PREFERREDDROPEFFECT)
{
if(pformatetc->lindex != -1)
return DV_E_LINDEX;
if(!(pformatetc->tymed&TYMED_HGLOBAL))
return DV_E_TYMED;
return S_OK;
}
}
return DV_E_FORMATETC;
}
STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink,
DWORD *pdwConnection)
{
ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::DAdvise\n"));
return m_spDataAdviseHolder->Advise((IDataObject*)this, pformatetc, advf, pAdvSink, pdwConnection);
}
STDMETHOD(DUnadvise)(DWORD dwConnection)
{
ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::DUnadvise\n"));
return m_spDataAdviseHolder->Unadvise(dwConnection);
}
STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise)
{
ATLTRACE2(atlTraceControls,2,_T("IDataObjectImpl::EnumDAdvise\n"));
return m_spDataAdviseHolder->EnumAdvise(ppenumAdvise);
}
};