Artifact Content

Not logged in

Artifact c1d100a942724719f89e693d36c5db6f07dca2e2


     1  //--- K.I.LIB ---
     2  // kl_dnd.h : drag and drop operation
     3  
     4  #include "stdafx.h"
     5  #include "kilib.h"
     6  
     7  //--------------------------------------------------------------------//
     8  
     9  bool kiDropSource::DnD( kiDataObject* pObj, DWORD efct, DWORD* pefct )
    10  {
    11  	kiDropSource* pDrpSrc = new kiDropSource;
    12  	pDrpSrc->AddRef();
    13  	pObj->begin();
    14  
    15  	DWORD d, *p=(pefct==NULL ? &d : pefct);
    16  	HRESULT hr = ::DoDragDrop( pObj, pDrpSrc, efct, p );
    17  
    18  	pDrpSrc->Release();
    19  	return (hr == DRAGDROP_S_DROP);
    20  }
    21  
    22  //------------------------ IUnknown Implement -------------------------//
    23  
    24  kiDropSource::kiDropSource() : m_cRef( 0L )
    25  {
    26  	app()->shellInit(); // OleInitialize()
    27  }
    28  
    29  STDMETHODIMP_(ULONG) kiDropSource::AddRef()
    30  {
    31  	return ++m_cRef;
    32  }
    33  
    34  STDMETHODIMP_(ULONG) kiDropSource::Release()
    35  {
    36  	if( --m_cRef )
    37  		return m_cRef;
    38  
    39  	delete this;
    40  	return 0L;
    41  }
    42  
    43  STDMETHODIMP kiDropSource::QueryInterface( REFIID riid, void** ppObj )
    44  {
    45  	if( ::IsEqualIID( riid, IID_IUnknown )
    46  	 || ::IsEqualIID( riid, IID_IDropSource ) )
    47  	{
    48  		*ppObj = (void*)this;
    49  		AddRef();
    50  		return S_OK;
    51  	}
    52  
    53  	*ppObj = NULL;
    54  	return E_NOINTERFACE;
    55  }
    56  
    57  //------------------------ IDropSource Implement -------------------------//
    58  
    59  STDMETHODIMP kiDropSource::GiveFeedback( DWORD dwEffect )
    60  {
    61  	return DRAGDROP_S_USEDEFAULTCURSORS;
    62  }
    63  
    64  STDMETHODIMP kiDropSource::QueryContinueDrag( BOOL keyESC, DWORD keyOther )
    65  {
    66  	if( keyESC )
    67  		return DRAGDROP_S_CANCEL;
    68  	if( !(keyOther&MK_LBUTTON) && !(keyOther&MK_RBUTTON) ) 
    69  		return DRAGDROP_S_DROP;
    70  	return S_OK;
    71  }
    72  
    73  //------------------------ IUnknown Implement -------------------------//
    74  
    75  kiDataObject::kiDataObject() : m_cRef( 0L ), m_FormatList( 2 )
    76  {
    77  }
    78  
    79  STDMETHODIMP_(ULONG) kiDataObject::AddRef()
    80  {
    81  	return ++m_cRef;
    82  }
    83  
    84  STDMETHODIMP_(ULONG) kiDataObject::Release()
    85  {
    86  	if( --m_cRef )
    87  		return m_cRef;
    88  
    89  	delete this;
    90  	return 0L;
    91  }
    92  
    93  STDMETHODIMP kiDataObject::QueryInterface( REFIID riid, void** ppObj )
    94  {
    95  	if( ::IsEqualIID( riid, IID_IUnknown )
    96  	 || ::IsEqualIID( riid, IID_IDataObject ) )
    97  	{
    98  		*ppObj = (void*)this;
    99  		AddRef();
   100  		return S_OK;
   101  	}
   102  
   103  	*ppObj = NULL;
   104  	return E_NOINTERFACE;
   105  }
   106  
   107  //------------------------ IDataObject Implement -------------------------//
   108  
   109  
   110  STDMETHODIMP kiDataObject::GetData( FORMATETC* fmtc, STGMEDIUM* stg )
   111  {
   112  	HRESULT hr = QueryGetData( fmtc );
   113  	if( FAILED(hr) )
   114  		return hr;
   115  	bool res = giveData( *fmtc, stg, m_bFirst );
   116  	m_bFirst = false;
   117  	return res ? S_OK : STG_E_MEDIUMFULL;
   118  }
   119  
   120  STDMETHODIMP kiDataObject::QueryGetData( FORMATETC* fmtc )
   121  {
   122  	for( unsigned int i=0; i!=m_FormatList.len(); i++ )
   123  		if( m_FormatList[i].cfFormat == fmtc->cfFormat )
   124  //			if(fmtc & TYMED_HGLOBAL)
   125  				return S_OK;
   126  	return DV_E_FORMATETC;
   127  }
   128  
   129  //---------- Enumrator ---------//
   130  
   131  class kiDataObject_Enum : public IEnumFORMATETC
   132  {
   133  public:
   134  	kiDataObject_Enum( kiDataObject* p )
   135  		: m_cRef( 0L ), m_pObj( p ), m_nCur( 0L )
   136  		{
   137  			m_pObj->AddRef();
   138  		}
   139  	~kiDataObject_Enum()
   140  		{
   141  			m_pObj->Release();
   142  		}
   143  	STDMETHODIMP_(ULONG) AddRef()
   144  		{
   145  			return ++m_cRef;
   146  		}
   147  	STDMETHODIMP_(ULONG) Release()
   148  		{
   149  			if( --m_cRef )
   150  				return m_cRef;
   151  			delete this;
   152  			return 0L;
   153  		}
   154  	STDMETHODIMP QueryInterface( REFIID riid, void** ppObj )
   155  		{
   156  			if( ::IsEqualIID( riid, IID_IUnknown )
   157  			 || ::IsEqualIID( riid, IID_IEnumFORMATETC ) )
   158  			{
   159  				*ppObj = (void*)this;
   160  				AddRef();
   161  				return S_OK;
   162  			}
   163  			*ppObj = NULL;
   164  			return E_NOINTERFACE;
   165  		}
   166  	STDMETHODIMP Clone( IEnumFORMATETC** ppNew )
   167  		{
   168  			*ppNew = new kiDataObject_Enum( m_pObj );
   169  			((kiDataObject_Enum*)(*ppNew))->m_nCur = m_nCur;
   170  			(*ppNew)->AddRef();
   171  			return S_OK;
   172  		}
   173  	STDMETHODIMP Reset()
   174  		{
   175  			m_nCur = 0;
   176  			return S_OK;
   177  		}
   178  	STDMETHODIMP Skip( ULONG celt )
   179  		{
   180  			m_nCur += celt;
   181  			if( m_pObj->m_FormatList.len() <= m_nCur )
   182  			{
   183  				m_nCur = m_pObj->m_FormatList.len() - 1;
   184  				return S_FALSE;
   185  			}
   186  			return S_OK;
   187  		}
   188  	STDMETHODIMP Next( ULONG celt, FORMATETC* pFmt, ULONG* fetched )
   189  		{
   190  			if( fetched )
   191  				*fetched = 0L;
   192  			if( !pFmt )
   193  				return E_POINTER;
   194  			ULONG i;
   195  			for( i=0; i < celt && m_nCur < m_pObj->m_FormatList.len(); i++,m_nCur++ )
   196  				*pFmt++ = m_pObj->m_FormatList[m_nCur];
   197  			if( fetched )
   198  				*fetched = i;
   199  			return i==celt ? S_OK : S_FALSE;
   200  		}
   201  private:
   202  	ULONG         m_cRef;
   203  	ULONG         m_nCur;
   204  	kiDataObject* m_pObj;
   205  };
   206  
   207  STDMETHODIMP kiDataObject::EnumFormatEtc( DWORD drctn, IEnumFORMATETC** ppEnm )
   208  {
   209  	if( !ppEnm )
   210  		return E_INVALIDARG;
   211  	*ppEnm = NULL;
   212  	if( drctn!=DATADIR_GET )
   213  		return E_NOTIMPL;
   214  
   215  	(*ppEnm = new kiDataObject_Enum( this ))->AddRef();
   216  	return S_OK;
   217  }