00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #if defined(WIN32) && defined(USE_EXULTSTUDIO) && !defined(UNDER_CE)
00011
00012 #include <iostream>
00013
00014 #include "windrag.h"
00015 #include "u7drag.h"
00016
00017 static UINT CF_EXULT = RegisterClipboardFormat("ExultData");
00018
00019
00020
00021 void Windnd::CreateStudioDropDest(Windnd *& windnd, HWND &hWnd,
00022 Drop_shape_handler_fun shapefun,
00023 Drop_chunk_handler_fun cfun,
00024 Drop_shape_handler_fun facefun,
00025 void *udata)
00026 {
00027 hWnd = GetActiveWindow();
00028 windnd = new Windnd(hWnd, shapefun, cfun, facefun, udata);
00029 if (FAILED(RegisterDragDrop(hWnd, windnd))) {
00030 std::cout << "Something's wrong with OLE2 ..." << std::endl;
00031 }
00032 }
00033
00034 void Windnd::DestroyStudioDropDest(Windnd *& windnd, HWND &hWnd)
00035 {
00036 RevokeDragDrop(hWnd);
00037 delete windnd;
00038 windnd = 0;
00039 hWnd = 0;
00040 }
00041
00042
00043
00044 Windnd::Windnd(HWND hgwnd, Move_shape_handler_fun movefun,
00045 Move_combo_handler_fun movecmbfun,
00046 Drop_shape_handler_fun shapefun,
00047 Drop_chunk_handler_fun cfun, Drop_combo_handler_fun combfun
00048 ) : gamewin(hgwnd), udata(0), move_shape_handler(movefun),
00049 move_combo_handler(movecmbfun), shape_handler(shapefun),
00050 chunk_handler(cfun), face_handler(0), combo_handler(combfun),
00051 drag_id(-1)
00052 {
00053 std::memset (&data, 0, sizeof(data));
00054 m_cRef = 1;
00055 };
00056
00057 Windnd::Windnd(HWND hgwnd, Drop_shape_handler_fun shapefun,
00058 Drop_chunk_handler_fun cfun, Drop_shape_handler_fun ffun, void *d
00059 )
00060 :gamewin(hgwnd), udata(d), move_shape_handler(0), move_combo_handler(0),
00061 shape_handler(shapefun), chunk_handler(cfun),
00062 face_handler(ffun), combo_handler(0), drag_id(-1)
00063 {
00064 std::memset (&data, 0, sizeof(data));
00065 m_cRef = 1;
00066 };
00067
00068 Windnd::~Windnd()
00069 {
00070 };
00071
00072 STDMETHODIMP
00073 Windnd::QueryInterface(REFIID iid, void ** ppvObject)
00074 {
00075 *ppvObject=NULL;
00076 if (IID_IUnknown==iid || IID_IDropTarget==iid)
00077 *ppvObject=this;
00078 if (NULL==*ppvObject)
00079 return E_NOINTERFACE;
00080 ((LPUNKNOWN)*ppvObject)->AddRef();
00081 return NOERROR;
00082 };
00083
00084 STDMETHODIMP_(ULONG)
00085 Windnd::AddRef(void)
00086 {
00087 return ++m_cRef;
00088 };
00089
00090 STDMETHODIMP_(ULONG)
00091 Windnd::Release(void)
00092 {
00093 if (0!=--m_cRef)
00094 return m_cRef;
00095 delete this;
00096 return 0;
00097 };
00098
00099 STDMETHODIMP
00100 Windnd::DragEnter(IDataObject * pDataObject,
00101 DWORD grfKeyState,
00102 POINTL pt,
00103 DWORD * pdwEffect)
00104 {
00105 if (!is_valid(pDataObject)) {
00106 *pdwEffect = DROPEFFECT_NONE;
00107 } else {
00108 *pdwEffect = DROPEFFECT_COPY;
00109 };
00110
00111 std::memset (&data, 0, sizeof(data));
00112
00113 FORMATETC fetc;
00114 fetc.cfFormat = CF_EXULT;
00115 fetc.ptd = NULL;
00116 fetc.dwAspect = DVASPECT_CONTENT;
00117 fetc.lindex = -1;
00118 fetc.tymed = TYMED_HGLOBAL;
00119
00120 STGMEDIUM med;
00121 pDataObject->GetData(&fetc, &med);
00122 windragdata wdd((unsigned char *)GlobalLock(med.hGlobal));
00123 GlobalUnlock(med.hGlobal);
00124 ReleaseStgMedium(&med);
00125
00126 drag_id=wdd.get_id();
00127 switch (drag_id) {
00128
00129 case U7_TARGET_SHAPEID:
00130 Get_u7_shapeid(wdd.get_data(), data.shape.file, data.shape.shape, data.shape.frame);
00131 break;
00132
00133 case U7_TARGET_CHUNKID:
00134 Get_u7_chunkid(wdd.get_data(), data.chunk.chunknum);
00135 break;
00136
00137 case U7_TARGET_COMBOID:
00138 Get_u7_comboid(wdd.get_data(), data.combo.xtiles, data.combo.ytiles, data.combo.right, data.combo.below, data.combo.cnt, data.combo.combo);
00139 break;
00140
00141 default:
00142 break;
00143 }
00144
00145 prevx = -1;
00146 prevy = -1;
00147
00148 return S_OK;
00149 };
00150
00151 STDMETHODIMP
00152 Windnd::DragOver(DWORD grfKeyState,
00153 POINTL pt,
00154 DWORD * pdwEffect)
00155 {
00156 *pdwEffect = DROPEFFECT_COPY;
00157
00158
00159 POINT pnt = { pt.x, pt.y};
00160 ScreenToClient(gamewin, &pnt);
00161
00162 switch (drag_id) {
00163
00164 case U7_TARGET_SHAPEID:
00165 if (data.shape.file == U7_SHAPE_SHAPES) {
00166 if (move_shape_handler) move_shape_handler(data.shape.shape, data.shape.frame,
00167 pnt.x, pnt.y, prevx, prevy, true);
00168 }
00169 break;
00170
00171 case U7_TARGET_COMBOID:
00172 if (data.combo.cnt > 0) {
00173 if (move_combo_handler) move_combo_handler(data.combo.xtiles, data.combo.ytiles,
00174 data.combo.right, data.combo.below, pnt.x, pnt.y, prevx, prevy, true);
00175 }
00176 break;
00177
00178 default:
00179 break;
00180 }
00181
00182 prevx = pnt.x;
00183 prevy = pnt.y;
00184
00185 return S_OK;
00186 };
00187
00188 STDMETHODIMP
00189 Windnd::DragLeave(void)
00190 {
00191 move_shape_handler(-1, -1, 0, 0, prevx, prevy, true);
00192
00193 switch (drag_id) {
00194 case U7_TARGET_SHAPEID:
00195 break;
00196 case U7_TARGET_COMBOID:
00197 delete data.combo.combo;
00198 break;
00199
00200 default:
00201 break;
00202 }
00203 std::memset (&data, 0, sizeof(data));
00204 drag_id = -1;
00205
00206 return S_OK;
00207 };
00208
00209 STDMETHODIMP
00210 Windnd::Drop(IDataObject * pDataObject,
00211 DWORD grfKeyState,
00212 POINTL pt,
00213 DWORD * pdwEffect)
00214 {
00215 *pdwEffect = DROPEFFECT_COPY;
00216 ;
00217
00218
00219 FORMATETC fetc;
00220 fetc.cfFormat = CF_EXULT;
00221 fetc.ptd = NULL;
00222 fetc.dwAspect = DVASPECT_CONTENT;
00223 fetc.lindex = -1;
00224 fetc.tymed = TYMED_HGLOBAL;
00225 STGMEDIUM med;
00226
00227 pDataObject->GetData(&fetc, &med);
00228 windragdata wdd((unsigned char *)GlobalLock(med.hGlobal));
00229 GlobalUnlock(med.hGlobal);
00230 ReleaseStgMedium(&med);
00231
00232 POINT pnt = { pt.x, pt.y};
00233 ScreenToClient(gamewin, &pnt);
00234
00235 int id = wdd.get_id();
00236
00237 if (id == U7_TARGET_SHAPEID) {
00238 int file,shape,frame;
00239 Get_u7_shapeid(wdd.get_data(), file, shape, frame);
00240 if (file == U7_SHAPE_SHAPES) {
00241 if (shape_handler) (*shape_handler)(shape, frame, pnt.x, pnt.y, udata);
00242 }
00243 else if (file == U7_SHAPE_FACES) {
00244 if (face_handler) (*face_handler)(shape, frame, pnt.x, pnt.y, udata);
00245 }
00246 } else if (id == U7_TARGET_CHUNKID) {
00247 int chunknum;
00248 Get_u7_chunkid(wdd.get_data(), chunknum);
00249 if (chunk_handler) (*chunk_handler)(chunknum, pnt.x, pnt.y, udata);
00250 } else if (id == U7_TARGET_COMBOID) {
00251 int xtiles, ytiles;
00252 int right, below, cnt;
00253 U7_combo_data *combo;
00254 Get_u7_comboid(wdd.get_data(), xtiles, ytiles, right, below, cnt, combo);
00255 if (combo_handler) combo_handler(cnt, combo, pnt.x, pnt.y, udata);
00256 delete combo;
00257 }
00258
00259 return S_OK;
00260 };
00261
00262 bool Windnd::is_valid(IDataObject * pDataObject)
00263 {
00264 FORMATETC fetc;
00265 fetc.cfFormat = CF_EXULT;
00266 fetc.ptd = NULL;
00267 fetc.dwAspect = DVASPECT_CONTENT;
00268 fetc.lindex = -1;
00269 fetc.tymed = TYMED_HGLOBAL;
00270
00271 if (FAILED(pDataObject->QueryGetData(& fetc))) {
00272 return false;
00273 } else {
00274 return true;
00275 }
00276 };
00277
00278
00279
00280 Windropsource::Windropsource(HBITMAP pdrag_bitmap, int x0, int y0)
00281 :drag_bitmap(pdrag_bitmap)
00282 {
00283 m_cRef = 1;
00284 drag_shape = 0;
00285
00286 #if 0
00287
00288 SIZE bsize;
00289 GetBitmapDimensionEx(drag_bitmap, &bsize);
00290 bsize.cx = 32; bsize.cy = 32;
00291 int shw = bsize.cx, shh = bsize.cy;
00292 drag_shape = CreateWindowEx(WS_EX_TRANSPARENT,
00293 "STATIC",
00294 NULL,
00295 WS_POPUP,
00296 x0, y0,
00297 shw, shh,
00298 GetForegroundWindow(),
00299 NULL,
00300 (HINSTANCE)GetWindowLong(GetForegroundWindow(), GWL_HINSTANCE),
00301 NULL);
00302
00303 if (FAILED(drag_shape)) {
00304 g_warning("Create Window FAILED !");
00305 };
00306 #endif
00307 };
00308
00309 Windropsource::~Windropsource()
00310 {
00311 DestroyWindow(drag_shape);
00312 };
00313
00314 STDMETHODIMP
00315 Windropsource::QueryInterface(REFIID iid, void ** ppvObject)
00316 {
00317 *ppvObject=NULL;
00318 if (IID_IUnknown==iid || IID_IDropSource==iid)
00319 *ppvObject = this;
00320 if (NULL==*ppvObject)
00321 return E_NOINTERFACE;
00322 ((LPUNKNOWN)*ppvObject)->AddRef();
00323 return NOERROR;
00324 };
00325
00326 STDMETHODIMP_(ULONG)
00327 Windropsource::AddRef(void)
00328 {
00329 m_cRef = m_cRef + 1;
00330
00331 return m_cRef;
00332 };
00333
00334 STDMETHODIMP_(ULONG)
00335 Windropsource::Release(void)
00336 {
00337 if (0!=--m_cRef)
00338 return m_cRef;
00339 delete this;
00340 return 0;
00341 };
00342
00343 STDMETHODIMP
00344 Windropsource::QueryContinueDrag(
00345 BOOL fEscapePressed,
00346 DWORD grfKeyState
00347 )
00348 {
00349 #if 0
00350
00351 POINT pnt;
00352 GetCursorPos(&pnt);
00353
00354 MoveWindow(drag_shape,
00355 pnt.x, pnt.y,
00356 shw, shh,
00357 true);
00358 #endif
00359
00360 if (fEscapePressed)
00361 return DRAGDROP_S_CANCEL;
00362 else if (!(grfKeyState & MK_LBUTTON))
00363 return DRAGDROP_S_DROP;
00364 else
00365 return NOERROR;
00366 };
00367
00368 STDMETHODIMP
00369 Windropsource::GiveFeedback(
00370 DWORD dwEffect
00371 )
00372 {
00373 return DRAGDROP_S_USEDEFAULTCURSORS;
00374 };
00375
00376
00377
00378 Winstudioobj::Winstudioobj(windragdata pdata)
00379 :data(pdata)
00380 {
00381 m_cRef = 1;
00382 drag_image = 0;
00383 };
00384
00385 Winstudioobj::~Winstudioobj()
00386 {
00387 };
00388
00389
00390 STDMETHODIMP
00391 Winstudioobj::QueryInterface(REFIID iid, void ** ppvObject)
00392 {
00393 *ppvObject=NULL;
00394 if (IID_IUnknown==iid || IID_IDataObject==iid)
00395 *ppvObject=this;
00396 if (NULL==*ppvObject)
00397 return E_NOINTERFACE;
00398 ((LPUNKNOWN)*ppvObject)->AddRef();
00399 return NOERROR;
00400 };
00401
00402 STDMETHODIMP_(ULONG)
00403 Winstudioobj::AddRef(void)
00404 {
00405 return ++m_cRef;
00406 };
00407
00408 STDMETHODIMP_(ULONG)
00409 Winstudioobj::Release(void)
00410 {
00411 if (0!=--m_cRef)
00412 return m_cRef;
00413 delete this;
00414 return 0;
00415 };
00416
00417 STDMETHODIMP
00418 Winstudioobj::GetData(
00419 FORMATETC * pFormatetc,
00420 STGMEDIUM * pmedium
00421 )
00422 {
00423 std::cout << "In GetData"<< std::endl;
00424
00425 HGLOBAL hText;
00426 unsigned char *ldata;
00427
00428 pmedium->tymed = 0;
00429 pmedium->pUnkForRelease = NULL;
00430 pmedium->hGlobal = NULL;
00431
00432
00433
00434 if (pFormatetc->cfFormat == CF_EXULT &&
00435 pFormatetc->dwAspect == DVASPECT_CONTENT &&
00436 pFormatetc->tymed == TYMED_HGLOBAL)
00437 {
00438 hText = GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT, 8 + data.get_size());
00439 if (!hText)
00440 return E_OUTOFMEMORY;
00441
00442
00443 ldata = (unsigned char *)GlobalLock(hText);
00444 data.serialize(ldata);
00445 GlobalUnlock(hText);
00446
00447 pmedium->tymed = TYMED_HGLOBAL;
00448 pmedium->hGlobal = hText;
00449
00450 return S_OK;
00451 }
00452
00453 return DATA_E_FORMATETC;
00454 };
00455
00456 STDMETHODIMP
00457 Winstudioobj::GetDataHere(
00458 FORMATETC * pFormatetc,
00459 STGMEDIUM * pmedium
00460 )
00461 {
00462 return DATA_E_FORMATETC;
00463 };
00464
00465 STDMETHODIMP
00466 Winstudioobj::QueryGetData(
00467 FORMATETC * pFormatetc
00468 )
00469 {
00470
00471
00472 if (pFormatetc->cfFormat == CF_EXULT
00473 && pFormatetc->dwAspect == DVASPECT_CONTENT
00474 && pFormatetc->tymed & TYMED_HGLOBAL)
00475 return S_OK;
00476 else return S_FALSE;
00477 };
00478
00479 STDMETHODIMP
00480 Winstudioobj::GetCanonicalFormatEtc(
00481 FORMATETC * pFormatetcIn,
00482 FORMATETC * pFormatetcOut
00483 )
00484 {
00485 pFormatetcOut->ptd = NULL;
00486 return E_NOTIMPL;
00487 };
00488
00489 STDMETHODIMP
00490 Winstudioobj::SetData(
00491 FORMATETC * pFormatetc,
00492 STGMEDIUM * pmedium,
00493 BOOL fRelease
00494 )
00495 {
00496 return E_NOTIMPL;
00497 };
00498
00499 STDMETHODIMP
00500 Winstudioobj::EnumFormatEtc(
00501 DWORD dwDirection,
00502 IEnumFORMATETC ** ppenumFormatetc
00503 )
00504 {
00505 SCODE sc = S_OK;
00506 FORMATETC fmtetc;
00507
00508 fmtetc.cfFormat = CF_EXULT;
00509 fmtetc.dwAspect = DVASPECT_CONTENT;
00510 fmtetc.tymed = TYMED_HGLOBAL;
00511 fmtetc.ptd = NULL;
00512 fmtetc.lindex = -1;
00513
00514 if (dwDirection == DATADIR_GET){
00515 std::cout << "EnumFmt" << std::endl;
00516
00517
00518
00519
00523 sc = E_NOTIMPL;
00524
00525 } else if (dwDirection == DATADIR_SET){
00526
00527
00528
00529 sc = E_NOTIMPL;
00530 goto error;
00531 } else {
00532 sc = E_INVALIDARG;
00533 goto error;
00534 }
00535
00536 error:
00537 return sc;
00538 };
00539
00540 STDMETHODIMP
00541 Winstudioobj::DAdvise(
00542 FORMATETC * pFormatetc,
00543 DWORD advf,
00544 IAdviseSink * pAdvSink,
00545 DWORD * pdwConnection
00546 )
00547 {
00548 return OLE_E_ADVISENOTSUPPORTED;
00549 };
00550
00551 STDMETHODIMP
00552 Winstudioobj::DUnadvise(
00553 DWORD dwConnection
00554 )
00555 {
00556 return OLE_E_ADVISENOTSUPPORTED;
00557 };
00558
00559 STDMETHODIMP
00560 Winstudioobj::EnumDAdvise(
00561 IEnumSTATDATA ** ppenumAdvise
00562 )
00563 {
00564 return OLE_E_ADVISENOTSUPPORTED;
00565 };
00566
00567 #endif