Artifact c1d100a942724719f89e693d36c5db6f07dca2e2
//--- K.I.LIB ---
// kl_dnd.h : drag and drop operation
#include "stdafx.h"
#include "kilib.h"
//--------------------------------------------------------------------//
bool kiDropSource::DnD( kiDataObject* pObj, DWORD efct, DWORD* pefct )
{
kiDropSource* pDrpSrc = new kiDropSource;
pDrpSrc->AddRef();
pObj->begin();
DWORD d, *p=(pefct==NULL ? &d : pefct);
HRESULT hr = ::DoDragDrop( pObj, pDrpSrc, efct, p );
pDrpSrc->Release();
return (hr == DRAGDROP_S_DROP);
}
//------------------------ IUnknown Implement -------------------------//
kiDropSource::kiDropSource() : m_cRef( 0L )
{
app()->shellInit(); // OleInitialize()
}
STDMETHODIMP_(ULONG) kiDropSource::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) kiDropSource::Release()
{
if( --m_cRef )
return m_cRef;
delete this;
return 0L;
}
STDMETHODIMP kiDropSource::QueryInterface( REFIID riid, void** ppObj )
{
if( ::IsEqualIID( riid, IID_IUnknown )
|| ::IsEqualIID( riid, IID_IDropSource ) )
{
*ppObj = (void*)this;
AddRef();
return S_OK;
}
*ppObj = NULL;
return E_NOINTERFACE;
}
//------------------------ IDropSource Implement -------------------------//
STDMETHODIMP kiDropSource::GiveFeedback( DWORD dwEffect )
{
return DRAGDROP_S_USEDEFAULTCURSORS;
}
STDMETHODIMP kiDropSource::QueryContinueDrag( BOOL keyESC, DWORD keyOther )
{
if( keyESC )
return DRAGDROP_S_CANCEL;
if( !(keyOther&MK_LBUTTON) && !(keyOther&MK_RBUTTON) )
return DRAGDROP_S_DROP;
return S_OK;
}
//------------------------ IUnknown Implement -------------------------//
kiDataObject::kiDataObject() : m_cRef( 0L ), m_FormatList( 2 )
{
}
STDMETHODIMP_(ULONG) kiDataObject::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) kiDataObject::Release()
{
if( --m_cRef )
return m_cRef;
delete this;
return 0L;
}
STDMETHODIMP kiDataObject::QueryInterface( REFIID riid, void** ppObj )
{
if( ::IsEqualIID( riid, IID_IUnknown )
|| ::IsEqualIID( riid, IID_IDataObject ) )
{
*ppObj = (void*)this;
AddRef();
return S_OK;
}
*ppObj = NULL;
return E_NOINTERFACE;
}
//------------------------ IDataObject Implement -------------------------//
STDMETHODIMP kiDataObject::GetData( FORMATETC* fmtc, STGMEDIUM* stg )
{
HRESULT hr = QueryGetData( fmtc );
if( FAILED(hr) )
return hr;
bool res = giveData( *fmtc, stg, m_bFirst );
m_bFirst = false;
return res ? S_OK : STG_E_MEDIUMFULL;
}
STDMETHODIMP kiDataObject::QueryGetData( FORMATETC* fmtc )
{
for( unsigned int i=0; i!=m_FormatList.len(); i++ )
if( m_FormatList[i].cfFormat == fmtc->cfFormat )
// if(fmtc & TYMED_HGLOBAL)
return S_OK;
return DV_E_FORMATETC;
}
//---------- Enumrator ---------//
class kiDataObject_Enum : public IEnumFORMATETC
{
public:
kiDataObject_Enum( kiDataObject* p )
: m_cRef( 0L ), m_pObj( p ), m_nCur( 0L )
{
m_pObj->AddRef();
}
~kiDataObject_Enum()
{
m_pObj->Release();
}
STDMETHODIMP_(ULONG) AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) Release()
{
if( --m_cRef )
return m_cRef;
delete this;
return 0L;
}
STDMETHODIMP QueryInterface( REFIID riid, void** ppObj )
{
if( ::IsEqualIID( riid, IID_IUnknown )
|| ::IsEqualIID( riid, IID_IEnumFORMATETC ) )
{
*ppObj = (void*)this;
AddRef();
return S_OK;
}
*ppObj = NULL;
return E_NOINTERFACE;
}
STDMETHODIMP Clone( IEnumFORMATETC** ppNew )
{
*ppNew = new kiDataObject_Enum( m_pObj );
((kiDataObject_Enum*)(*ppNew))->m_nCur = m_nCur;
(*ppNew)->AddRef();
return S_OK;
}
STDMETHODIMP Reset()
{
m_nCur = 0;
return S_OK;
}
STDMETHODIMP Skip( ULONG celt )
{
m_nCur += celt;
if( m_pObj->m_FormatList.len() <= m_nCur )
{
m_nCur = m_pObj->m_FormatList.len() - 1;
return S_FALSE;
}
return S_OK;
}
STDMETHODIMP Next( ULONG celt, FORMATETC* pFmt, ULONG* fetched )
{
if( fetched )
*fetched = 0L;
if( !pFmt )
return E_POINTER;
ULONG i;
for( i=0; i < celt && m_nCur < m_pObj->m_FormatList.len(); i++,m_nCur++ )
*pFmt++ = m_pObj->m_FormatList[m_nCur];
if( fetched )
*fetched = i;
return i==celt ? S_OK : S_FALSE;
}
private:
ULONG m_cRef;
ULONG m_nCur;
kiDataObject* m_pObj;
};
STDMETHODIMP kiDataObject::EnumFormatEtc( DWORD drctn, IEnumFORMATETC** ppEnm )
{
if( !ppEnm )
return E_INVALIDARG;
*ppEnm = NULL;
if( drctn!=DATADIR_GET )
return E_NOTIMPL;
(*ppEnm = new kiDataObject_Enum( this ))->AddRef();
return S_OK;
}