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 }