Changeset 50305 in vbox for trunk/src/VBox/Additions/WINNT
- Timestamp:
- Feb 3, 2014 10:47:45 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
r50266 r50305 515 515 reset(); 516 516 rc = VINF_SUCCESS; /** @todo GUEST_DND_GH_EVT_ERROR */ 517 #else 518 rc = VERR_NOT_SUPPORTED; 519 #endif 520 break; 521 } 522 523 case DragAndDropSvc::HOST_DND_GH_RECV_DIR: 524 { 525 LogFlowThisFunc(("HOST_DND_GH_RECV_DIR\n")); 526 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 527 if (mMode == GH) 528 { 529 rc = OnGhSendDir(pEvent->Event.pszFormats, 530 pEvent->Event.cbFormats, 531 pEvent->Event.u.a.uDefAction); 532 } 533 else 534 rc = VERR_WRONG_ORDER; 535 #else 536 rc = VERR_NOT_SUPPORTED; 537 #endif 538 break; 539 } 540 541 case DragAndDropSvc::HOST_DND_GH_RECV_FILE: 542 { 543 LogFlowThisFunc(("HOST_DND_GH_RECV_FILE\n")); 544 #ifdef VBOX_WITH_DRAG_AND_DROP_GH 545 if (mMode == GH) 546 { 547 rc = OnGhSendFile(pEvent->Event.pszFormats, 548 pEvent->Event.cbFormats, 549 pEvent->Event.u.a.uDefAction); 550 } 551 else 552 rc = VERR_WRONG_ORDER; 517 553 #else 518 554 rc = VERR_NOT_SUPPORTED; … … 934 970 #endif 935 971 936 #if 1937 972 /** @todo Multi-monitor setups? */ 938 973 int iScreenX = GetSystemMetrics(SM_CXSCREEN) - 1; … … 963 998 else 964 999 LogFlowFunc(("Unable to send input, error=0x%x\n", GetLastError())); 965 #else966 SetCursorPos(p.x, p.y);967 #endif968 1000 969 1001 #ifdef DEBUG_andy … … 981 1013 if (RT_SUCCESS(rc)) 982 1014 { 1015 uint32_t uDefAction = DND_IGNORE_ACTION; 1016 983 1017 AssertPtr(pDropTarget); 984 985 uint32_t uDefAction = DND_IGNORE_ACTION; 986 RTCString strFormat = "unknown"; 987 if (pDropTarget->HasData()) 1018 RTCString strFormats = pDropTarget->Formats(); 1019 if (!strFormats.isEmpty()) 988 1020 { 989 1021 uDefAction = DND_COPY_ACTION; 990 1022 uAllActions = uDefAction; 991 1023 992 /** @todo There can be more than one format, separated 993 * with \r\n. */ 994 strFormat = "text/plain;charset=utf-8"; 995 996 LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormat=%s\n", 997 pDropTarget, uDefAction, uAllActions, strFormat.c_str())); 1024 LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormats=%s\n", 1025 pDropTarget, uDefAction, uAllActions, strFormats.c_str())); 998 1026 rc = VbglR3DnDGHAcknowledgePending(mClientID, 999 uDefAction, uAllActions, strFormat.c_str()); 1000 } 1027 uDefAction, uAllActions, strFormats.c_str()); 1028 } 1029 else 1030 LogFlowFunc(("No format data available yet\n")); 1001 1031 } 1002 1032 … … 1008 1038 uint32_t uDefAction) 1009 1039 { 1010 LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, cbFormats=%RU32, uDefAction=0x%x\n", 1011 mMode, mState, pDropTarget, cbFormats, uDefAction)); 1040 AssertPtrReturn(pszFormats, VERR_INVALID_POINTER); 1041 AssertReturn(cbFormats, VERR_INVALID_PARAMETER); 1042 1043 LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, uDefAction=0x%x\n", 1044 mMode, mState, pDropTarget, uDefAction)); 1045 #ifdef DEBUG 1046 RTCList<RTCString> lstFormats = 1047 RTCString(pszFormats, cbFormats - 1).split("\r\n"); 1048 1049 LogFlow(("cbFormats=%RU32: ", cbFormats)); 1050 for (size_t i = 0; i < lstFormats.size(); i++) 1051 LogFlow(("'%s' ", lstFormats.at(i).c_str())); 1052 LogFlow(("\n")); 1053 #endif 1054 1012 1055 int rc; 1013 1056 if (mState == Dragging) 1014 1057 { 1015 1058 AssertPtr(pDropTarget); 1016 rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout */);1059 rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */); 1017 1060 if (RT_SUCCESS(rc)) 1018 1061 { … … 1035 1078 rc = VERR_WRONG_ORDER; 1036 1079 1080 LogFlowFuncLeaveRC(rc); 1081 return rc; 1082 } 1083 1084 int VBoxDnDWnd::OnGhSendDir(const char *pszFormats, uint32_t cbFormats, 1085 uint32_t uDefAction) 1086 { 1087 int rc = 0; 1088 LogFlowFuncLeaveRC(rc); 1089 return rc; 1090 } 1091 1092 int VBoxDnDWnd::OnGhSendFile(const char *pszFormats, uint32_t cbFormats, 1093 uint32_t uDefAction) 1094 { 1095 int rc = 0; 1037 1096 LogFlowFuncLeaveRC(rc); 1038 1097 return rc; -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h
r50265 r50305 155 155 public: 156 156 157 bool HasData(void) { return RT_BOOL(mFormatEtc.cfFormat != 0); }158 157 void *DataMutableRaw(void) { return mpvData; } 159 158 uint32_t DataSize(void) { return mcbData; } 159 RTCString Formats(void); 160 160 int WaitForDrop(RTMSINTERVAL msTimeout); 161 161 … … 170 170 * DVTARGETDEVICE here! */ 171 171 FORMATETC mFormatEtc; 172 RTCString mFormats; 172 173 void *mpvData; 173 174 uint32_t mcbData; … … 338 339 int OnGhIsDnDPending(uint32_t uScreenID); 339 340 int OnGhDropped(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction); 341 int OnGhSendDir(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction); 342 int OnGhSendFile(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction); 340 343 #endif 341 344 -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp
r50265 r50305 17 17 #include <windows.h> 18 18 #include <new> /* For bad_alloc. */ 19 #include <Shlobj.h> /* For DROPFILES and friends. */ 19 20 20 21 #include "VBoxTray.h" … … 107 108 reset(); 108 109 110 /** @todo At the moment we only support one DnD format at a time. */ 111 109 112 /* Try different formats. CF_HDROP is the most common one, so start 110 113 * with this. */ 111 /** @todo At the moment we only support TYMED_HGLOBAL. */112 114 FORMATETC fmtEtc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; 113 115 HRESULT hr = pDataObject->QueryGetData(&fmtEtc); 114 if (hr != S_OK) 116 if (hr == S_OK) 117 { 118 mFormats = "text/uri-list"; 119 } 120 else 115 121 { 116 122 LogFlowFunc(("CF_HDROP not supported, hr=%Rhrc\n", hr)); … … 125 131 fmtEtc.cfFormat = 0; /* Mark it to not supported. */ 126 132 } 133 else 134 { 135 mFormats = "text/plain;charset=utf-8"; 136 } 127 137 } 128 138 … … 130 140 if (fmtEtc.cfFormat) 131 141 { 132 LogFlowFunc(("Found supported format %RI16\n", fmtEtc.cfFormat)); 142 LogFlowFunc(("Found supported format %RI16 (%s)\n", 143 fmtEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(fmtEtc.cfFormat))); 133 144 134 145 /* Make a copy of the FORMATETC structure so that we later can 135 146 * use this for comparrison and stuff. */ 136 /** Note: The DVTARGETDEVICE member only is a shallow copy ! */147 /** Note: The DVTARGETDEVICE member only is a shallow copy for now! */ 137 148 memcpy(&mFormatEtc, &fmtEtc, sizeof(FORMATETC)); 138 149 … … 164 175 while (pEnumFormats->Next(1, &curFormatEtc, 165 176 NULL /* pceltFetched */) == S_OK) 166 177 { 167 178 WCHAR wszCfName[128]; /* 128 chars should be enough, rest will be truncated. */ 168 179 hr2 = GetClipboardFormatNameW(curFormatEtc.cfFormat, wszCfName, 169 180 sizeof(wszCfName) / sizeof(WCHAR)); 170 LogRel(("\tcfFormat=%RI16 , tyMed=%RI32, dwAspect=%RI32, strCustomName=%ls, hr=%Rhrc\n",181 LogRel(("\tcfFormat=%RI16 (%s), tyMed=%RI32, dwAspect=%RI32, strCustomName=%ls, hr=%Rhrc\n", 171 182 curFormatEtc.cfFormat, 183 VBoxDnDDataObject::ClipboardFormatToString(curFormatEtc.cfFormat), 172 184 curFormatEtc.tymed, 173 185 curFormatEtc.dwAspect, … … 176 188 177 189 pEnumFormats->Release(); 178 190 } 179 191 180 192 break; … … 236 248 237 249 #ifdef DEBUG 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)); 250 LogFlowFunc(("mFormatEtc.cfFormat=%RI16 (%s), pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld\n", 251 mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat), 252 pDataObject, grfKeyState, pt.x, pt.y)); 240 253 #endif 241 254 HRESULT hr = S_OK; … … 248 261 hr = pDataObject->QueryGetData(&mFormatEtc); 249 262 AssertMsg(SUCCEEDED(hr), 250 ("Data format changed between DragEnter() and Drop(), cfFormat=%RI16, hr=%Rhrc\n", 251 mFormatEtc.cfFormat, hr)); 252 } 263 ("Data format changed between DragEnter() and Drop(), cfFormat=%RI16 (%s), hr=%Rhrc\n", 264 mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat), 265 hr)); 266 } 267 268 int rc = VINF_SUCCESS; 253 269 254 270 if (SUCCEEDED(hr)) … … 272 288 LogFlowFunc(("Locking HGLOBAL storage failed with %Rrc\n", 273 289 RTErrConvertFromWin32(GetLastError()))); 274 hr = ERROR_INVALID_HANDLE; 290 rc = VERR_INVALID_HANDLE; 291 hr = E_INVALIDARG; /* Set special hr for OLE. */ 275 292 } 276 293 break; … … 279 296 AssertMsgFailed(("Storage medium type %RI32 supported\n", 280 297 mFormatEtc.tymed)); 281 hr = ERROR_NOT_SUPPORTED; 298 rc = VERR_NOT_SUPPORTED; 299 hr = DV_E_TYMED; /* Set special hr for OLE. */ 282 300 break; 283 301 } 284 302 285 if ( SUCCEEDED(hr))303 if (RT_SUCCESS(rc)) 286 304 { 287 305 /* Second stage: Do the actual copying of the data object's data, … … 289 307 switch (mFormatEtc.cfFormat) 290 308 { 309 /* Handling CF_TEXT means that the system already did some marshalling 310 * to convert RTF or unicode text to plain ANSI text. */ 291 311 case CF_TEXT: 292 312 { 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; 313 AssertPtr(pvData); 314 size_t cbSize = GlobalSize(pvData); 315 LogFlowFunc(("CF_TEXT 0x%p got %zu bytes\n", pvData, cbSize)); 316 if (cbSize) 317 { 318 char *pszText = NULL; 319 rc = RTStrCurrentCPToUtf8(&pszText, (char *)pvData); 320 if (RT_SUCCESS(rc)) 321 { 322 mpvData = (void *)pszText; 323 mcbData = strlen(pszText) + 1; 324 } 325 } 326 298 327 break; 299 328 } 300 329 301 330 case CF_HDROP: 331 { 332 AssertPtr(pvData); 333 334 /* Convert to a string list, separated by \r\n. */ 335 DROPFILES *pDropFiles = (DROPFILES *)pvData; 336 AssertPtr(pDropFiles); 337 bool fUnicode = RT_BOOL(pDropFiles->fWide); 338 339 /* Get the offset of the file list. */ 340 Assert(pDropFiles->pFiles >= sizeof(DROPFILES)); 341 /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only 342 * will work with the plain storage medium pointer! */ 343 HDROP hDrop = (HDROP)(pvData); 344 345 /* First, get the file count. */ 346 /** @todo Does this work on Windows 2000 / NT4? */ 347 char *pszFiles = NULL; 348 uint32_t cchFiles = 0; 349 UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */, 350 NULL /* lpszFile */, 0 /* cchFile */); 351 LogFlowFunc(("CF_HDROP got %RU16 file(s)\n", cFiles)); 352 353 for (UINT i = 0; i < cFiles; i++) 354 { 355 UINT cch = DragQueryFile(hDrop, i /* File index */, 356 NULL /* Query size first */, 357 0 /* cchFile */); 358 Assert(cch); 359 360 /* Add separation between filenames. */ 361 if (i > 0) 362 { 363 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, 364 "\r\n", 2 /* Bytes */); 365 if (RT_SUCCESS(rc)) 366 cchFiles += 2; /* Include \r\n */ 367 } 368 369 if (RT_FAILURE(rc)) 370 return rc; 371 372 char *pszFile = NULL; /* UTF-8 version. */ 373 UINT cchFile = 0; 374 if (fUnicode) 375 { 376 /* Allocate enough space (including terminator). */ 377 WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cch + 1) * sizeof(WCHAR)); 378 if (pwszFile) 379 { 380 cchFile = DragQueryFileW(hDrop, i /* File index */, 381 pwszFile, cch + 1 /* Include terminator */); 382 AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n", 383 cchFile, cch)); 384 int rc2 = RTUtf16ToUtf8(pwszFile, &pszFile); 385 AssertRC(rc2); 386 } 387 else 388 rc = VERR_NO_MEMORY; 389 } 390 else /* ANSI */ 391 { 392 /* Allocate enough space (including terminator). */ 393 pszFile = (char *)RTMemAlloc((cch + 1) * sizeof(char)); 394 if (pszFile) 395 { 396 cchFile = DragQueryFileA(hDrop, i /* File index */, 397 pszFile, cchFile + 1 /* Include terminator */); 398 AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n", 399 cchFile, cch)); 400 } 401 else 402 rc = VERR_NO_MEMORY; 403 } 404 405 if (RT_SUCCESS(rc)) 406 { 407 LogFlowFunc(("\tFile: %s (%RU32 characters)\n", 408 pszFile, cchFile)); 409 410 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, 411 pszFile, cchFile); 412 } 413 414 /* Termination. */ 415 pszFiles[cchFiles] = '\0'; 416 417 if (pszFile) 418 RTMemFree(pszFile); 419 420 if (RT_FAILURE(rc)) 421 break; 422 } 423 424 if (RT_SUCCESS(rc)) 425 { 426 uint32_t cbSize = cchFiles * sizeof(char); 427 Assert(cbSize); 428 429 mpvData = RTMemDup(pszFiles, cbSize); 430 mcbData = cbSize; 431 } 432 433 LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n", 434 rc, pszFiles, cFiles, cchFiles)); 435 436 if (pszFiles) 437 RTStrFree(pszFiles); 302 438 break; 439 } 303 440 304 441 default: 305 AssertMsgFailed(("Format of type %RI16 supported\n", 306 mFormatEtc.cfFormat)); 442 AssertMsgFailed(("Format of type %RI16 (%s) not supported\n", 443 mFormatEtc.cfFormat, 444 VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat))); 307 445 hr = ERROR_NOT_SUPPORTED; 446 hr = DV_E_CLIPFORMAT; /* Set special hr for OLE. */ 308 447 break; 309 448 } … … 320 459 321 460 default: 322 AssertMsgFailed(("Storage medium type %RI32 supported\n", 323 mFormatEtc.tymed)); 324 hr = ERROR_NOT_SUPPORTED; 461 AssertMsgFailed(("Really should not happen -- see init stage!\n")); 325 462 break; 326 463 } … … 329 466 ReleaseStgMedium(&stgMed); 330 467 331 if (SUCCEEDED(hr)) 468 /** @todo Signal in any case to avoid hangs/timeouts? */ 469 if (RT_SUCCESS(rc)) 332 470 { 333 471 RTSemEventSignal(hEventDrop); … … 349 487 mpWndParent->hide(); 350 488 351 LogFlowFunc(("Returning with mFormatEtc.cfFormat=%RI16, fCanDrop=%RTbool, *pdwEffect=%RI32\n", 352 mFormatEtc.cfFormat, fCanDrop, *pdwEffect)); 489 LogFlowFunc(("Returning with rc=%Rrc, mFormatEtc.cfFormat=%RI16 (%s), fCanDrop=%RTbool, *pdwEffect=%RI32\n", 490 rc, mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat), 491 fCanDrop, *pdwEffect)); 492 353 493 return hr; 354 494 } … … 395 535 mcbData = 0; 396 536 RT_ZERO(mFormatEtc); 537 mFormats = ""; 538 } 539 540 RTCString VBoxDnDDropTarget::Formats(void) 541 { 542 return mFormats; 397 543 } 398 544
Note:
See TracChangeset
for help on using the changeset viewer.