Changeset 50265 in vbox for trunk/src/VBox/Additions/WINNT
- Timestamp:
- Jan 29, 2014 11:12:44 AM (11 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/VBoxTray
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp
r50179 r50265 229 229 } while (RT_SUCCESS(rc)); 230 230 231 int rc2 = pThis->UnregisterAsDropTarget(); 232 if (RT_SUCCESS(rc)) 233 rc = rc2; 234 231 235 OleUninitialize(); 232 236 } … … 405 409 reset(); 406 410 407 Assert(mMode == Unknown);408 411 mMode = HG; 409 412 … … 464 467 465 468 rc = OnHgCancel(); 466 467 reset();468 469 break; 469 470 } … … 473 474 LogFlowThisFunc(("HOST_DND_GH_REQ_PENDING\n")); 474 475 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 475 Assert( mMode == Unknown 476 || mMode == GH); 477 mMode = GH; 478 rc = OnGhIsDnDPending(pEvent->Event.uScreenId); 476 if ( mMode == Unknown 477 /* There can be more than one HOST_DND_GH_REQ_PENDING 478 * messages coming in. */ 479 || mMode == GH) 480 { 481 mMode = GH; 482 rc = OnGhIsDnDPending(pEvent->Event.uScreenId); 483 } 484 else 485 rc = VERR_WRONG_ORDER; 479 486 #else 480 487 rc = VERR_NOT_SUPPORTED; … … 487 494 LogFlowThisFunc(("HOST_DND_GH_EVT_DROPPED\n")); 488 495 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 489 Assert(mMode == GH); 490 rc = OnGhDropped(pEvent->Event.pszFormats, 491 pEvent->Event.cbFormats, 492 pEvent->Event.u.a.uDefAction); 493 mMode = Unknown; 496 if (mMode == GH) 497 { 498 rc = OnGhDropped(pEvent->Event.pszFormats, 499 pEvent->Event.cbFormats, 500 pEvent->Event.u.a.uDefAction); 501 } 502 else 503 rc = VERR_WRONG_ORDER; 494 504 #else 495 505 rc = VERR_NOT_SUPPORTED; … … 585 595 } 586 596 else 597 { 587 598 rc = VINF_SUCCESS; 599 } 588 600 } 589 601 catch (std::bad_alloc) … … 598 610 int VBoxDnDWnd::UnregisterAsDropTarget(void) 599 611 { 612 LogFlowFuncEnter(); 613 600 614 if (!pDropTarget) /* No drop target? Bail out. */ 601 615 return VINF_SUCCESS; … … 606 620 TRUE /* fLastUnlockReleases */); 607 621 if (SUCCEEDED(hr)) 608 pDropTarget->Release(); 622 { 623 ULONG cRefs = pDropTarget->Release(); 624 625 Assert(cRefs == 0); 626 pDropTarget = NULL; 627 } 609 628 610 629 int rc = SUCCEEDED(hr) … … 652 671 */ 653 672 const RTCList<RTCString> lstAllowedMimeTypes = RTCList<RTCString>() 654 /* U ri's */673 /* URI's */ 655 674 << "text/uri-list" 656 675 /* Text */ … … 661 680 << "TEXT" 662 681 << "STRING" 663 /* OpenOffice format es */682 /* OpenOffice formats */ 664 683 << "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"" 665 684 << "application/x-openoffice-drawing;windows_formatname=\"Drawing Format\""; … … 855 874 if (RT_SUCCESS(rc)) 856 875 rc = rc2; 876 877 reset(); 857 878 858 879 return rc; … … 959 980 if (RT_SUCCESS(rc)) 960 981 { 982 AssertPtr(pDropTarget); 983 961 984 uint32_t uDefAction = DND_IGNORE_ACTION; 962 985 RTCString strFormat = "unknown"; 963 if ( pDropTarget 964 && pDropTarget->HasData()) 986 if (pDropTarget->HasData()) 965 987 { 966 988 uDefAction = DND_COPY_ACTION; … … 970 992 * with \r\n. */ 971 993 strFormat = "text/plain;charset=utf-8"; 972 } 973 974 LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormat=%s\n",975 pDropTarget, uDefAction, uAllActions, strFormat.c_str()));976 rc = VbglR3DnDGHAcknowledgePending(mClientID,977 uDefAction, uAllActions, strFormat.c_str());994 995 LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormat=%s\n", 996 pDropTarget, uDefAction, uAllActions, strFormat.c_str())); 997 rc = VbglR3DnDGHAcknowledgePending(mClientID, 998 uDefAction, uAllActions, strFormat.c_str()); 999 } 978 1000 } 979 1001 … … 985 1007 uint32_t uDefAction) 986 1008 { 987 LogFlowThisFunc(("mMode=%ld, mState=%ld, cbFormats=%RU32, uDefAction=0x%x\n",988 mMode, mState, cbFormats, uDefAction));1009 LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, cbFormats=%RU32, uDefAction=0x%x\n", 1010 mMode, mState, pDropTarget, cbFormats, uDefAction)); 989 1011 int rc; 990 1012 if (mState == Dragging) 991 1013 { 992 1014 AssertPtr(pDropTarget); 1015 rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout */); 1016 if (RT_SUCCESS(rc)) 1017 { 1018 /** @todo Respect uDefAction. */ 1019 /** @todo Do data checking / conversion based on pszFormats. */ 1020 1021 void *pvData = pDropTarget->DataMutableRaw(); 1022 AssertPtr(pvData); 1023 uint32_t cbData = pDropTarget->DataSize(); 1024 Assert(cbData); 1025 1026 rc = VbglR3DnDGHSendData(mClientID, pvData, cbData); 1027 LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n", 1028 pvData, cbData, rc)); 1029 } 1030 1031 reset(); 993 1032 } 994 1033 else -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h
r50177 r50265 151 151 152 152 static DWORD GetDropEffect(DWORD grfKeyState, DWORD dwAllowedEffects); 153 154 public: 155 156 const IDataObject *GetDataObject(void) { return mpDataObject; } 157 bool HasData(void) { return mfHasDropData; } 153 void reset(void); 154 155 public: 156 157 bool HasData(void) { return RT_BOOL(mFormatEtc.cfFormat != 0); } 158 void *DataMutableRaw(void) { return mpvData; } 159 uint32_t DataSize(void) { return mcbData; } 160 int WaitForDrop(RTMSINTERVAL msTimeout); 158 161 159 162 protected: … … 163 166 uint32_t mClientID; 164 167 DWORD mdwCurEffect; 165 IDataObject *mpDataObject; 166 bool mfHasDropData; 168 /** Copy of the data object's FORMATETC struct. 169 * Note: We don't keep the pointer of the 170 * DVTARGETDEVICE here! */ 171 FORMATETC mFormatEtc; 172 void *mpvData; 173 uint32_t mcbData; 174 RTSEMEVENT hEventDrop; 167 175 }; 168 176 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp
r50177 r50265 31 31 mClientID(UINT32_MAX), 32 32 mdwCurEffect(0), 33 mpDataObject(NULL), 34 mfHasDropData(false) 33 mpvData(NULL), 34 mcbData(0), 35 hEventDrop(NIL_RTSEMEVENT) 35 36 { 36 37 int rc = VbglR3DnDConnect(&mClientID); 38 if (RT_SUCCESS(rc)) 39 rc = RTSemEventCreate(&hEventDrop); 37 40 38 41 LogFlowFunc(("clientID=%RU32, rc=%Rrc\n", … … 42 45 VBoxDnDDropTarget::~VBoxDnDDropTarget(void) 43 46 { 44 int rc = VbglR3DnDDisconnect(mClientID); 45 46 LogFlowFunc(("rc=%Rrc, mRefCount=%RI32\n", rc, mRefCount)); 47 reset(); 48 49 int rc2 = VbglR3DnDDisconnect(mClientID); 50 AssertRC(rc2); 51 rc2 = RTSemEventDestroy(hEventDrop); 52 AssertRC(rc2); 53 54 LogFlowFunc(("rc=%Rrc, mRefCount=%RI32\n", rc2, mRefCount)); 47 55 } 48 56 … … 94 102 AssertPtrReturn(pdwEffect, E_INVALIDARG); 95 103 96 LogFlowFunc(("mfHasDropData=%RTbool, pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld, dwEffect=%RU32\n", 97 mfHasDropData, pDataObject, grfKeyState, pt.x, pt.y, *pdwEffect)); 98 99 FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; 100 101 /* We only handle CF_HDROP in an HGLOBAL medium at the moment. */ 102 HRESULT hr = pDataObject->QueryGetData(&fmtetc); 103 mfHasDropData = hr == S_OK; 104 105 if (mfHasDropData) 106 { 104 LogFlowFunc(("pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld, dwEffect=%RU32\n", 105 pDataObject, grfKeyState, pt.x, pt.y, *pdwEffect)); 106 107 reset(); 108 109 /* Try different formats. CF_HDROP is the most common one, so start 110 * with this. */ 111 /** @todo At the moment we only support TYMED_HGLOBAL. */ 112 FORMATETC fmtEtc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; 113 HRESULT hr = pDataObject->QueryGetData(&fmtEtc); 114 if (hr != S_OK) 115 { 116 LogFlowFunc(("CF_HDROP not supported, hr=%Rhrc\n", hr)); 117 118 /* So we couldn't retrieve the data in CF_HDROP format; try with 119 * CF_TEXT format now. Rest stays the same. */ 120 fmtEtc.cfFormat = CF_TEXT; 121 hr = pDataObject->QueryGetData(&fmtEtc); 122 if (hr != S_OK) 123 { 124 LogFlowFunc(("CF_TEXT not supported, hr=%Rhrc\n", hr)); 125 fmtEtc.cfFormat = 0; /* Mark it to not supported. */ 126 } 127 } 128 129 /* Did we find a format that we support? */ 130 if (fmtEtc.cfFormat) 131 { 132 LogFlowFunc(("Found supported format %RI16\n", fmtEtc.cfFormat)); 133 134 /* Make a copy of the FORMATETC structure so that we later can 135 * use this for comparrison and stuff. */ 136 /** Note: The DVTARGETDEVICE member only is a shallow copy! */ 137 memcpy(&mFormatEtc, &fmtEtc, sizeof(FORMATETC)); 138 107 139 /* Which drop effect we're going to use? */ 108 140 /* Note: pt is not used since we don't need to differentiate within our … … 114 146 /* No or incompatible data -- so no drop effect required. */ 115 147 *pdwEffect = DROPEFFECT_NONE; 116 } 117 118 LogFlowFunc(("Returning mfHasDropData=%RTbool, pdwEffect=%ld, hr=%Rhrc\n", 119 mfHasDropData, *pdwEffect, hr)); 148 149 switch (hr) 150 { 151 case ERROR_INVALID_FUNCTION: 152 { 153 LogRel(("DnD: Drag'n drop format is not supported by VBoxTray\n")); 154 155 /* Enumerate supported source formats. This shouldn't happen too often 156 * on day to day use, but still keep it in here. */ 157 IEnumFORMATETC *pEnumFormats; 158 HRESULT hr2 = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormats); 159 if (SUCCEEDED(hr2)) 160 { 161 LogRel(("DnD: The following formats were offered to us:\n")); 162 163 FORMATETC curFormatEtc; 164 while (pEnumFormats->Next(1, &curFormatEtc, 165 NULL /* pceltFetched */) == S_OK) 166 { 167 WCHAR wszCfName[128]; /* 128 chars should be enough, rest will be truncated. */ 168 hr2 = GetClipboardFormatNameW(curFormatEtc.cfFormat, wszCfName, 169 sizeof(wszCfName) / sizeof(WCHAR)); 170 LogRel(("\tcfFormat=%RI16, tyMed=%RI32, dwAspect=%RI32, strCustomName=%ls, hr=%Rhrc\n", 171 curFormatEtc.cfFormat, 172 curFormatEtc.tymed, 173 curFormatEtc.dwAspect, 174 wszCfName, hr2)); 175 } 176 177 pEnumFormats->Release(); 178 } 179 180 break; 181 } 182 183 default: 184 break; 185 } 186 } 187 188 LogFlowFunc(("Returning cfFormat=%RI16, pdwEffect=%ld, hr=%Rhrc\n", 189 fmtEtc.cfFormat, *pdwEffect, hr)); 120 190 return hr; 121 191 } … … 126 196 127 197 #ifdef DEBUG_andy 128 LogFlowFunc((" mfHasDropData=%RTbool, grfKeyState=0x%x, x=%ld, y=%ld\n",129 m fHasDropData, grfKeyState, pt.x, pt.y));198 LogFlowFunc(("cfFormat=%RI16, grfKeyState=0x%x, x=%ld, y=%ld\n", 199 mFormatEtc.cfFormat, grfKeyState, pt.x, pt.y)); 130 200 #endif 131 201 132 if (m fHasDropData)202 if (mFormatEtc.cfFormat) 133 203 { 134 204 /* Note: pt is not used since we don't need to differentiate within our … … 150 220 { 151 221 #ifdef DEBUG_andy 152 LogFlowFunc((" mfHasDropData=%RTbool\n", mfHasDropData));222 LogFlowFunc(("cfFormat=%RI16\n", mFormatEtc.cfFormat)); 153 223 #endif 154 224 155 mpWndParent->hide(); 225 if (mpWndParent) 226 mpWndParent->hide(); 156 227 157 228 return S_OK; … … 165 236 166 237 #ifdef DEBUG 167 LogFlowFunc(("m fHasDropData=%RTbool, pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld\n",168 m fHasDropData, pDataObject, grfKeyState, pt.x, pt.y));238 LogFlowFunc(("mFormatEtc.cfFormat=%RI16, pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld\n", 239 mFormatEtc.cfFormat, pDataObject, grfKeyState, pt.x, pt.y)); 169 240 #endif 241 HRESULT hr = S_OK; 242 170 243 bool fCanDrop = false; 171 if (mfHasDropData) 172 { 173 FORMATETC fmtEtc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; 244 if (mFormatEtc.cfFormat) /* Did we get a supported format yet? */ 245 { 246 /* Make sure the data object's data format is still the same 247 * as we got it in DragEnter(). */ 248 hr = pDataObject->QueryGetData(&mFormatEtc); 249 AssertMsg(SUCCEEDED(hr), 250 ("Data format changed between DragEnter() and Drop(), cfFormat=%RI16, hr=%Rhrc\n", 251 mFormatEtc.cfFormat, hr)); 252 } 253 254 if (SUCCEEDED(hr)) 255 { 174 256 STGMEDIUM stgMed; 175 176 AssertPtr(pDataObject); 177 if ( (pDataObject->QueryGetData(&fmtEtc) == S_OK) 178 && (pDataObject->GetData(&fmtEtc, &stgMed) == S_OK)) 257 hr = pDataObject->GetData(&mFormatEtc, &stgMed); 258 if (SUCCEEDED(hr)) 179 259 { 180 PVOID pvData = GlobalLock(stgMed.hGlobal); 181 #ifdef DEBUG 182 if (fmtEtc.cfFormat == CF_TEXT) 183 LogFlowFunc(("pvData=%s\n", (char*)pvData)); 184 #endif 185 GlobalUnlock(stgMed.hGlobal); 260 /* 261 * First stage: Prepare the access to the storage medium. 262 * For now we only support HGLOBAL stuff. 263 */ 264 PVOID pvData = NULL; /** @todo Put this in an own union? */ 265 266 switch (mFormatEtc.tymed) 267 { 268 case TYMED_HGLOBAL: 269 pvData = GlobalLock(stgMed.hGlobal); 270 if (!pvData) 271 { 272 LogFlowFunc(("Locking HGLOBAL storage failed with %Rrc\n", 273 RTErrConvertFromWin32(GetLastError()))); 274 hr = ERROR_INVALID_HANDLE; 275 } 276 break; 277 278 default: 279 AssertMsgFailed(("Storage medium type %RI32 supported\n", 280 mFormatEtc.tymed)); 281 hr = ERROR_NOT_SUPPORTED; 282 break; 283 } 284 285 if (SUCCEEDED(hr)) 286 { 287 /* Second stage: Do the actual copying of the data object's data, 288 based on the storage medium type. */ 289 switch (mFormatEtc.cfFormat) 290 { 291 case CF_TEXT: 292 { 293 LogFlowFunc(("pvData=%s\n", (char*)pvData)); 294 295 uint32_t cbSize = strlen((char*)pvData); /** @todo Evil hack, fix this! */ 296 mpvData = RTMemDup(pvData, cbSize); 297 mcbData = cbSize; 298 break; 299 } 300 301 case CF_HDROP: 302 break; 303 304 default: 305 AssertMsgFailed(("Format of type %RI16 supported\n", 306 mFormatEtc.cfFormat)); 307 hr = ERROR_NOT_SUPPORTED; 308 break; 309 } 310 } 311 312 /* 313 * Third stage: Release access to the storage medium again. 314 */ 315 switch (mFormatEtc.tymed) 316 { 317 case TYMED_HGLOBAL: 318 GlobalUnlock(stgMed.hGlobal); 319 break; 320 321 default: 322 AssertMsgFailed(("Storage medium type %RI32 supported\n", 323 mFormatEtc.tymed)); 324 hr = ERROR_NOT_SUPPORTED; 325 break; 326 } 186 327 187 328 /* Release storage medium again. */ 188 329 ReleaseStgMedium(&stgMed); 189 330 190 fCanDrop = true; 331 if (SUCCEEDED(hr)) 332 { 333 RTSemEventSignal(hEventDrop); 334 fCanDrop = true; 335 } 191 336 } 192 337 } … … 201 346 *pdwEffect = DROPEFFECT_NONE; 202 347 203 LogFlowFunc(("Returning with mfHasDropData=%RTbool, fCanDrop=%RTbool, *pdwEffect=%RI32\n", 204 mfHasDropData, fCanDrop, *pdwEffect)); 205 return S_OK; 348 if (mpWndParent) 349 mpWndParent->hide(); 350 351 LogFlowFunc(("Returning with mFormatEtc.cfFormat=%RI16, fCanDrop=%RTbool, *pdwEffect=%RI32\n", 352 mFormatEtc.cfFormat, fCanDrop, *pdwEffect)); 353 return hr; 206 354 } 207 355 … … 235 383 } 236 384 385 void VBoxDnDDropTarget::reset(void) 386 { 387 LogFlowFuncEnter(); 388 389 if (mpvData) 390 { 391 RTMemFree(mpvData); 392 mpvData = NULL; 393 } 394 395 mcbData = 0; 396 RT_ZERO(mFormatEtc); 397 } 398 399 int VBoxDnDDropTarget::WaitForDrop(RTMSINTERVAL msTimeout) 400 { 401 LogFlowFunc(("msTimeout=%RU32\n", msTimeout)); 402 int rc = RTSemEventWait(hEventDrop, msTimeout); 403 LogFlowFuncLeaveRC(rc); 404 return rc; 405 } 406
Note:
See TracChangeset
for help on using the changeset viewer.