1 /**************************************************************************
\r
5 (C) Copyright 1996-2002 By Tomoaki Nakashima. All right reserved.
\r
6 http://www.nakka.com/
\r
9 **************************************************************************/
\r
11 /**************************************************************************
\r
13 **************************************************************************/
\r
16 #include <windows.h>
\r
22 #include "OleDragDrop.h"
\r
25 /* Clipboard format
\82©
\82ç Type of storage medium
\82ð
\8eæ
\93¾ */
\r
26 static DWORD FormatToTymed(const UINT cfFormat)
\r
33 case CF_METAFILEPICT:
\r
34 return TYMED_MFPICT;
\r
36 case CF_ENHMETAFILE:
\r
39 return TYMED_HGLOBAL;
\r
43 /******************************************************************************
\r
47 ******************************************************************************/
\r
49 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_QueryInterface(LPDROPTARGET pThis, REFIID riid, LPVOID *ppvObject);
\r
50 static ULONG STDMETHODCALLTYPE OLE_IDropTarget_AddRef(LPDROPTARGET pThis);
\r
51 static ULONG STDMETHODCALLTYPE OLE_IDropTarget_Release(LPDROPTARGET pThis);
\r
52 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragEnter(LPDROPTARGET pThis, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
\r
53 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragOver(LPDROPTARGET pThis, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
\r
54 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragLeave(LPDROPTARGET pThis);
\r
55 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_Drop(LPDROPTARGET pThis, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
\r
56 static HRESULT APIPRIVATE OLE_IDropTarget_Internal_SendMessage(LPDROPTARGET pThis, UINT uNotify, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL *ppt, LPDWORD pdwEffect);
\r
57 static HRESULT APIPRIVATE DropTarget_GetData(LPDATAOBJECT pdo, UINT cfFormat, LPSTGMEDIUM psm);
\r
58 static HRESULT APIPRIVATE DropTarget_QueryGetData(LPDATAOBJECT pdo, UINT cfFormat);
\r
60 /* IDropTarget Virtual Table */
\r
61 static IDropTargetVtbl dtv = {
\r
62 OLE_IDropTarget_QueryInterface,
\r
63 OLE_IDropTarget_AddRef,
\r
64 OLE_IDropTarget_Release,
\r
65 OLE_IDropTarget_DragEnter,
\r
66 OLE_IDropTarget_DragOver,
\r
67 OLE_IDropTarget_DragLeave,
\r
68 OLE_IDropTarget_Drop
\r
71 typedef struct _IDROPTARGET_INTERNAL{
\r
75 UINT uCallbackMessage;
\r
78 IDROPTARGET_NOTIFY dtn;
\r
79 }IDROPTARGET_INTERNAL , *LPIDROPTARGET_INTERNAL;
\r
81 /* OLE
\82Ì
\83h
\83\8d\83b
\83v
\83^
\81[
\83Q
\83b
\83g
\82Æ
\82µ
\82Ä
\93o
\98^
\82·
\82é */
\r
82 BOOL APIPRIVATE OLE_IDropTarget_RegisterDragDrop(HWND hWnd, UINT uCallbackMessage, UINT *cFormat, int cfcnt)
\r
84 static IDROPTARGET_INTERNAL *pdti;
\r
86 pdti = GlobalAlloc(GPTR, sizeof(IDROPTARGET_INTERNAL));
\r
90 pdti->lpVtbl = (LPVOID)&dtv;
\r
92 pdti->hWnd = hWnd; /*
\83\81\83b
\83Z
\81[
\83W
\82ð
\8eó
\82¯
\8eæ
\82é
\83E
\83B
\83\93\83h
\83E */
\r
93 pdti->uCallbackMessage = uCallbackMessage; /*
\83\81\83b
\83Z
\81[
\83W */
\r
94 pdti->cFormat = (UINT *)GlobalAlloc(GPTR, sizeof(UINT) * cfcnt); /*
\91Î
\89\9e\82µ
\82Ä
\82¢
\82é
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g */
\r
95 if(pdti->cFormat == NULL){
\r
99 CopyMemory(pdti->cFormat, cFormat, sizeof(UINT) * cfcnt);
\r
100 pdti->cfcnt = cfcnt; /*
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82Ì
\90\94 */
\r
101 return (S_OK == RegisterDragDrop(hWnd, (LPDROPTARGET)pdti));
\r
104 /* OLE
\82Ì
\83h
\83\8d\83b
\83v
\83^
\81[
\83Q
\83b
\83g
\82ð
\89ð
\8f\9c\82·
\82é */
\r
105 void APIPRIVATE OLE_IDropTarget_RevokeDragDrop(HWND hWnd)
\r
107 RevokeDragDrop(hWnd);
\r
110 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_QueryInterface(LPDROPTARGET pThis, REFIID riid, PVOID *ppvObject)
\r
112 //
\97v
\8b\81\82³
\82ê
\82½IID
\82Æ
\93¯
\82¶
\8fê
\8d\87\82Í
\83I
\83u
\83W
\83F
\83N
\83g
\82ð
\95Ô
\82·
\r
113 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropTarget)){
\r
114 *ppvObject = (LPVOID)pThis;
\r
115 ((LPUNKNOWN)*ppvObject)->lpVtbl->AddRef((LPUNKNOWN)*ppvObject);
\r
119 return ResultFromScode(E_NOINTERFACE);
\r
122 static ULONG STDMETHODCALLTYPE OLE_IDropTarget_AddRef(LPDROPTARGET pThis)
\r
124 CONST LPIDROPTARGET_INTERNAL pdti = (LPIDROPTARGET_INTERNAL)pThis;
\r
126 /* reference count
\82ð
\83C
\83\93\83N
\83\8a\83\81\83\93\83g
\82·
\82é */
\r
128 return pdti->m_refCnt;
\r
131 static ULONG STDMETHODCALLTYPE OLE_IDropTarget_Release(LPDROPTARGET pThis)
\r
133 CONST LPIDROPTARGET_INTERNAL pdti = (LPIDROPTARGET_INTERNAL)pThis;
\r
135 /* reference count
\82ð
\83f
\83N
\83\8a\83\81\83\93\83g
\82·
\82é */
\r
138 /* reference count
\82ª 0
\82É
\82È
\82Á
\82½
\8fê
\8d\87\82Í
\83I
\83u
\83W
\83F
\83N
\83g
\82Ì
\89ð
\95ú
\82ð
\8ds
\82¤ */
\r
139 if(pdti->m_refCnt == 0L){
\r
140 if(pdti->cFormat != NULL){
\r
141 GlobalFree(pdti->cFormat);
\r
146 return pdti->m_refCnt;
\r
149 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragEnter(LPDROPTARGET pThis, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
\r
151 return OLE_IDropTarget_Internal_SendMessage(pThis, IDROPTARGET_NOTIFY_DRAGENTER, pdo, grfKeyState, &pt, pdwEffect);
\r
154 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragOver(LPDROPTARGET pThis, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
\r
156 return OLE_IDropTarget_Internal_SendMessage(pThis, IDROPTARGET_NOTIFY_DRAGOVER, NULL, grfKeyState, &pt, pdwEffect);
\r
159 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragLeave(LPDROPTARGET pThis)
\r
161 return OLE_IDropTarget_Internal_SendMessage(pThis, IDROPTARGET_NOTIFY_DRAGLEAVE, NULL, 0, NULL, NULL);
\r
164 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_Drop(LPDROPTARGET pThis, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
\r
166 return OLE_IDropTarget_Internal_SendMessage(pThis, IDROPTARGET_NOTIFY_DROP, pdo, grfKeyState, &pt, pdwEffect);
\r
169 static HRESULT APIPRIVATE OLE_IDropTarget_Internal_SendMessage(LPDROPTARGET pThis, UINT uNotify, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL *ppt, LPDWORD pdwEffect)
\r
171 CONST LPIDROPTARGET_INTERNAL pdti = (LPIDROPTARGET_INTERNAL)pThis;
\r
172 CONST LPIDROPTARGET_NOTIFY pdtn = &(pdti->dtn);
\r
178 /*
\91Î
\89\9e\82µ
\82Ä
\82¢
\82é
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82ª
\82 \82é
\82©
\92²
\82×
\82é */
\r
179 for(i = 0;i < pdti->cfcnt;i++){
\r
180 if(DropTarget_QueryGetData(pdo, pdti->cFormat[i]) == S_OK){
\r
181 cfFormat = pdti->cFormat[i];
\r
185 /*
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82©
\82ç
\83f
\81[
\83^
\82ð
\8eæ
\93¾
\82·
\82é */
\r
187 if (DropTarget_GetData(pdo, cfFormat, &sm) != S_OK){
\r
192 pdtn->ppt = ppt; /*
\83}
\83E
\83X
\83|
\83C
\83\93\83^
\82Ì
\88Ê
\92u */
\r
193 pdtn->grfKeyState = grfKeyState; /*
\83L
\81[
\81A
\83}
\83E
\83X
\83{
\83^
\83\93\82Ì
\8fó
\91Ô */
\r
194 pdtn->cfFormat = cfFormat; /*
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g */
\r
195 pdtn->hMem = sm.hGlobal; /*
\8eÀ
\83f
\81[
\83^ */
\r
196 pdtn->pdo = pdo; /* IDataObject */
\r
198 /*
\83E
\83B
\83\93\83h
\83E
\82É
\83C
\83x
\83\93\83g
\82ð
\92Ê
\92m
\82·
\82é */
\r
199 SendMessage(pdti->hWnd, pdti->uCallbackMessage, (WPARAM)uNotify, (LPARAM)pdtn);
\r
201 /*
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\8c`
\8e®
\82Ì
\83f
\81[
\83^
\82Ì
\89ð
\95ú */
\r
203 ReleaseStgMedium(&sm);
\r
206 /*
\8cø
\89Ê
\82Ì
\90Ý
\92è */
\r
208 *pdwEffect &= pdtn->dwEffect;
\r
210 if((*pdwEffect & DROPEFFECT_MOVE) && (*pdwEffect & DROPEFFECT_COPY)){
\r
211 *pdwEffect ^= DROPEFFECT_COPY;
\r
212 pdtn->dwEffect ^= DROPEFFECT_COPY;
\r
218 static HRESULT APIPRIVATE DropTarget_GetData(LPDATAOBJECT pdo, UINT cfFormat, LPSTGMEDIUM psm)
\r
222 /* IDataObject
\82É
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\8c`
\8e®
\82Ì
\83f
\81[
\83^
\82ð
\97v
\8b\81\82·
\82é */
\r
223 fmt.cfFormat = cfFormat;
\r
225 fmt.dwAspect = DVASPECT_CONTENT;
\r
227 fmt.tymed = FormatToTymed(cfFormat);
\r
228 return pdo->lpVtbl->GetData(pdo, &fmt, psm);
\r
231 static HRESULT APIPRIVATE DropTarget_QueryGetData(LPDATAOBJECT pdo, UINT cfFormat)
\r
235 /* IDataObject
\82É
\8ew
\92è
\82Ì
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82ª
\91¶
\8dÝ
\82·
\82é
\82©
\96â
\82¢
\8d\87\82í
\82¹
\82é */
\r
236 fmt.cfFormat = cfFormat;
\r
238 fmt.dwAspect = DVASPECT_CONTENT;
\r
240 fmt.tymed = FormatToTymed(cfFormat);
\r
241 return pdo->lpVtbl->QueryGetData(pdo, &fmt);
\r
245 /******************************************************************************
\r
249 ******************************************************************************/
\r
251 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_QueryInterface(LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* lplpvObj);
\r
252 static ULONG STDMETHODCALLTYPE OLE_IEnumFORMATETC_AddRef(LPENUMFORMATETC lpThis);
\r
253 static ULONG STDMETHODCALLTYPE OLE_IEnumFORMATETC_Release(LPENUMFORMATETC lpThis);
\r
254 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Next(LPENUMFORMATETC lpThis, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched);
\r
255 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Skip(LPENUMFORMATETC lpThis, ULONG celt);
\r
256 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Reset(LPENUMFORMATETC lpThis);
\r
257 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Clone(LPENUMFORMATETC lpThis, IEnumFORMATETC **ppenum);
\r
259 /* IEnumFORMATETC Virtual Table */
\r
260 static IEnumFORMATETCVtbl efv = {
\r
261 OLE_IEnumFORMATETC_QueryInterface,
\r
262 OLE_IEnumFORMATETC_AddRef,
\r
263 OLE_IEnumFORMATETC_Release,
\r
264 OLE_IEnumFORMATETC_Next,
\r
265 OLE_IEnumFORMATETC_Skip,
\r
266 OLE_IEnumFORMATETC_Reset,
\r
267 OLE_IEnumFORMATETC_Clone
\r
270 typedef struct _IENUMFORMATETC_INTERNAL{
\r
273 LPUNKNOWN m_pUnknownObj;
\r
274 ULONG m_currElement;
\r
275 ULONG m_numFormats;
\r
276 LPFORMATETC m_formatList;
\r
277 }IENUMFORMATETC_INTERNAL , *LPIENUMFORMATETC_INTERNAL;
\r
279 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_QueryInterface(LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* lplpvObj)
\r
281 //
\97v
\8b\81\82³
\82ê
\82½IID
\82Æ
\93¯
\82¶
\8fê
\8d\87\82Í
\83I
\83u
\83W
\83F
\83N
\83g
\82ð
\95Ô
\82·
\r
282 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumFORMATETC)){
\r
283 *lplpvObj = (LPVOID) lpThis;
\r
284 ((LPUNKNOWN)*lplpvObj)->lpVtbl->AddRef(((LPUNKNOWN)*lplpvObj));
\r
288 return ResultFromScode(E_NOINTERFACE);
\r
291 static ULONG STDMETHODCALLTYPE OLE_IEnumFORMATETC_AddRef(LPENUMFORMATETC lpThis)
\r
293 CONST LPIENUMFORMATETC_INTERNAL pefi = (LPIENUMFORMATETC_INTERNAL)lpThis;
\r
295 /* reference count
\82ð
\83C
\83\93\83N
\83\8a\83\81\83\93\83g
\82·
\82é */
\r
297 /*
\90e
\83I
\83u
\83W
\83F
\83N
\83g
\82Ìreference count
\82ð
\89Á
\82¦
\82é */
\r
298 pefi->m_pUnknownObj->lpVtbl->AddRef(pefi->m_pUnknownObj);
\r
299 return pefi->m_refCnt;
\r
302 static ULONG STDMETHODCALLTYPE OLE_IEnumFORMATETC_Release(LPENUMFORMATETC lpThis)
\r
304 CONST LPIENUMFORMATETC_INTERNAL pefi = (LPIENUMFORMATETC_INTERNAL)lpThis;
\r
306 /* reference count
\82ð
\83f
\83N
\83\8a\83\81\83\93\83g
\82·
\82é */
\r
308 /*
\90e
\83I
\83u
\83W
\83F
\83N
\83g
\82Ìreference count
\82ð
\8c¸
\82ç
\82· */
\r
309 pefi->m_pUnknownObj->lpVtbl->Release(pefi->m_pUnknownObj);
\r
311 /* reference count
\82ª 0
\82É
\82È
\82Á
\82½
\8fê
\8d\87\82Í
\83I
\83u
\83W
\83F
\83N
\83g
\82Ì
\89ð
\95ú
\82ð
\8ds
\82¤ */
\r
312 if(pefi->m_refCnt == 0L){
\r
313 if(pefi->m_formatList != NULL){
\r
314 GlobalFree(pefi->m_formatList);
\r
319 return pefi->m_refCnt;
\r
322 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Next(LPENUMFORMATETC lpThis, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched)
\r
326 LPIENUMFORMATETC_INTERNAL lpefi = ((LPIENUMFORMATETC_INTERNAL)lpThis);
\r
329 *pceltFetched = 0L;
\r
331 if(lpefi->m_formatList == NULL){
\r
332 return ResultFromScode(S_FALSE);
\r
337 return ResultFromScode(S_FALSE);
\r
339 return ResultFromScode(E_POINTER);
\r
343 if(lpefi->m_currElement >= lpefi->m_numFormats){
\r
344 return ResultFromScode(S_FALSE);
\r
347 for(i = 0;i < celt && lpefi->m_currElement < lpefi->m_numFormats;i++, lpefi->m_currElement++){
\r
348 *rgelt = lpefi->m_formatList[lpefi->m_currElement];
\r
352 if(pceltFetched != NULL){
\r
359 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Skip(LPENUMFORMATETC lpThis, ULONG celt)
\r
361 LPIENUMFORMATETC_INTERNAL lpefi = ((LPIENUMFORMATETC_INTERNAL)lpThis);
\r
363 lpefi->m_currElement += celt;
\r
365 if(lpefi->m_currElement > lpefi->m_numFormats){
\r
366 lpefi->m_currElement = lpefi->m_numFormats;
\r
367 return ResultFromScode(S_FALSE);
\r
372 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Reset(LPENUMFORMATETC lpThis)
\r
374 LPIENUMFORMATETC_INTERNAL lpefi = ((LPIENUMFORMATETC_INTERNAL)lpThis);
\r
376 lpefi->m_currElement = 0L;
\r
380 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Clone(LPENUMFORMATETC lpThis, IEnumFORMATETC **ppenum)
\r
382 LPIENUMFORMATETC_INTERNAL pNew;
\r
383 LPIENUMFORMATETC_INTERNAL lpefi = ((LPIENUMFORMATETC_INTERNAL)lpThis);
\r
386 /* IEnumFORMATETC
\82ð
\8dì
\90¬
\82·
\82é */
\r
387 pNew = GlobalAlloc(GPTR, sizeof(IENUMFORMATETC_INTERNAL));
\r
389 return ResultFromScode(E_OUTOFMEMORY);
\r
391 pNew->lpVtbl = (LPVOID)&efv;
\r
392 pNew->m_refCnt = 0;
\r
393 pNew->m_currElement = 0;
\r
395 pNew->m_pUnknownObj = lpefi->m_pUnknownObj;
\r
396 pNew->m_numFormats = lpefi->m_numFormats;
\r
398 /*
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82Ì
\83\8a\83X
\83g
\82ð
\83R
\83s
\81[
\82·
\82é */
\r
399 pNew->m_formatList = GlobalAlloc(GPTR, sizeof(FORMATETC) * pNew->m_numFormats);
\r
400 if(pNew->m_formatList != NULL){
\r
401 for(i = 0;i < pNew->m_numFormats;i++){
\r
402 pNew->m_formatList[i] = lpefi->m_formatList[i];
\r
406 *ppenum = (struct IEnumFORMATETC *)pNew;
\r
408 return ResultFromScode(E_OUTOFMEMORY);
\r
410 ((LPENUMFORMATETC)pNew)->lpVtbl->AddRef(((LPENUMFORMATETC)pNew));
\r
411 pNew->m_currElement = lpefi->m_currElement;
\r
416 /******************************************************************************
\r
420 ******************************************************************************/
\r
422 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_QueryInterface(LPDATAOBJECT lpThis, REFIID riid, LPVOID FAR *lplpvObj);
\r
423 static ULONG STDMETHODCALLTYPE OLE_IDataObject_AddRef(LPDATAOBJECT lpThis);
\r
424 static ULONG STDMETHODCALLTYPE OLE_IDataObject_Release(LPDATAOBJECT lpThis);
\r
425 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium);
\r
426 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetDataHere(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium);
\r
427 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_QueryGetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc);
\r
428 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT lpThis, FORMATETC *pFormatetcIn, FORMATETC *pFormatetcOut);
\r
429 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_SetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium, BOOL fRelease);
\r
430 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_EnumFormatEtc(LPDATAOBJECT lpThis, DWORD dwDirection, IEnumFORMATETC **ppenumFormatetc);
\r
431 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_DAdvise(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
\r
432 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_DUnadvise(LPDATAOBJECT lpThis, DWORD dwConnection);
\r
433 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_EnumDAdvise(LPDATAOBJECT lpThis, IEnumSTATDATA **ppenumAdvise);
\r
435 /* IDataObject Virtual Table */
\r
436 static IDataObjectVtbl dov = {
\r
437 OLE_IDataObject_QueryInterface,
\r
438 OLE_IDataObject_AddRef,
\r
439 OLE_IDataObject_Release,
\r
440 OLE_IDataObject_GetData,
\r
441 OLE_IDataObject_GetDataHere,
\r
442 OLE_IDataObject_QueryGetData,
\r
443 OLE_IDataObject_GetCanonicalFormatEtc,
\r
444 OLE_IDataObject_SetData,
\r
445 OLE_IDataObject_EnumFormatEtc,
\r
446 OLE_IDataObject_DAdvise,
\r
447 OLE_IDataObject_DUnadvise,
\r
448 OLE_IDataObject_EnumDAdvise
\r
451 typedef struct _IDATAOBJECT_INTERNAL{
\r
456 FORMATETC *m_typeList;
\r
458 UINT uCallbackMessage;
\r
459 }IDATAOBJECT_INTERNAL , *LPIDATAOBJECT_INTERNAL;
\r
462 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_QueryInterface(LPDATAOBJECT lpThis, REFIID riid, LPVOID FAR *lplpvObj)
\r
464 //
\97v
\8b\81\82³
\82ê
\82½IID
\82Æ
\93¯
\82¶
\8fê
\8d\87\82Í
\83I
\83u
\83W
\83F
\83N
\83g
\82ð
\95Ô
\82·
\r
465 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDataObject)){
\r
466 *lplpvObj = lpThis;
\r
467 ((LPUNKNOWN)*lplpvObj)->lpVtbl->AddRef(((LPUNKNOWN)*lplpvObj));
\r
471 return ResultFromScode(E_NOINTERFACE);
\r
474 static ULONG STDMETHODCALLTYPE OLE_IDataObject_AddRef(LPDATAOBJECT lpThis)
\r
476 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
478 /* reference count
\82ð
\83C
\83\93\83N
\83\8a\83\81\83\93\83g
\82·
\82é */
\r
480 return pdoi->m_refCnt;
\r
483 static ULONG STDMETHODCALLTYPE OLE_IDataObject_Release(LPDATAOBJECT lpThis)
\r
485 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
487 /* reference count
\82ð
\83f
\83N
\83\8a\83\81\83\93\83g
\82·
\82é */
\r
490 /* reference count
\82ª 0
\82É
\82È
\82Á
\82½
\8fê
\8d\87\82Í
\83I
\83u
\83W
\83F
\83N
\83g
\82Ì
\89ð
\95ú
\82ð
\8ds
\82¤ */
\r
491 if(pdoi->m_refCnt == 0L){
\r
492 if(pdoi->m_typeList != NULL){
\r
493 GlobalFree(pdoi->m_typeList);
\r
498 return pdoi->m_refCnt;
\r
501 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium)
\r
503 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
507 /*
\97v
\8b\81\82³
\82ê
\82½
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82ª
\91¶
\8dÝ
\82·
\82é
\82©
\92²
\82×
\82é */
\r
508 for(i = 0;i < pdoi->m_numTypes;i++){
\r
509 if(pdoi->m_typeList[i].cfFormat == pFormatetc->cfFormat){
\r
513 if(i == pdoi->m_numTypes){
\r
514 /*
\97v
\8b\81\82³
\82ê
\82½
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82ð
\83T
\83|
\81[
\83g
\82µ
\82Ä
\82È
\82¢
\8fê
\8d\87 */
\r
515 return ResultFromScode(DV_E_FORMATETC);
\r
518 //
\83}
\83E
\83X
\82Ì
\83h
\83\89\83b
\83O
\92\86\82Í WM_GETDATA
\82ð
\91\97\82ç
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é
\81B(2007.9.3 yutaka)
\r
519 if (GetAsyncKeyState(VK_LBUTTON) & 0x8000 ||
\r
520 GetAsyncKeyState(VK_RBUTTON) & 0x8000) {
\r
521 return ResultFromScode(DV_E_FORMATETC);
\r
524 /*
\83E
\83B
\83\93\83h
\83E
\82É
\83f
\81[
\83^
\82Ì
\97v
\8b\81\82ð
\8ds
\82¤ */
\r
525 SendMessage(pdoi->hWnd, pdoi->uCallbackMessage, (WPARAM)pdoi->m_typeList[i].cfFormat, (LPARAM)&hMem);
\r
527 return ResultFromScode(STG_E_MEDIUMFULL);
\r
529 pmedium->hGlobal = hMem;
\r
530 pmedium->tymed = FormatToTymed(pFormatetc->cfFormat);
\r
531 pmedium->pUnkForRelease = NULL;
\r
535 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetDataHere(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium)
\r
537 return ResultFromScode(E_NOTIMPL);
\r
540 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_QueryGetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc)
\r
542 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
545 /*
\97v
\8b\81\82³
\82ê
\82½
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82ª
\91¶
\8dÝ
\82·
\82é
\82©
\92²
\82×
\82é */
\r
546 for(i = 0;i < pdoi->m_numTypes;i++){
\r
547 if(pdoi->m_typeList[i].cfFormat == pFormatetc->cfFormat){
\r
551 return ResultFromScode(DV_E_FORMATETC);
\r
554 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT lpThis, FORMATETC *pFormatetcIn, FORMATETC *pFormatetcOut)
\r
556 return ResultFromScode(E_NOTIMPL);
\r
559 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_SetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium, BOOL fRelease)
\r
561 return ResultFromScode(E_NOTIMPL);
\r
564 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_EnumFormatEtc(LPDATAOBJECT lpThis, DWORD dwDirection, IEnumFORMATETC **ppenumFormatetc)
\r
566 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
567 static IENUMFORMATETC_INTERNAL *pefi;
\r
570 if(ppenumFormatetc == NULL){
\r
571 return ResultFromScode(E_INVALIDARG);
\r
574 if(dwDirection != DATADIR_GET){
\r
575 *ppenumFormatetc = NULL;
\r
576 return ResultFromScode(E_NOTIMPL);
\r
579 /* IEnumFORMATETC
\82ð
\8dì
\90¬
\82·
\82é */
\r
580 pefi = GlobalAlloc(GPTR, sizeof(IENUMFORMATETC_INTERNAL));
\r
582 return E_OUTOFMEMORY;
\r
584 pefi->lpVtbl = (LPVOID)&efv;
\r
585 pefi->m_refCnt = 0;
\r
586 pefi->m_currElement = 0;
\r
587 pefi->m_pUnknownObj = (struct IUnknown *)lpThis;
\r
588 pefi->m_numFormats = pdoi->m_numTypes;
\r
590 /*
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82Ì
\83\8a\83X
\83g
\82ð
\83R
\83s
\81[
\82·
\82é */
\r
591 pefi->m_formatList = GlobalAlloc(GPTR, sizeof(FORMATETC) * pefi->m_numFormats);
\r
592 if(pefi->m_formatList != NULL){
\r
593 for(i = 0;i < pefi->m_numFormats;i++){
\r
594 pefi->m_formatList[i] = pdoi->m_typeList[i];
\r
598 ((LPENUMFORMATETC)pefi)->lpVtbl->AddRef(((LPENUMFORMATETC)pefi));
\r
600 *ppenumFormatetc = (struct IEnumFORMATETC *)pefi;
\r
601 if(*ppenumFormatetc == NULL){
\r
602 return E_OUTOFMEMORY;
\r
607 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_DAdvise(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
\r
609 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
\r
612 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_DUnadvise(LPDATAOBJECT lpThis, DWORD dwConnection)
\r
614 return ResultFromScode(OLE_E_NOCONNECTION);
\r
617 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_EnumDAdvise(LPDATAOBJECT lpThis, IEnumSTATDATA **ppenumAdvise)
\r
619 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
\r
623 /******************************************************************************
\r
627 ******************************************************************************/
\r
629 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_QueryInterface(LPDROPSOURCE lpThis, REFIID riid, LPVOID FAR* lplpvObj);
\r
630 static ULONG STDMETHODCALLTYPE OLE_IDropSource_AddRef(LPDROPSOURCE lpThis);
\r
631 static ULONG STDMETHODCALLTYPE OLE_IDropSource_Release(LPDROPSOURCE lpThis);
\r
632 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_QueryContinueDrag(LPDROPSOURCE lpThis, BOOL fEscapePressed, DWORD grfKeyState);
\r
633 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_GiveFeedback(LPDROPSOURCE lpThis, DWORD dwEffect);
\r
635 /* IDropSource Virtual Table */
\r
636 static IDropSourceVtbl dsv = {
\r
637 OLE_IDropSource_QueryInterface,
\r
638 OLE_IDropSource_AddRef,
\r
639 OLE_IDropSource_Release,
\r
640 OLE_IDropSource_QueryContinueDrag,
\r
641 OLE_IDropSource_GiveFeedback,
\r
644 typedef struct _IDROPSOURCE_INTERNAL{
\r
650 UINT m_uCallbackDragOverMessage;
\r
651 }IDROPSOURCE_INTERNAL , *LPIDROPSOURCE_INTERNAL;
\r
653 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_QueryInterface(LPDROPSOURCE lpThis, REFIID riid, LPVOID FAR *lplpvObj)
\r
655 //
\97v
\8b\81\82³
\82ê
\82½IID
\82Æ
\93¯
\82¶
\8fê
\8d\87\82Í
\83I
\83u
\83W
\83F
\83N
\83g
\82ð
\95Ô
\82·
\r
656 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropSource)){
\r
657 *lplpvObj = (LPVOID) lpThis;
\r
658 ((LPUNKNOWN)*lplpvObj)->lpVtbl->AddRef(((LPUNKNOWN)*lplpvObj));
\r
662 return ResultFromScode(E_NOINTERFACE);
\r
666 static ULONG STDMETHODCALLTYPE OLE_IDropSource_AddRef(LPDROPSOURCE lpThis)
\r
668 CONST LPIDROPSOURCE_INTERNAL pdsi = (LPIDROPSOURCE_INTERNAL)lpThis;
\r
670 /* reference count
\82ð
\83C
\83\93\83N
\83\8a\83\81\83\93\83g
\82·
\82é */
\r
672 return pdsi->m_refCnt;
\r
675 static ULONG STDMETHODCALLTYPE OLE_IDropSource_Release(LPDROPSOURCE lpThis)
\r
677 CONST LPIDROPSOURCE_INTERNAL pdsi = (LPIDROPSOURCE_INTERNAL)lpThis;
\r
679 /* reference count
\82ð
\83f
\83N
\83\8a\83\81\83\93\83g
\82·
\82é */
\r
682 /* reference count
\82ª 0
\82É
\82È
\82Á
\82½
\8fê
\8d\87\82Í
\83I
\83u
\83W
\83F
\83N
\83g
\82Ì
\89ð
\95ú
\82ð
\8ds
\82¤ */
\r
683 if(pdsi->m_refCnt == 0L){
\r
687 return pdsi->m_refCnt;
\r
690 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_QueryContinueDrag(LPDROPSOURCE lpThis, BOOL fEscapePressed, DWORD grfKeyState)
\r
692 CONST LPIDROPSOURCE_INTERNAL pdsi = (LPIDROPSOURCE_INTERNAL)lpThis;
\r
694 if(fEscapePressed){
\r
695 /*
\83G
\83X
\83P
\81[
\83v
\82ª
\89\9f\82³
\82ê
\82½
\8fê
\8d\87\82Í
\83L
\83\83\83\93\83Z
\83\8b\82É
\82·
\82é */
\r
696 return ResultFromScode(DRAGDROP_S_CANCEL);
\r
699 // Mouse over
\82Ì
\92Ê
\92m (yutaka)
\r
700 SendMessage(pdsi->m_hWnd, pdsi->m_uCallbackDragOverMessage, 0, 0);
\r
702 /*
\8ew
\92è
\82Ì
\83L
\81[
\82â
\83}
\83E
\83X
\82ª
\97£
\82³
\82ê
\82½
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82É
\82·
\82é */
\r
703 if(pdsi->m_button == 0){
\r
704 if(grfKeyState != pdsi->m_keyState){
\r
705 return ResultFromScode(DRAGDROP_S_DROP);
\r
708 if(!(grfKeyState & pdsi->m_button)){
\r
709 return ResultFromScode(DRAGDROP_S_DROP);
\r
715 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_GiveFeedback(LPDROPSOURCE lpThis, DWORD dwEffect)
\r
717 return ResultFromScode(DRAGDROP_S_USEDEFAULTCURSORS);
\r
720 /*
\83h
\83\89\83b
\83O
\81\95\83h
\83\8d\83b
\83v
\82Ì
\8aJ
\8en */
\r
721 int APIPRIVATE OLE_IDropSource_Start(HWND hWnd, UINT uCallbackMessage, UINT uCallbackDragOverMessage, UINT *ClipFormtList, int cfcnt, int Effect)
\r
723 static IDATAOBJECT_INTERNAL *pdoi;
\r
724 static IDROPSOURCE_INTERNAL *pdsi;
\r
730 /* IDataObject
\82Ì
\8dì
\90¬ */
\r
731 pdoi = GlobalAlloc(GPTR, sizeof(IDATAOBJECT_INTERNAL));
\r
735 pdoi->lpVtbl = (LPVOID)&dov;
\r
736 pdoi->m_refCnt = 0;
\r
737 pdoi->m_numTypes = cfcnt;
\r
738 pdoi->m_maxTypes = cfcnt;
\r
739 /*
\97L
\8cø
\82È
\83N
\83\8a\83b
\83v
\83{
\81[
\83h
\83t
\83H
\81[
\83}
\83b
\83g
\82ð
\90Ý
\92è
\82·
\82é */
\r
740 pdoi->m_typeList = GlobalAlloc(GPTR, sizeof(FORMATETC) * cfcnt);
\r
741 if(pdoi->m_typeList == NULL){
\r
745 for(i = 0;i < cfcnt;i++){
\r
746 pdoi->m_typeList[i].cfFormat = ClipFormtList[i];
\r
747 pdoi->m_typeList[i].ptd = NULL;
\r
748 pdoi->m_typeList[i].dwAspect = DVASPECT_CONTENT;
\r
749 pdoi->m_typeList[i].lindex = -1;
\r
750 pdoi->m_typeList[i].tymed = FormatToTymed(ClipFormtList[i]);
\r
753 pdoi->uCallbackMessage = uCallbackMessage;
\r
754 ((LPDATAOBJECT)pdoi)->lpVtbl->AddRef((LPDATAOBJECT)pdoi);
\r
756 /* IDropSource
\82Ì
\8dì
\90¬ */
\r
757 pdsi = GlobalAlloc(GPTR, sizeof(IDROPSOURCE_INTERNAL));
\r
759 /* IDataObject
\82ð
\89ð
\95ú
\82·
\82é */
\r
760 ((LPDATAOBJECT)pdoi)->lpVtbl->Release((LPDATAOBJECT)pdoi);
\r
763 pdsi->lpVtbl = (LPVOID)&dsv;
\r
764 pdsi->m_refCnt = 0;
\r
765 pdsi->m_hWnd = hWnd; // yutaka
\r
766 pdsi->m_uCallbackDragOverMessage = uCallbackDragOverMessage;
\r
768 /*
\97L
\8cø
\82È
\83L
\81[
\82Æ
\83}
\83E
\83X
\82Ì
\8fó
\91Ô */
\r
769 if(GetKeyState(VK_RBUTTON) & 0x8000){
\r
770 pdsi->m_button = MK_RBUTTON;
\r
772 pdsi->m_button = MK_LBUTTON;
\r
775 /*
\8c»
\8dÝ
\82Ì
\83L
\81[
\82Æ
\83}
\83E
\83X
\82Ì
\8fó
\91Ô */
\r
777 if(GetKeyState(VK_SHIFT) & 0x8000){
\r
778 keyState |= MK_SHIFT;
\r
780 if(GetKeyState(VK_CONTROL) & 0x8000){
\r
781 keyState |= MK_CONTROL;
\r
783 if(GetKeyState(VK_MENU) & 0x8000){
\r
784 keyState |= MK_ALT;
\r
786 if(GetKeyState(VK_LBUTTON) & 0x8000){
\r
787 keyState |= MK_LBUTTON;
\r
789 if(GetKeyState(VK_MBUTTON) & 0x8000){
\r
790 keyState |= MK_MBUTTON;
\r
792 if(GetKeyState(VK_RBUTTON) & 0x8000){
\r
793 keyState |= MK_RBUTTON;
\r
795 pdsi->m_keyState = keyState;
\r
796 ((LPDROPSOURCE)pdsi)->lpVtbl->AddRef((LPDROPSOURCE)pdsi);
\r
800 /*
\83h
\83\89\83b
\83O&
\83h
\83\8d\83b
\83v
\82Ì
\8aJ
\8en */
\r
801 ret = DoDragDrop((LPDATAOBJECT)pdoi, (LPDROPSOURCE)pdsi, Effect, &lpdwEffect);
\r
803 /* IDataObject
\82ð
\89ð
\95ú
\82·
\82é */
\r
804 ((LPDATAOBJECT)pdoi)->lpVtbl->Release((LPDATAOBJECT)pdoi);
\r
805 /* IDropSource
\82ð
\89ð
\95ú
\82·
\82é */
\r
806 ((LPDROPSOURCE)pdsi)->lpVtbl->Release((LPDROPSOURCE)pdsi);
\r
808 if(ret == DRAGDROP_S_DROP){
\r
809 /*
\83h
\83\8d\83b
\83v
\90æ
\82Ì
\83A
\83v
\83\8a\83P
\81[
\83V
\83\87\83\93\82ª
\90Ý
\92è
\82µ
\82½
\8cø
\89Ê
\82ð
\95Ô
\82· */
\r
814 /* End of source */
\r