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 <winsock2.h>
\r
19 #include <windows.h>
\r
28 #include "OleDragDrop.h"
\r
31 /* Clipboard format から Type of storage medium を取得 */
\r
32 static DWORD FormatToTymed(const UINT cfFormat)
\r
39 case CF_METAFILEPICT:
\r
40 return TYMED_MFPICT;
\r
42 case CF_ENHMETAFILE:
\r
45 return TYMED_HGLOBAL;
\r
49 /******************************************************************************
\r
53 ******************************************************************************/
\r
55 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_QueryInterface(LPDROPTARGET pThis, REFIID riid, LPVOID *ppvObject);
\r
56 static ULONG STDMETHODCALLTYPE OLE_IDropTarget_AddRef(LPDROPTARGET pThis);
\r
57 static ULONG STDMETHODCALLTYPE OLE_IDropTarget_Release(LPDROPTARGET pThis);
\r
58 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragEnter(LPDROPTARGET pThis, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
\r
59 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragOver(LPDROPTARGET pThis, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
\r
60 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragLeave(LPDROPTARGET pThis);
\r
61 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_Drop(LPDROPTARGET pThis, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
\r
62 static HRESULT APIPRIVATE OLE_IDropTarget_Internal_SendMessage(LPDROPTARGET pThis, UINT uNotify, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL *ppt, LPDWORD pdwEffect);
\r
63 static HRESULT APIPRIVATE DropTarget_GetData(LPDATAOBJECT pdo, UINT cfFormat, LPSTGMEDIUM psm);
\r
64 static HRESULT APIPRIVATE DropTarget_QueryGetData(LPDATAOBJECT pdo, UINT cfFormat);
\r
66 /* IDropTarget Virtual Table */
\r
67 static IDropTargetVtbl dtv = {
\r
68 OLE_IDropTarget_QueryInterface,
\r
69 OLE_IDropTarget_AddRef,
\r
70 OLE_IDropTarget_Release,
\r
71 OLE_IDropTarget_DragEnter,
\r
72 OLE_IDropTarget_DragOver,
\r
73 OLE_IDropTarget_DragLeave,
\r
74 OLE_IDropTarget_Drop
\r
77 typedef struct _IDROPTARGET_INTERNAL{
\r
81 UINT uCallbackMessage;
\r
84 IDROPTARGET_NOTIFY dtn;
\r
85 }IDROPTARGET_INTERNAL , *LPIDROPTARGET_INTERNAL;
\r
87 /* OLEのドロップターゲットとして登録する */
\r
88 BOOL APIPRIVATE OLE_IDropTarget_RegisterDragDrop(HWND hWnd, UINT uCallbackMessage, UINT *cFormat, int cfcnt)
\r
90 static IDROPTARGET_INTERNAL *pdti;
\r
92 pdti = GlobalAlloc(GPTR, sizeof(IDROPTARGET_INTERNAL));
\r
96 pdti->lpVtbl = (LPVOID)&dtv;
\r
98 pdti->hWnd = hWnd; /* メッセージを受け取るウィンドウ */
\r
99 pdti->uCallbackMessage = uCallbackMessage; /* メッセージ */
\r
100 pdti->cFormat = (UINT *)GlobalAlloc(GPTR, sizeof(UINT) * cfcnt); /* 対応しているクリップボードフォーマット */
\r
101 if(pdti->cFormat == NULL){
\r
105 CopyMemory(pdti->cFormat, cFormat, sizeof(UINT) * cfcnt);
\r
106 pdti->cfcnt = cfcnt; /* クリップボードフォーマットの数 */
\r
107 return (S_OK == RegisterDragDrop(hWnd, (LPDROPTARGET)pdti));
\r
110 /* OLEのドロップターゲットを解除する */
\r
111 void APIPRIVATE OLE_IDropTarget_RevokeDragDrop(HWND hWnd)
\r
113 RevokeDragDrop(hWnd);
\r
116 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_QueryInterface(LPDROPTARGET pThis, REFIID riid, PVOID *ppvObject)
\r
118 //要求されたIIDと同じ場合はオブジェクトを返す
\r
119 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropTarget)){
\r
120 *ppvObject = (LPVOID)pThis;
\r
121 ((LPUNKNOWN)*ppvObject)->lpVtbl->AddRef((LPUNKNOWN)*ppvObject);
\r
125 return ResultFromScode(E_NOINTERFACE);
\r
128 static ULONG STDMETHODCALLTYPE OLE_IDropTarget_AddRef(LPDROPTARGET pThis)
\r
130 CONST LPIDROPTARGET_INTERNAL pdti = (LPIDROPTARGET_INTERNAL)pThis;
\r
132 /* reference countをインクリメントする */
\r
134 return pdti->m_refCnt;
\r
137 static ULONG STDMETHODCALLTYPE OLE_IDropTarget_Release(LPDROPTARGET pThis)
\r
139 CONST LPIDROPTARGET_INTERNAL pdti = (LPIDROPTARGET_INTERNAL)pThis;
\r
141 /* reference countをデクリメントする */
\r
144 /* reference countが 0 になった場合はオブジェクトの解放を行う */
\r
145 if(pdti->m_refCnt == 0L){
\r
146 if(pdti->cFormat != NULL){
\r
147 GlobalFree(pdti->cFormat);
\r
152 return pdti->m_refCnt;
\r
155 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragEnter(LPDROPTARGET pThis, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
\r
157 return OLE_IDropTarget_Internal_SendMessage(pThis, IDROPTARGET_NOTIFY_DRAGENTER, pdo, grfKeyState, &pt, pdwEffect);
\r
160 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragOver(LPDROPTARGET pThis, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
\r
162 return OLE_IDropTarget_Internal_SendMessage(pThis, IDROPTARGET_NOTIFY_DRAGOVER, NULL, grfKeyState, &pt, pdwEffect);
\r
165 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_DragLeave(LPDROPTARGET pThis)
\r
167 return OLE_IDropTarget_Internal_SendMessage(pThis, IDROPTARGET_NOTIFY_DRAGLEAVE, NULL, 0, NULL, NULL);
\r
170 static HRESULT STDMETHODCALLTYPE OLE_IDropTarget_Drop(LPDROPTARGET pThis, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
\r
172 return OLE_IDropTarget_Internal_SendMessage(pThis, IDROPTARGET_NOTIFY_DROP, pdo, grfKeyState, &pt, pdwEffect);
\r
175 static HRESULT APIPRIVATE OLE_IDropTarget_Internal_SendMessage(LPDROPTARGET pThis, UINT uNotify, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL *ppt, LPDWORD pdwEffect)
\r
177 CONST LPIDROPTARGET_INTERNAL pdti = (LPIDROPTARGET_INTERNAL)pThis;
\r
178 CONST LPIDROPTARGET_NOTIFY pdtn = &(pdti->dtn);
\r
184 /* 対応しているクリップボードフォーマットがあるか調べる */
\r
185 for(i = 0;i < pdti->cfcnt;i++){
\r
186 if(DropTarget_QueryGetData(pdo, pdti->cFormat[i]) == S_OK){
\r
187 cfFormat = pdti->cFormat[i];
\r
191 /* クリップボードフォーマットからデータを取得する */
\r
193 if (DropTarget_GetData(pdo, cfFormat, &sm) != S_OK){
\r
198 pdtn->ppt = ppt; /* マウスポインタの位置 */
\r
199 pdtn->grfKeyState = grfKeyState; /* キー、マウスボタンの状態 */
\r
200 pdtn->cfFormat = cfFormat; /* クリップボードフォーマット */
\r
201 pdtn->hMem = sm.hGlobal; /* 実データ */
\r
202 pdtn->pdo = pdo; /* IDataObject */
\r
204 /* ウィンドウにイベントを通知する */
\r
205 SendMessage(pdti->hWnd, pdti->uCallbackMessage, (WPARAM)uNotify, (LPARAM)pdtn);
\r
207 /* クリップボード形式のデータの解放 */
\r
209 ReleaseStgMedium(&sm);
\r
214 *pdwEffect &= pdtn->dwEffect;
\r
216 if((*pdwEffect & DROPEFFECT_MOVE) && (*pdwEffect & DROPEFFECT_COPY)){
\r
217 *pdwEffect ^= DROPEFFECT_COPY;
\r
218 pdtn->dwEffect ^= DROPEFFECT_COPY;
\r
224 static HRESULT APIPRIVATE DropTarget_GetData(LPDATAOBJECT pdo, UINT cfFormat, LPSTGMEDIUM psm)
\r
228 /* IDataObjectにクリップボード形式のデータを要求する */
\r
229 fmt.cfFormat = cfFormat;
\r
231 fmt.dwAspect = DVASPECT_CONTENT;
\r
233 fmt.tymed = FormatToTymed(cfFormat);
\r
234 return pdo->lpVtbl->GetData(pdo, &fmt, psm);
\r
237 static HRESULT APIPRIVATE DropTarget_QueryGetData(LPDATAOBJECT pdo, UINT cfFormat)
\r
241 /* IDataObjectに指定のクリップボードフォーマットが存在するか問い合わせる */
\r
242 fmt.cfFormat = cfFormat;
\r
244 fmt.dwAspect = DVASPECT_CONTENT;
\r
246 fmt.tymed = FormatToTymed(cfFormat);
\r
247 return pdo->lpVtbl->QueryGetData(pdo, &fmt);
\r
251 /******************************************************************************
\r
255 ******************************************************************************/
\r
257 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_QueryInterface(LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* lplpvObj);
\r
258 static ULONG STDMETHODCALLTYPE OLE_IEnumFORMATETC_AddRef(LPENUMFORMATETC lpThis);
\r
259 static ULONG STDMETHODCALLTYPE OLE_IEnumFORMATETC_Release(LPENUMFORMATETC lpThis);
\r
260 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Next(LPENUMFORMATETC lpThis, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched);
\r
261 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Skip(LPENUMFORMATETC lpThis, ULONG celt);
\r
262 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Reset(LPENUMFORMATETC lpThis);
\r
263 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Clone(LPENUMFORMATETC lpThis, IEnumFORMATETC **ppenum);
\r
265 /* IEnumFORMATETC Virtual Table */
\r
266 static IEnumFORMATETCVtbl efv = {
\r
267 OLE_IEnumFORMATETC_QueryInterface,
\r
268 OLE_IEnumFORMATETC_AddRef,
\r
269 OLE_IEnumFORMATETC_Release,
\r
270 OLE_IEnumFORMATETC_Next,
\r
271 OLE_IEnumFORMATETC_Skip,
\r
272 OLE_IEnumFORMATETC_Reset,
\r
273 OLE_IEnumFORMATETC_Clone
\r
276 typedef struct _IENUMFORMATETC_INTERNAL{
\r
279 LPUNKNOWN m_pUnknownObj;
\r
280 ULONG m_currElement;
\r
281 ULONG m_numFormats;
\r
282 LPFORMATETC m_formatList;
\r
283 }IENUMFORMATETC_INTERNAL , *LPIENUMFORMATETC_INTERNAL;
\r
285 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_QueryInterface(LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* lplpvObj)
\r
287 //要求されたIIDと同じ場合はオブジェクトを返す
\r
288 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumFORMATETC)){
\r
289 *lplpvObj = (LPVOID) lpThis;
\r
290 ((LPUNKNOWN)*lplpvObj)->lpVtbl->AddRef(((LPUNKNOWN)*lplpvObj));
\r
294 return ResultFromScode(E_NOINTERFACE);
\r
297 static ULONG STDMETHODCALLTYPE OLE_IEnumFORMATETC_AddRef(LPENUMFORMATETC lpThis)
\r
299 CONST LPIENUMFORMATETC_INTERNAL pefi = (LPIENUMFORMATETC_INTERNAL)lpThis;
\r
301 /* reference countをインクリメントする */
\r
303 /* 親オブジェクトのreference countを加える */
\r
304 pefi->m_pUnknownObj->lpVtbl->AddRef(pefi->m_pUnknownObj);
\r
305 return pefi->m_refCnt;
\r
308 static ULONG STDMETHODCALLTYPE OLE_IEnumFORMATETC_Release(LPENUMFORMATETC lpThis)
\r
310 CONST LPIENUMFORMATETC_INTERNAL pefi = (LPIENUMFORMATETC_INTERNAL)lpThis;
\r
312 /* reference countをデクリメントする */
\r
314 /* 親オブジェクトのreference countを減らす */
\r
315 pefi->m_pUnknownObj->lpVtbl->Release(pefi->m_pUnknownObj);
\r
317 /* reference countが 0 になった場合はオブジェクトの解放を行う */
\r
318 if(pefi->m_refCnt == 0L){
\r
319 if(pefi->m_formatList != NULL){
\r
320 GlobalFree(pefi->m_formatList);
\r
325 return pefi->m_refCnt;
\r
328 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Next(LPENUMFORMATETC lpThis, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched)
\r
332 LPIENUMFORMATETC_INTERNAL lpefi = ((LPIENUMFORMATETC_INTERNAL)lpThis);
\r
335 *pceltFetched = 0L;
\r
337 if(lpefi->m_formatList == NULL){
\r
338 return ResultFromScode(S_FALSE);
\r
343 return ResultFromScode(S_FALSE);
\r
345 return ResultFromScode(E_POINTER);
\r
349 if(lpefi->m_currElement >= lpefi->m_numFormats){
\r
350 return ResultFromScode(S_FALSE);
\r
353 for(i = 0;i < celt && lpefi->m_currElement < lpefi->m_numFormats;i++, lpefi->m_currElement++){
\r
354 *rgelt = lpefi->m_formatList[lpefi->m_currElement];
\r
358 if(pceltFetched != NULL){
\r
365 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Skip(LPENUMFORMATETC lpThis, ULONG celt)
\r
367 LPIENUMFORMATETC_INTERNAL lpefi = ((LPIENUMFORMATETC_INTERNAL)lpThis);
\r
369 lpefi->m_currElement += celt;
\r
371 if(lpefi->m_currElement > lpefi->m_numFormats){
\r
372 lpefi->m_currElement = lpefi->m_numFormats;
\r
373 return ResultFromScode(S_FALSE);
\r
378 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Reset(LPENUMFORMATETC lpThis)
\r
380 LPIENUMFORMATETC_INTERNAL lpefi = ((LPIENUMFORMATETC_INTERNAL)lpThis);
\r
382 lpefi->m_currElement = 0L;
\r
386 static HRESULT STDMETHODCALLTYPE OLE_IEnumFORMATETC_Clone(LPENUMFORMATETC lpThis, IEnumFORMATETC **ppenum)
\r
388 LPIENUMFORMATETC_INTERNAL pNew;
\r
389 LPIENUMFORMATETC_INTERNAL lpefi = ((LPIENUMFORMATETC_INTERNAL)lpThis);
\r
392 /* IEnumFORMATETCを作成する */
\r
393 pNew = GlobalAlloc(GPTR, sizeof(IENUMFORMATETC_INTERNAL));
\r
395 return ResultFromScode(E_OUTOFMEMORY);
\r
397 pNew->lpVtbl = (LPVOID)&efv;
\r
398 pNew->m_refCnt = 0;
\r
399 pNew->m_currElement = 0;
\r
401 pNew->m_pUnknownObj = lpefi->m_pUnknownObj;
\r
402 pNew->m_numFormats = lpefi->m_numFormats;
\r
404 /* クリップボードフォーマットのリストをコピーする */
\r
405 pNew->m_formatList = GlobalAlloc(GPTR, sizeof(FORMATETC) * pNew->m_numFormats);
\r
406 if(pNew->m_formatList != NULL){
\r
407 for(i = 0;i < pNew->m_numFormats;i++){
\r
408 pNew->m_formatList[i] = lpefi->m_formatList[i];
\r
412 *ppenum = (struct IEnumFORMATETC *)pNew;
\r
414 return ResultFromScode(E_OUTOFMEMORY);
\r
416 ((LPENUMFORMATETC)pNew)->lpVtbl->AddRef(((LPENUMFORMATETC)pNew));
\r
417 pNew->m_currElement = lpefi->m_currElement;
\r
422 /******************************************************************************
\r
426 ******************************************************************************/
\r
428 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_QueryInterface(LPDATAOBJECT lpThis, REFIID riid, LPVOID FAR *lplpvObj);
\r
429 static ULONG STDMETHODCALLTYPE OLE_IDataObject_AddRef(LPDATAOBJECT lpThis);
\r
430 static ULONG STDMETHODCALLTYPE OLE_IDataObject_Release(LPDATAOBJECT lpThis);
\r
431 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium);
\r
432 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetDataHere(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium);
\r
433 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_QueryGetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc);
\r
434 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT lpThis, FORMATETC *pFormatetcIn, FORMATETC *pFormatetcOut);
\r
435 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_SetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium, BOOL fRelease);
\r
436 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_EnumFormatEtc(LPDATAOBJECT lpThis, DWORD dwDirection, IEnumFORMATETC **ppenumFormatetc);
\r
437 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_DAdvise(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
\r
438 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_DUnadvise(LPDATAOBJECT lpThis, DWORD dwConnection);
\r
439 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_EnumDAdvise(LPDATAOBJECT lpThis, IEnumSTATDATA **ppenumAdvise);
\r
441 /* IDataObject Virtual Table */
\r
442 static IDataObjectVtbl dov = {
\r
443 OLE_IDataObject_QueryInterface,
\r
444 OLE_IDataObject_AddRef,
\r
445 OLE_IDataObject_Release,
\r
446 OLE_IDataObject_GetData,
\r
447 OLE_IDataObject_GetDataHere,
\r
448 OLE_IDataObject_QueryGetData,
\r
449 OLE_IDataObject_GetCanonicalFormatEtc,
\r
450 OLE_IDataObject_SetData,
\r
451 OLE_IDataObject_EnumFormatEtc,
\r
452 OLE_IDataObject_DAdvise,
\r
453 OLE_IDataObject_DUnadvise,
\r
454 OLE_IDataObject_EnumDAdvise
\r
457 typedef struct _IDATAOBJECT_INTERNAL{
\r
462 FORMATETC *m_typeList;
\r
464 UINT uCallbackMessage;
\r
465 }IDATAOBJECT_INTERNAL , *LPIDATAOBJECT_INTERNAL;
\r
468 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_QueryInterface(LPDATAOBJECT lpThis, REFIID riid, LPVOID FAR *lplpvObj)
\r
470 //要求されたIIDと同じ場合はオブジェクトを返す
\r
471 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDataObject)){
\r
472 *lplpvObj = lpThis;
\r
473 ((LPUNKNOWN)*lplpvObj)->lpVtbl->AddRef(((LPUNKNOWN)*lplpvObj));
\r
477 return ResultFromScode(E_NOINTERFACE);
\r
480 static ULONG STDMETHODCALLTYPE OLE_IDataObject_AddRef(LPDATAOBJECT lpThis)
\r
482 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
484 /* reference countをインクリメントする */
\r
486 return pdoi->m_refCnt;
\r
489 static ULONG STDMETHODCALLTYPE OLE_IDataObject_Release(LPDATAOBJECT lpThis)
\r
491 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
493 /* reference countをデクリメントする */
\r
496 /* reference countが 0 になった場合はオブジェクトの解放を行う */
\r
497 if(pdoi->m_refCnt == 0L){
\r
498 if(pdoi->m_typeList != NULL){
\r
499 GlobalFree(pdoi->m_typeList);
\r
504 return pdoi->m_refCnt;
\r
507 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium)
\r
509 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
513 /* 要求されたクリップボードフォーマットが存在するか調べる */
\r
514 for(i = 0;i < pdoi->m_numTypes;i++){
\r
515 if(pdoi->m_typeList[i].cfFormat == pFormatetc->cfFormat){
\r
519 if(i == pdoi->m_numTypes){
\r
520 /* 要求されたクリップボードフォーマットをサポートしてない場合 */
\r
521 return ResultFromScode(DV_E_FORMATETC);
\r
524 // マウスのドラッグ中は WM_GETDATA を送らないようにする。(2007.9.3 yutaka)
\r
525 if (GetAsyncKeyState(VK_LBUTTON) & 0x8000 ||
\r
526 GetAsyncKeyState(VK_RBUTTON) & 0x8000) {
\r
527 return ResultFromScode(DV_E_FORMATETC);
\r
530 /* ウィンドウにデータの要求を行う */
\r
531 SendMessage(pdoi->hWnd, pdoi->uCallbackMessage, (WPARAM)pdoi->m_typeList[i].cfFormat, (LPARAM)&hMem);
\r
533 return ResultFromScode(STG_E_MEDIUMFULL);
\r
535 pmedium->hGlobal = hMem;
\r
536 pmedium->tymed = FormatToTymed(pFormatetc->cfFormat);
\r
537 pmedium->pUnkForRelease = NULL;
\r
541 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetDataHere(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium)
\r
543 return ResultFromScode(E_NOTIMPL);
\r
546 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_QueryGetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc)
\r
548 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
551 /* 要求されたクリップボードフォーマットが存在するか調べる */
\r
552 for(i = 0;i < pdoi->m_numTypes;i++){
\r
553 if(pdoi->m_typeList[i].cfFormat == pFormatetc->cfFormat){
\r
557 return ResultFromScode(DV_E_FORMATETC);
\r
560 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_GetCanonicalFormatEtc(LPDATAOBJECT lpThis, FORMATETC *pFormatetcIn, FORMATETC *pFormatetcOut)
\r
562 return ResultFromScode(E_NOTIMPL);
\r
565 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_SetData(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, STGMEDIUM *pmedium, BOOL fRelease)
\r
567 return ResultFromScode(E_NOTIMPL);
\r
570 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_EnumFormatEtc(LPDATAOBJECT lpThis, DWORD dwDirection, IEnumFORMATETC **ppenumFormatetc)
\r
572 CONST LPIDATAOBJECT_INTERNAL pdoi = (LPIDATAOBJECT_INTERNAL)lpThis;
\r
573 static IENUMFORMATETC_INTERNAL *pefi;
\r
576 if(ppenumFormatetc == NULL){
\r
577 return ResultFromScode(E_INVALIDARG);
\r
580 if(dwDirection != DATADIR_GET){
\r
581 *ppenumFormatetc = NULL;
\r
582 return ResultFromScode(E_NOTIMPL);
\r
585 /* IEnumFORMATETCを作成する */
\r
586 pefi = GlobalAlloc(GPTR, sizeof(IENUMFORMATETC_INTERNAL));
\r
588 return E_OUTOFMEMORY;
\r
590 pefi->lpVtbl = (LPVOID)&efv;
\r
591 pefi->m_refCnt = 0;
\r
592 pefi->m_currElement = 0;
\r
593 pefi->m_pUnknownObj = (struct IUnknown *)lpThis;
\r
594 pefi->m_numFormats = pdoi->m_numTypes;
\r
596 /* クリップボードフォーマットのリストをコピーする */
\r
597 pefi->m_formatList = GlobalAlloc(GPTR, sizeof(FORMATETC) * pefi->m_numFormats);
\r
598 if(pefi->m_formatList != NULL){
\r
599 for(i = 0;i < pefi->m_numFormats;i++){
\r
600 pefi->m_formatList[i] = pdoi->m_typeList[i];
\r
604 ((LPENUMFORMATETC)pefi)->lpVtbl->AddRef(((LPENUMFORMATETC)pefi));
\r
606 *ppenumFormatetc = (struct IEnumFORMATETC *)pefi;
\r
607 if(*ppenumFormatetc == NULL){
\r
608 return E_OUTOFMEMORY;
\r
613 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_DAdvise(LPDATAOBJECT lpThis, FORMATETC *pFormatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
\r
615 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
\r
618 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_DUnadvise(LPDATAOBJECT lpThis, DWORD dwConnection)
\r
620 return ResultFromScode(OLE_E_NOCONNECTION);
\r
623 static HRESULT STDMETHODCALLTYPE OLE_IDataObject_EnumDAdvise(LPDATAOBJECT lpThis, IEnumSTATDATA **ppenumAdvise)
\r
625 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
\r
629 /******************************************************************************
\r
633 ******************************************************************************/
\r
635 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_QueryInterface(LPDROPSOURCE lpThis, REFIID riid, LPVOID FAR* lplpvObj);
\r
636 static ULONG STDMETHODCALLTYPE OLE_IDropSource_AddRef(LPDROPSOURCE lpThis);
\r
637 static ULONG STDMETHODCALLTYPE OLE_IDropSource_Release(LPDROPSOURCE lpThis);
\r
638 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_QueryContinueDrag(LPDROPSOURCE lpThis, BOOL fEscapePressed, DWORD grfKeyState);
\r
639 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_GiveFeedback(LPDROPSOURCE lpThis, DWORD dwEffect);
\r
641 /* IDropSource Virtual Table */
\r
642 static IDropSourceVtbl dsv = {
\r
643 OLE_IDropSource_QueryInterface,
\r
644 OLE_IDropSource_AddRef,
\r
645 OLE_IDropSource_Release,
\r
646 OLE_IDropSource_QueryContinueDrag,
\r
647 OLE_IDropSource_GiveFeedback,
\r
650 typedef struct _IDROPSOURCE_INTERNAL{
\r
656 UINT m_uCallbackDragOverMessage;
\r
657 }IDROPSOURCE_INTERNAL , *LPIDROPSOURCE_INTERNAL;
\r
659 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_QueryInterface(LPDROPSOURCE lpThis, REFIID riid, LPVOID FAR *lplpvObj)
\r
661 //要求されたIIDと同じ場合はオブジェクトを返す
\r
662 if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropSource)){
\r
663 *lplpvObj = (LPVOID) lpThis;
\r
664 ((LPUNKNOWN)*lplpvObj)->lpVtbl->AddRef(((LPUNKNOWN)*lplpvObj));
\r
668 return ResultFromScode(E_NOINTERFACE);
\r
672 static ULONG STDMETHODCALLTYPE OLE_IDropSource_AddRef(LPDROPSOURCE lpThis)
\r
674 CONST LPIDROPSOURCE_INTERNAL pdsi = (LPIDROPSOURCE_INTERNAL)lpThis;
\r
676 /* reference countをインクリメントする */
\r
678 return pdsi->m_refCnt;
\r
681 static ULONG STDMETHODCALLTYPE OLE_IDropSource_Release(LPDROPSOURCE lpThis)
\r
683 CONST LPIDROPSOURCE_INTERNAL pdsi = (LPIDROPSOURCE_INTERNAL)lpThis;
\r
685 /* reference countをデクリメントする */
\r
688 /* reference countが 0 になった場合はオブジェクトの解放を行う */
\r
689 if(pdsi->m_refCnt == 0L){
\r
693 return pdsi->m_refCnt;
\r
696 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_QueryContinueDrag(LPDROPSOURCE lpThis, BOOL fEscapePressed, DWORD grfKeyState)
\r
698 CONST LPIDROPSOURCE_INTERNAL pdsi = (LPIDROPSOURCE_INTERNAL)lpThis;
\r
700 if(fEscapePressed){
\r
701 /* エスケープが押された場合はキャンセルにする */
\r
702 return ResultFromScode(DRAGDROP_S_CANCEL);
\r
705 // Mouse overの通知 (yutaka)
\r
706 SendMessage(pdsi->m_hWnd, pdsi->m_uCallbackDragOverMessage, 0, 0);
\r
708 /* 指定のキーやマウスが離された場合はドロップにする */
\r
709 if(pdsi->m_button == 0){
\r
710 if(grfKeyState != pdsi->m_keyState){
\r
711 return ResultFromScode(DRAGDROP_S_DROP);
\r
714 if(!(grfKeyState & pdsi->m_button)){
\r
715 return ResultFromScode(DRAGDROP_S_DROP);
\r
721 static HRESULT STDMETHODCALLTYPE OLE_IDropSource_GiveFeedback(LPDROPSOURCE lpThis, DWORD dwEffect)
\r
723 return ResultFromScode(DRAGDROP_S_USEDEFAULTCURSORS);
\r
727 int APIPRIVATE OLE_IDropSource_Start(HWND hWnd, UINT uCallbackMessage, UINT uCallbackDragOverMessage, UINT *ClipFormtList, int cfcnt, int Effect)
\r
729 static IDATAOBJECT_INTERNAL *pdoi;
\r
730 static IDROPSOURCE_INTERNAL *pdsi;
\r
736 /* IDataObjectの作成 */
\r
737 pdoi = GlobalAlloc(GPTR, sizeof(IDATAOBJECT_INTERNAL));
\r
741 pdoi->lpVtbl = (LPVOID)&dov;
\r
742 pdoi->m_refCnt = 0;
\r
743 pdoi->m_numTypes = cfcnt;
\r
744 pdoi->m_maxTypes = cfcnt;
\r
745 /* 有効なクリップボードフォーマットを設定する */
\r
746 pdoi->m_typeList = GlobalAlloc(GPTR, sizeof(FORMATETC) * cfcnt);
\r
747 if(pdoi->m_typeList == NULL){
\r
751 for(i = 0;i < cfcnt;i++){
\r
752 pdoi->m_typeList[i].cfFormat = ClipFormtList[i];
\r
753 pdoi->m_typeList[i].ptd = NULL;
\r
754 pdoi->m_typeList[i].dwAspect = DVASPECT_CONTENT;
\r
755 pdoi->m_typeList[i].lindex = -1;
\r
756 pdoi->m_typeList[i].tymed = FormatToTymed(ClipFormtList[i]);
\r
759 pdoi->uCallbackMessage = uCallbackMessage;
\r
760 ((LPDATAOBJECT)pdoi)->lpVtbl->AddRef((LPDATAOBJECT)pdoi);
\r
762 /* IDropSourceの作成 */
\r
763 pdsi = GlobalAlloc(GPTR, sizeof(IDROPSOURCE_INTERNAL));
\r
765 /* IDataObjectを解放する */
\r
766 ((LPDATAOBJECT)pdoi)->lpVtbl->Release((LPDATAOBJECT)pdoi);
\r
769 pdsi->lpVtbl = (LPVOID)&dsv;
\r
770 pdsi->m_refCnt = 0;
\r
771 pdsi->m_hWnd = hWnd; // yutaka
\r
772 pdsi->m_uCallbackDragOverMessage = uCallbackDragOverMessage;
\r
775 if(GetKeyState(VK_RBUTTON) & 0x8000){
\r
776 pdsi->m_button = MK_RBUTTON;
\r
778 pdsi->m_button = MK_LBUTTON;
\r
783 if(GetKeyState(VK_SHIFT) & 0x8000){
\r
784 keyState |= MK_SHIFT;
\r
786 if(GetKeyState(VK_CONTROL) & 0x8000){
\r
787 keyState |= MK_CONTROL;
\r
789 if(GetKeyState(VK_MENU) & 0x8000){
\r
790 keyState |= MK_ALT;
\r
792 if(GetKeyState(VK_LBUTTON) & 0x8000){
\r
793 keyState |= MK_LBUTTON;
\r
795 if(GetKeyState(VK_MBUTTON) & 0x8000){
\r
796 keyState |= MK_MBUTTON;
\r
798 if(GetKeyState(VK_RBUTTON) & 0x8000){
\r
799 keyState |= MK_RBUTTON;
\r
801 pdsi->m_keyState = keyState;
\r
802 ((LPDROPSOURCE)pdsi)->lpVtbl->AddRef((LPDROPSOURCE)pdsi);
\r
807 ret = DoDragDrop((LPDATAOBJECT)pdoi, (LPDROPSOURCE)pdsi, Effect, &lpdwEffect);
\r
809 /* IDataObjectを解放する */
\r
810 ((LPDATAOBJECT)pdoi)->lpVtbl->Release((LPDATAOBJECT)pdoi);
\r
811 /* IDropSourceを解放する */
\r
812 ((LPDROPSOURCE)pdsi)->lpVtbl->Release((LPDROPSOURCE)pdsi);
\r
814 if(ret == DRAGDROP_S_DROP){
\r
815 /* ドロップ先のアプリケーションが設定した効果を返す */
\r
820 /* End of source */
\r