Skip to content

Instantly share code, notes, and snippets.

@yohhoy
Created Jul 5, 2012
Embed
What would you like to do?
OLE Drag & Drop sample code
/*
* OLE Drag and Drop module
*
* Copyright(c) 2001 yoh(yohhoy)
*/
#define STRICT
#define NONAMELESSUNION
#define COBJMACROS
#include <windows.h>
#include "oledd.h"
/* malloc/free compatible function */
#define xalloc(_s) ((void *)GlobalAlloc(GPTR, (_s)))
#define xfree(_p) ((void)GlobalFree((HGLOBAL)(_p)))
typedef struct tagOLEEnumFORMATETC { /* IEnumFORMATETC */
IEnumFORMATETC super;
ULONG m_cRefCnt;
FORMATETC *m_array;
ULONG m_size, m_cur;
} OLEEnumFORMATETC;
typedef struct tagOLEDataObject { /* IDataObject */
IDataObject super;
ULONG m_cRefCnt;
FORMATETC **m_fmts;
STGMEDIUM **m_stgs;
ULONG m_size;
} OLEDataObject;
typedef struct tagOLEDropSource { /* IDropSource */
IDropSource super;
ULONG m_cRefCnt;
OLEDDDROPSOURCE m_funcs;
LPVOID m_data;
} OLEDropSource;
typedef struct tagOLEDropTarget { /* IDropTarget */
IDropTarget super;
ULONG m_cRefCnt;
OLEDDDROPTARGET m_funcs;
LPVOID m_data;
} OLEDropTarget;
/* virtual function table */
static IEnumFORMATETCVtbl m_OLEEnumFORMATETCVtbl;
static IDataObjectVtbl m_OLEDataObjectVtbl;
static IDropSourceVtbl m_OLEDropSourceVtbl;
static IDropTargetVtbl m_OLEDropTargetVtbl;
/* helper function */
static void CopySTGMEDIUM(STGMEDIUM *pdest, const STGMEDIUM *psrc, const FORMATETC *pfmt)
{
pdest->tymed = psrc->tymed;
switch (psrc->tymed) {
case TYMED_HGLOBAL:
pdest->u.hGlobal = (HGLOBAL)OleDuplicateData(psrc->u.hGlobal, pfmt->cfFormat, (UINT)NULL);
break;
case TYMED_GDI:
pdest->u.hBitmap = (HBITMAP)OleDuplicateData(psrc->u.hBitmap, pfmt->cfFormat, (UINT)NULL);
break;
case TYMED_MFPICT:
pdest->u.hMetaFilePict = (HMETAFILEPICT)OleDuplicateData(psrc->u.hMetaFilePict, pfmt->cfFormat, (UINT)NULL);
break;
case TYMED_ENHMF:
pdest->u.hEnhMetaFile = (HENHMETAFILE)OleDuplicateData(psrc->u.hEnhMetaFile, pfmt->cfFormat, (UINT)NULL);
break;
case TYMED_FILE:
pdest->u.lpszFileName = (LPOLESTR)OleDuplicateData(psrc->u.lpszFileName, pfmt->cfFormat, (UINT)NULL);
break;
case TYMED_ISTREAM:
pdest->u.pstm = psrc->u.pstm;
IStream_AddRef(psrc->u.pstm);
break;
case TYMED_ISTORAGE:
pdest->u.pstg = psrc->u.pstg;
IStorage_AddRef(psrc->u.pstg);
break;
case TYMED_NULL:
default:
break;
}
pdest->pUnkForRelease = psrc->pUnkForRelease;
if (psrc->pUnkForRelease != NULL)
IUnknown_AddRef(psrc->pUnkForRelease);
}
/*
* OLEEnumFORMATETC implementation
*/
static OLEEnumFORMATETC *OLEEnumFORMATETC_new(FORMATETC **array, ULONG size)
{
OLEEnumFORMATETC *ptr;
ULONG i;
ptr = xalloc(sizeof(OLEEnumFORMATETC));
if (ptr != NULL) {
ptr->super.lpVtbl = &m_OLEEnumFORMATETCVtbl;
ptr->m_cRefCnt = 0;
ptr->m_array = xalloc(sizeof(FORMATETC) * size);
for (i = 0; i < size; i++)
ptr->m_array[i] = *array[i];
ptr->m_size = size;
ptr->m_cur = 0;
}
return ptr;
}
static OLEEnumFORMATETC *OLEEnumFORMATETC_copy(OLEEnumFORMATETC *src)
{
OLEEnumFORMATETC *ptr;
ptr = xalloc(sizeof(OLEEnumFORMATETC));
if (ptr != NULL) {
ptr->super.lpVtbl = &m_OLEEnumFORMATETCVtbl;
ptr->m_cRefCnt = 0;
ptr->m_array = xalloc(sizeof(FORMATETC) * src->m_size);
CopyMemory(ptr->m_array, src->m_array, sizeof(FORMATETC) * src->m_size);
ptr->m_size = src->m_size;
ptr->m_cur = src->m_cur;
}
return ptr;
}
static void OLEEnumFORMATETC_delete(OLEEnumFORMATETC *ptr)
{
xfree(ptr->m_array);
xfree(ptr);
}
static STDMETHODIMP OLEEnumFORMATETC_QueryInterface(OLEEnumFORMATETC *pThis, REFIID riid, void **ppvObject)
{
*ppvObject = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumFORMATETC)) {
*ppvObject = pThis;
IUnknown_AddRef((IUnknown *)*ppvObject);
return S_OK;
}
return E_NOINTERFACE;
}
static STDMETHODIMP_(ULONG) OLEEnumFORMATETC_AddRef(OLEEnumFORMATETC *pThis)
{
return ++pThis->m_cRefCnt;
}
static STDMETHODIMP_(ULONG) OLEEnumFORMATETC_Release(OLEEnumFORMATETC *pThis)
{
ULONG tmp = --pThis->m_cRefCnt;
if (tmp == 0)
OLEEnumFORMATETC_delete(pThis);
return tmp;
}
static STDMETHODIMP OLEEnumFORMATETC_Next(OLEEnumFORMATETC *pThis, ULONG celt, LPFORMATETC pfmt, ULONG *pceltFetched)
{
ULONG num = celt;
if (pceltFetched != NULL)
*pceltFetched = 0;
if (celt <= 0 || pfmt == NULL || pThis->m_cur >= pThis->m_size)
return S_FALSE;
/* pceltFetched can be NULL only for 1 item request */
if (pceltFetched == NULL && celt != 1)
return S_FALSE;
while (pThis->m_cur < pThis->m_size && num > 0) {
*pfmt++ = pThis->m_array[pThis->m_cur++];
--num;
}
if (pceltFetched != NULL)
*pceltFetched = celt - num;
return (num == 0) ? S_OK : S_FALSE;
}
static STDMETHODIMP OLEEnumFORMATETC_Skip(OLEEnumFORMATETC *pThis, ULONG celt)
{
if ((pThis->m_cur + celt) >= pThis->m_size)
return S_FALSE;
pThis->m_cur += celt;
return S_OK;
}
static STDMETHODIMP OLEEnumFORMATETC_Reset(OLEEnumFORMATETC *pThis)
{
pThis->m_cur = 0;
return S_OK;
}
static STDMETHODIMP OLEEnumFORMATETC_Clone(OLEEnumFORMATETC *pThis, IEnumFORMATETC **ppenum)
{
OLEEnumFORMATETC *pnew;
if (ppenum == NULL)
return E_POINTER;
pnew = OLEEnumFORMATETC_copy(pThis);
if (pnew == NULL)
return E_OUTOFMEMORY;
IUnknown_AddRef((IUnknown *)pnew);
*ppenum = (IEnumFORMATETC *)pnew;
return S_OK;
}
/*
* OLEDataObject implementation
*/
static OLEDataObject* OLEDataObject_new()
{
OLEDataObject *ptr;
ptr = xalloc(sizeof(OLEDataObject));
if (ptr != NULL) {
ptr->super.lpVtbl = &m_OLEDataObjectVtbl;
ptr->m_cRefCnt = 0;
ptr->m_fmts = NULL;
ptr->m_stgs = NULL;
ptr->m_size = 0;
}
return ptr;
}
static void OLEDataObject_delete(OLEDataObject *ptr)
{
ULONG i;
for (i = 0; i < ptr->m_size; i++) {
xfree(ptr->m_fmts[i]);
ReleaseStgMedium(ptr->m_stgs[i]);
xfree(ptr->m_stgs[i]);
}
xfree(ptr->m_fmts);
xfree(ptr->m_stgs);
xfree(ptr);
}
static STDMETHODIMP OLEDataObject_QueryInterface(OLEDataObject *pThis, REFIID riid, void **ppvObject)
{
*ppvObject = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDataObject)) {
*ppvObject = pThis;
IUnknown_AddRef((IUnknown *)*ppvObject);
return S_OK;
}
return E_NOINTERFACE;
}
static STDMETHODIMP_(ULONG) OLEDataObject_AddRef(OLEDataObject *pThis)
{
return ++pThis->m_cRefCnt;
}
static STDMETHODIMP_(ULONG) OLEDataObject_Release(OLEDataObject *pThis)
{
ULONG tmp = --pThis->m_cRefCnt;
if (tmp == 0)
OLEDataObject_delete(pThis);
return tmp;
}
static STDMETHODIMP OLEDataObject_GetData(OLEDataObject *pThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium)
{
FORMATETC *pfmt;
ULONG i;
if (pFormatetc == NULL || pmedium == NULL)
return E_INVALIDARG;
pmedium->u.hGlobal = NULL;
for (i = 0; i < pThis->m_size; i++) {
pfmt = pThis->m_fmts[i];
if (pFormatetc->tymed & pfmt->tymed
&& pFormatetc->dwAspect == pfmt->tymed
&& pFormatetc->cfFormat == pfmt->cfFormat) {
CopySTGMEDIUM(pmedium, pThis->m_stgs[i], pfmt);
return S_OK;
}
}
return DV_E_FORMATETC;
}
static STDMETHODIMP OLEDataObject_GetDataHere(OLEDataObject *pThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium)
{
return E_NOTIMPL;
}
static STDMETHODIMP OLEDataObject_QueryGetData(OLEDataObject *pThis, FORMATETC *pFormatetc)
{
HRESULT result = DV_E_TYMED;
ULONG i;
if (pFormatetc == NULL)
return E_INVALIDARG;
if (!(DVASPECT_CONTENT & pFormatetc->dwAspect))
return DV_E_DVASPECT;
for (i = 0; i < pThis->m_size; i++){
if (pFormatetc->tymed & pThis->m_fmts[i]->tymed) {
if (pFormatetc->cfFormat == pThis->m_fmts[i]->cfFormat)
return S_OK;
result = DV_E_CLIPFORMAT;
} else {
result = DV_E_TYMED;
}
}
return result;
}
static STDMETHODIMP OLEDataObject_GetCanonicalFormatEtc(OLEDataObject *pThis, FORMATETC *pFormatetcIn, FORMATETC *pFormatetcOut)
{
if (pFormatetcOut == NULL)
return E_INVALIDARG;
return DATA_S_SAMEFORMATETC;
}
static STDMETHODIMP OLEDataObject_SetData(OLEDataObject *pThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium, BOOL fRelease)
{
FORMATETC *pfmt;
STGMEDIUM *pstg;
if(pFormatetc == NULL || pmedium == NULL)
return E_INVALIDARG;
pfmt = xalloc(sizeof(FORMATETC));
pstg = xalloc(sizeof(STGMEDIUM));
if (pfmt == NULL || pstg == NULL) {
xfree(pfmt);
xfree(pstg);
return E_OUTOFMEMORY;
}
*pfmt = *pFormatetc;
if (fRelease) {
*pstg = *pmedium;
} else {
CopySTGMEDIUM(pstg, pmedium, pFormatetc);
}
if (pThis->m_size == 0) {
pThis->m_fmts = xalloc(sizeof(FORMATETC *));
pThis->m_stgs = xalloc(sizeof(STGMEDIUM *));
pThis->m_fmts[0] = pfmt;
pThis->m_stgs[0] = pstg;
pThis->m_size = 1;
} else {
FORMATETC **oldfmts = pThis->m_fmts;
STGMEDIUM **oldstgs = pThis->m_stgs;
ULONG oldsize = pThis->m_size;
pThis->m_fmts = xalloc(sizeof(FORMATETC *) * (oldsize + 1));
pThis->m_stgs = xalloc(sizeof(STGMEDIUM *) * (oldsize + 1));
CopyMemory(pThis->m_fmts, oldfmts, sizeof(FORMATETC *) * oldsize);
CopyMemory(pThis->m_stgs, oldstgs, sizeof(STGMEDIUM *) * oldsize);
pThis->m_fmts[oldsize] = pfmt;
pThis->m_stgs[oldsize] = pstg;
pThis->m_size = oldsize + 1;
xfree(oldfmts);
xfree(oldstgs);
}
return S_OK;
}
static STDMETHODIMP OLEDataObject_EnumFormatEtc(OLEDataObject *pThis, DWORD dwDirection, IEnumFORMATETC **ppenumFormatetc)
{
if (ppenumFormatetc == NULL)
return E_POINTER;
*ppenumFormatetc = NULL;
switch (dwDirection) {
case DATADIR_GET:
*ppenumFormatetc = (IEnumFORMATETC *)OLEEnumFORMATETC_new(pThis->m_fmts, pThis->m_size);
if (*ppenumFormatetc == NULL)
return E_OUTOFMEMORY;
IEnumFORMATETC_AddRef(*ppenumFormatetc);
break;
case DATADIR_SET:
/* no implementation */
default:
return E_NOTIMPL;
}
return S_OK;
}
static STDMETHODIMP OLEDataObject_DAdvise(OLEDataObject *pThis, FORMATETC *pFormatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
return OLE_E_ADVISENOTSUPPORTED;
}
static STDMETHODIMP OLEDataObject_DUnadvise(OLEDataObject *pThis, DWORD dwConnection)
{
return OLE_E_ADVISENOTSUPPORTED;
}
static STDMETHODIMP OLEDataObject_EnumDAdvise(OLEDataObject *pThis, IEnumSTATDATA **ppenumAdvise)
{
return OLE_E_ADVISENOTSUPPORTED;
}
/*
* OLEDropSource implementation
*/
static OLEDropSource* OLEDropSource_new(LPOLEDDDROPSOURCE funcs, LPVOID pdat)
{
OLEDropSource *ptr;
ptr = xalloc(sizeof(OLEDropSource));
if (ptr != NULL) {
ptr->super.lpVtbl = &m_OLEDropSourceVtbl;
ptr->m_cRefCnt = 0;
ptr->m_funcs = *funcs;
ptr->m_data = pdat;
}
return ptr;
}
static void OLEDropSource_delete(OLEDropSource *ptr)
{
xfree(ptr);
}
static STDMETHODIMP OLEDropSource_QueryInterface(OLEDropSource *pThis, REFIID riid, void **ppvObject)
{
*ppvObject = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropSource)) {
*ppvObject = pThis;
IUnknown_AddRef((IUnknown *)*ppvObject);
return S_OK;
}
return E_NOINTERFACE;
}
static STDMETHODIMP_(ULONG) OLEDropSource_AddRef(OLEDropSource *pThis)
{
return ++pThis->m_cRefCnt;
}
static STDMETHODIMP_(ULONG) OLEDropSource_Release(OLEDropSource *pThis)
{
ULONG tmp = --pThis->m_cRefCnt;
if (tmp == 0)
OLEDropSource_delete(pThis);
return tmp;
}
static STDMETHODIMP OLEDropSource_QueryContinueDrag(OLEDropSource *pThis, BOOL fEscapePressed, DWORD grfKeyState)
{
if (pThis->m_funcs.lpQueryContinueDrag != NULL)
return pThis->m_funcs.lpQueryContinueDrag(pThis->m_data, fEscapePressed, grfKeyState);
/* デフォルト動作 */
if (fEscapePressed)
return DRAGDROP_S_CANCEL;
if (!(grfKeyState & (MK_LBUTTON|MK_RBUTTON)))
return DRAGDROP_S_DROP;
return S_OK;
}
static STDMETHODIMP OLEDropSource_GiveFeedback(OLEDropSource *pThis, DWORD dwEffect)
{
if (pThis->m_funcs.lpGiveFeedBack != NULL)
return pThis->m_funcs.lpGiveFeedBack(pThis->m_data, dwEffect);
/* デフォルト動作 */
return DRAGDROP_S_USEDEFAULTCURSORS;
}
/*
* OLEDropTarget implementation
*/
static OLEDropTarget* OLEDropTarget_new(OLEDDDROPTARGET *funcs, LPVOID pdata)
{
OLEDropTarget *ptr;
ptr = xalloc(sizeof(OLEDropTarget));
if (ptr != NULL) {
ptr->super.lpVtbl = &m_OLEDropTargetVtbl;
ptr->m_cRefCnt = 0;
ptr->m_funcs = *funcs;
ptr->m_data = pdata;
}
return ptr;
}
static void OLEDropTarget_delete(OLEDropTarget *ptr)
{
xfree(ptr);
}
static STDMETHODIMP OLEDropTarget_QueryInterface(OLEDropTarget *pThis, REFIID riid, void **ppvObject)
{
*ppvObject = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropTarget)) {
*ppvObject = pThis;
IUnknown_AddRef((IUnknown *)*ppvObject);
return S_OK;
}
return E_NOINTERFACE;
}
static STDMETHODIMP_(ULONG) OLEDropTarget_AddRef(OLEDropTarget *pThis)
{
return ++pThis->m_cRefCnt;
}
static STDMETHODIMP_(ULONG) OLEDropTarget_Release(OLEDropTarget *pThis)
{
ULONG tmp = --pThis->m_cRefCnt;
if (tmp == 0)
OLEDropTarget_delete(pThis);
return tmp;
}
static STDMETHODIMP OLEDropTarget_DragEnter(OLEDropTarget *pThis, IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
if (pThis->m_funcs.lpDragEnter != NULL)
return pThis->m_funcs.lpDragEnter(pThis->m_data, pDataObject, grfKeyState, pt, pdwEffect);
/* デフォルト動作 */
*pdwEffect = DROPEFFECT_NONE;
return S_OK;
}
static STDMETHODIMP OLEDropTarget_DragOver(OLEDropTarget *pThis, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
if (pThis->m_funcs.lpDragOver != NULL)
return pThis->m_funcs.lpDragOver(pThis->m_data, grfKeyState, pt, pdwEffect);
/* デフォルト動作 */
*pdwEffect = DROPEFFECT_NONE;
return S_OK;
}
static STDMETHODIMP OLEDropTarget_DragLeave(OLEDropTarget *pThis)
{
if (pThis->m_funcs.lpDragLeave != NULL)
return pThis->m_funcs.lpDragLeave(pThis->m_data);
/* デフォルト動作 */
return S_OK;
}
static STDMETHODIMP OLEDropTarget_Drop(OLEDropTarget *pThis, IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
if (pThis->m_funcs.lpDrop != NULL)
return pThis->m_funcs.lpDrop(pThis->m_data, pDataObject, grfKeyState, pt, pdwEffect);
/* デフォルト動作 */
*pdwEffect = DROPEFFECT_NONE;
return S_OK;
}
/*
* モジュールを初期化する
*/
void InitializeOLEDD()
{
/* IEnumFORMATETC */
m_OLEEnumFORMATETCVtbl.QueryInterface = (void *)OLEEnumFORMATETC_QueryInterface;
m_OLEEnumFORMATETCVtbl.AddRef = (void *)OLEEnumFORMATETC_AddRef;
m_OLEEnumFORMATETCVtbl.Release = (void *)OLEEnumFORMATETC_Release;
m_OLEEnumFORMATETCVtbl.Next = (void *)OLEEnumFORMATETC_Next;
m_OLEEnumFORMATETCVtbl.Skip = (void *)OLEEnumFORMATETC_Skip;
m_OLEEnumFORMATETCVtbl.Reset = (void *)OLEEnumFORMATETC_Reset;
m_OLEEnumFORMATETCVtbl.Clone = (void *)OLEEnumFORMATETC_Clone;
/* IDataSource */
m_OLEDataObjectVtbl.QueryInterface = (void *)OLEDataObject_QueryInterface;
m_OLEDataObjectVtbl.AddRef = (void *)OLEDataObject_AddRef;
m_OLEDataObjectVtbl.Release = (void *)OLEDataObject_Release;
m_OLEDataObjectVtbl.GetData = (void *)OLEDataObject_GetData;
m_OLEDataObjectVtbl.GetDataHere = (void *)OLEDataObject_GetDataHere;
m_OLEDataObjectVtbl.QueryGetData = (void *)OLEDataObject_QueryGetData;
m_OLEDataObjectVtbl.GetCanonicalFormatEtc = (void *)OLEDataObject_GetCanonicalFormatEtc;
m_OLEDataObjectVtbl.SetData = (void *)OLEDataObject_SetData;
m_OLEDataObjectVtbl.EnumFormatEtc = (void *)OLEDataObject_EnumFormatEtc;
m_OLEDataObjectVtbl.DAdvise = (void *)OLEDataObject_DAdvise;
m_OLEDataObjectVtbl.DUnadvise = (void *)OLEDataObject_DUnadvise;
m_OLEDataObjectVtbl.EnumDAdvise = (void *)OLEDataObject_EnumDAdvise;
/* IDropSource */
m_OLEDropSourceVtbl.QueryInterface = (void *)OLEDropSource_QueryInterface;
m_OLEDropSourceVtbl.AddRef = (void *)OLEDropSource_AddRef;
m_OLEDropSourceVtbl.Release = (void *)OLEDropSource_Release;
m_OLEDropSourceVtbl.QueryContinueDrag = (void *)OLEDropSource_QueryContinueDrag;
m_OLEDropSourceVtbl.GiveFeedback = (void *)OLEDropSource_GiveFeedback;
/* IDragTarget */
m_OLEDropTargetVtbl.QueryInterface = (void *)OLEDropTarget_QueryInterface;
m_OLEDropTargetVtbl.AddRef = (void *)OLEDropTarget_AddRef;
m_OLEDropTargetVtbl.Release = (void *)OLEDropTarget_Release;
m_OLEDropTargetVtbl.DragEnter = (void *)OLEDropTarget_DragEnter;
m_OLEDropTargetVtbl.DragOver = (void *)OLEDropTarget_DragOver;
m_OLEDropTargetVtbl.DragLeave = (void *)OLEDropTarget_DragLeave;
m_OLEDropTargetVtbl.Drop = (void *)OLEDropTarget_Drop;
}
/*
* IDataObjectのインスタンスを作成する
*/
IDataObject *CreateIDataObject()
{
return (IDataObject *)OLEDataObject_new();
}
/*
* IDropSourceのインスタンスを作成する
*
* PARAM:
* pfuncs OLEDDDropSource用のコールバック関数配列へのポインタ
* pdata コールバック関数に渡すデータへのポインタ
*/
IDropSource *CreateIDropSource(OLEDDDROPSOURCE *pfuncs, LPVOID pdata)
{
if (pfuncs == NULL) return NULL;
return (IDropSource *)OLEDropSource_new(pfuncs, pdata);
}
/*
* IDropTargetのインスタンスを作成する
*
* PARAM:
* pfuncs OLEDropTarget用のコールバック関数配列へのポインタ
* pdata コールバック関数に渡すデータへのポインタ
*/
IDropTarget *CreateIDropTarget(OLEDDDROPTARGET *pfuncs, LPVOID pdata)
{
if (pfuncs == NULL) return NULL;
return (IDropTarget *)OLEDropTarget_new(pfuncs, pdata);
}
/*
* OLE Drag and Drop module
*
* Copyright(c) 2001 yoh(yohhoy)
*/
#ifndef OLEDD_H_
#define OLEDD_H_
typedef HRESULT (* LPOLEDDQUERYCONTINUEDRAG)(LPVOID lpData, BOOL fEscapePressed, DWORD grfKeyState);
typedef HRESULT (* LPOLEDDGIVEFEEDBACK)(LPVOID lpData, DWORD dwEffect);
typedef struct tagOLEDDDROPSOURCE {
LPOLEDDQUERYCONTINUEDRAG lpQueryContinueDrag;
LPOLEDDGIVEFEEDBACK lpGiveFeedBack;
} OLEDDDROPSOURCE, *LPOLEDDDROPSOURCE;
typedef HRESULT (* LPOLEDDDRAGENTER)(LPVOID lpData, IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
typedef HRESULT (* LPOLEDDDRAGOVER)(LPVOID lpData, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
typedef HRESULT (* LPOLEDDDRAGLEAVE)(LPVOID lpData);
typedef HRESULT (* LPOLEDDDROP)(LPVOID lpData, IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
typedef struct tagOLEDDDROPTARGET {
LPOLEDDDRAGENTER lpDragEnter;
LPOLEDDDRAGOVER lpDragOver;
LPOLEDDDRAGLEAVE lpDragLeave;
LPOLEDDDROP lpDrop;
} OLEDDDROPTARGET, *LPOLEDDDROPTARGET;
void InitializeOLEDD();
IDataObject *CreateIDataObject();
IDropSource *CreateIDropSource(LPOLEDDDROPSOURCE, LPVOID);
IDropTarget *CreateIDropTarget(LPOLEDDDROPTARGET, LPVOID);
#endif /* OLEDD_H_ */
@yohhoy

This comment has been minimized.

Copy link
Owner Author

@yohhoy yohhoy commented Jul 6, 2012

Distributed under the Boost Software License, Version 1.0.
See copy at http://www.boost.org/LICENSE_1_0.txt

related article: http://yohhoy.hatenablog.jp/entry/2012/07/05/211940 (ja)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment