Changeset 78171 in vbox for trunk/src/VBox/Additions/WINNT
- Timestamp:
- Apr 17, 2019 4:03:40 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 130086
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
r78151 r78171 20 20 * Header Files * 21 21 *********************************************************************************************************************************/ 22 # 22 #define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD 23 23 #include "VBoxTray.h" 24 24 #include "VBoxHelpers.h" … … 69 69 case WM_CLIPBOARDUPDATE: 70 70 { 71 Log(("WM_CLIPBOARDUPDATE\n")); 72 73 if (GetClipboardOwner() != hwnd) 74 { 75 /* Clipboard was updated by another application. */ 76 uint32_t uFormats; 77 int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats); 78 if (RT_SUCCESS(vboxrc)) 79 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); 80 } 81 } break; 71 Log(("WM_CLIPBOARDUPDATE\n")); 72 73 if (GetClipboardOwner() != hwnd) 74 { 75 /* Clipboard was updated by another application. */ 76 uint32_t uFormats; 77 int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats); 78 if (RT_SUCCESS(vboxrc)) 79 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); 80 } 81 } 82 break; 82 83 83 84 case WM_CHANGECBCHAIN: 84 85 { 85 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 86 { 87 rc = DefWindowProc(hwnd, msg, wParam, lParam); 88 break; 89 } 90 91 HWND hWndRemoved = (HWND)wParam; 92 HWND hWndNext = (HWND)lParam; 93 94 LogFlowFunc(("WM_CHANGECBCHAIN: hWndRemoved=%p, hWndNext=%p, hWnd=%p\n", hWndRemoved, hWndNext, pWinCtx->hWnd)); 95 96 if (hWndRemoved == pWinCtx->hWndNextInChain) 97 { 98 /* The window that was next to our in the chain is being removed. 99 * Relink to the new next window. */ 100 pWinCtx->hWndNextInChain = hWndNext; 101 } 102 else 103 { 104 if (pWinCtx->hWndNextInChain) 105 { 106 /* Pass the message further. */ 107 DWORD_PTR dwResult; 108 rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, 109 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult); 110 if (!rc) 111 rc = (LRESULT) dwResult; 112 } 113 } 114 } break; 86 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 87 { 88 rc = DefWindowProc(hwnd, msg, wParam, lParam); 89 break; 90 } 91 92 HWND hWndRemoved = (HWND)wParam; 93 HWND hWndNext = (HWND)lParam; 94 95 LogFlowFunc(("WM_CHANGECBCHAIN: hWndRemoved=%p, hWndNext=%p, hWnd=%p\n", hWndRemoved, hWndNext, pWinCtx->hWnd)); 96 97 if (hWndRemoved == pWinCtx->hWndNextInChain) 98 { 99 /* The window that was next to our in the chain is being removed. 100 * Relink to the new next window. */ 101 pWinCtx->hWndNextInChain = hWndNext; 102 } 103 else 104 { 105 if (pWinCtx->hWndNextInChain) 106 { 107 /* Pass the message further. */ 108 DWORD_PTR dwResult; 109 rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, 110 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult); 111 if (!rc) 112 rc = (LRESULT)dwResult; 113 } 114 } 115 } 116 break; 115 117 116 118 case WM_DRAWCLIPBOARD: 117 119 { 118 LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd)); 119 120 if (GetClipboardOwner() != hwnd) 121 { 122 /* Clipboard was updated by another application. */ 123 /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */ 124 uint32_t uFormats; 125 int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats); 126 if (RT_SUCCESS(vboxrc)) 127 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); 128 } 129 130 if (pWinCtx->hWndNextInChain) 131 { 132 /* Pass the message to next windows in the clipboard chain. */ 133 SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL); 134 } 135 } break; 120 LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd)); 121 122 if (GetClipboardOwner() != hwnd) 123 { 124 /* Clipboard was updated by another application. */ 125 /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */ 126 uint32_t uFormats; 127 int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats); 128 if (RT_SUCCESS(vboxrc)) 129 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); 130 } 131 132 if (pWinCtx->hWndNextInChain) 133 { 134 /* Pass the message to next windows in the clipboard chain. */ 135 SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL); 136 } 137 } 138 break; 136 139 137 140 case WM_TIMER: 138 141 { 139 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 140 break; 141 142 HWND hViewer = GetClipboardViewer(); 143 144 /* Re-register ourselves in the clipboard chain if our last ping 145 * timed out or there seems to be no valid chain. */ 146 if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess) 147 { 148 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 149 VBoxClipboardWinAddToCBChain(pWinCtx); 150 } 151 152 /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be 153 * processed by ourselves to the chain. */ 154 pWinCtx->oldAPI.fCBChainPingInProcess = TRUE; 155 156 hViewer = GetClipboardViewer(); 157 if (hViewer) 158 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain, 159 VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx); 160 } break; 142 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 143 break; 144 145 HWND hViewer = GetClipboardViewer(); 146 147 /* Re-register ourselves in the clipboard chain if our last ping 148 * timed out or there seems to be no valid chain. */ 149 if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess) 150 { 151 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 152 VBoxClipboardWinAddToCBChain(pWinCtx); 153 } 154 155 /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be 156 * processed by ourselves to the chain. */ 157 pWinCtx->oldAPI.fCBChainPingInProcess = TRUE; 158 159 hViewer = GetClipboardViewer(); 160 if (hViewer) 161 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain, 162 VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx); 163 } 164 break; 161 165 162 166 case WM_CLOSE: 163 167 { 164 /* Do nothing. Ignore the message. */ 165 } break; 168 /* Do nothing. Ignore the message. */ 169 } 170 break; 166 171 167 172 case WM_RENDERFORMAT: 168 173 { 169 /* Insert the requested clipboard format data into the clipboard. */ 170 uint32_t u32Format = 0; 171 UINT format = (UINT)wParam; 172 173 LogFlowFunc(("WM_RENDERFORMAT, format = %x\n", format)); 174 switch (format) 175 { 176 case CF_UNICODETEXT: 177 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 178 break; 179 180 case CF_DIB: 181 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 182 break; 183 184 default: 185 if (format >= 0xC000) 186 { 187 TCHAR szFormatName[256]; 188 189 int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR)); 190 if (cActual) 191 { 192 if (strcmp (szFormatName, "HTML Format") == 0) 193 { 194 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML; 195 } 196 } 197 } 198 break; 199 } 200 201 if (u32Format == 0) 202 { 203 /* Unsupported clipboard format is requested. */ 204 LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format)); 205 VBoxClipboardWinClear(); 206 } 207 else 208 { 209 const uint32_t cbPrealloc = 4096; /** @todo r=andy Make it dynamic for supporting larger text buffers! */ 210 uint32_t cb = 0; 211 212 /* Preallocate a buffer, most of small text transfers will fit into it. */ 213 HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc); 214 LogFlowFunc(("Preallocated handle hMem = %p\n", hMem)); 215 216 if (hMem) 217 { 218 void *pMem = GlobalLock(hMem); 219 LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); 220 221 if (pMem) 222 { 223 /* Read the host data to the preallocated buffer. */ 224 int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cbPrealloc, &cb); 225 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n", vboxrc)); 226 227 if (RT_SUCCESS(vboxrc)) 228 { 229 if (cb == 0) 230 { 231 /* 0 bytes returned means the clipboard is empty. 232 * Deallocate the memory and set hMem to NULL to get to 233 * the clipboard empty code path. */ 234 GlobalUnlock(hMem); 235 GlobalFree(hMem); 236 hMem = NULL; 237 } 238 else if (cb > cbPrealloc) 239 { 240 GlobalUnlock(hMem); 241 242 /* The preallocated buffer is too small, adjust the size. */ 243 hMem = GlobalReAlloc(hMem, cb, 0); 244 LogFlowFunc(("Reallocated hMem = %p\n", hMem)); 245 246 if (hMem) 247 { 248 pMem = GlobalLock(hMem); 249 LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); 250 251 if (pMem) 252 { 253 /* Read the host data to the preallocated buffer. */ 254 uint32_t cbNew = 0; 255 vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cb, &cbNew); 256 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew)); 257 258 if (RT_SUCCESS (vboxrc) && cbNew <= cb) 259 { 260 cb = cbNew; 261 } 262 else 263 { 264 GlobalUnlock(hMem); 265 GlobalFree(hMem); 266 hMem = NULL; 267 } 268 } 269 else 270 { 271 GlobalFree(hMem); 272 hMem = NULL; 273 } 274 } 275 } 276 277 if (hMem) 278 { 279 /* pMem is the address of the data. cb is the size of returned data. */ 280 /* Verify the size of returned text, the memory block for clipboard 281 * must have the exact string size. 282 */ 283 if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 284 { 285 size_t cbActual = 0; 286 HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual); 287 if (FAILED (hrc)) 288 { 289 /* Discard invalid data. */ 290 GlobalUnlock(hMem); 291 GlobalFree(hMem); 292 hMem = NULL; 293 } 294 else 295 { 296 /* cbActual is the number of bytes, excluding those used 297 * for the terminating null character. 298 */ 299 cb = (uint32_t)(cbActual + 2); 300 } 301 } 302 } 303 304 if (hMem) 305 { 306 GlobalUnlock(hMem); 307 308 hMem = GlobalReAlloc(hMem, cb, 0); 309 LogFlowFunc(("Reallocated hMem = %p\n", hMem)); 310 311 if (hMem) 312 { 313 /* 'hMem' contains the host clipboard data. 314 * size is 'cb' and format is 'format'. */ 315 HANDLE hClip = SetClipboardData(format, hMem); 316 LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip)); 317 318 if (hClip) 319 { 320 /* The hMem ownership has gone to the system. Finish the processing. */ 321 break; 322 } 323 324 /* Cleanup follows. */ 325 } 326 } 327 } 328 if (hMem) 329 GlobalUnlock(hMem); 330 } 331 if (hMem) 332 GlobalFree(hMem); 333 } 334 335 /* Something went wrong. */ 336 VBoxClipboardWinClear(); 337 } 338 } break; 174 /* Insert the requested clipboard format data into the clipboard. */ 175 uint32_t u32Format = 0; 176 UINT format = (UINT)wParam; 177 178 LogFlowFunc(("WM_RENDERFORMAT, format = %x\n", format)); 179 switch (format) 180 { 181 case CF_UNICODETEXT: 182 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 183 break; 184 185 case CF_DIB: 186 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 187 break; 188 189 default: 190 if (format >= 0xC000) 191 { 192 TCHAR szFormatName[256]; 193 194 int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName) / sizeof(TCHAR)); 195 if (cActual) 196 { 197 if (strcmp(szFormatName, "HTML Format") == 0) 198 { 199 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML; 200 } 201 } 202 } 203 break; 204 } 205 206 if (u32Format == 0) 207 { 208 /* Unsupported clipboard format is requested. */ 209 LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format)); 210 VBoxClipboardWinClear(); 211 } 212 else 213 { 214 const uint32_t cbPrealloc = 4096; /** @todo r=andy Make it dynamic for supporting larger text buffers! */ 215 uint32_t cb = 0; 216 217 /* Preallocate a buffer, most of small text transfers will fit into it. */ 218 HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc); 219 LogFlowFunc(("Preallocated handle hMem = %p\n", hMem)); 220 221 if (hMem) 222 { 223 void *pMem = GlobalLock(hMem); 224 LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); 225 226 if (pMem) 227 { 228 /* Read the host data to the preallocated buffer. */ 229 int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cbPrealloc, &cb); 230 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n", vboxrc)); 231 232 if (RT_SUCCESS(vboxrc)) 233 { 234 if (cb == 0) 235 { 236 /* 0 bytes returned means the clipboard is empty. 237 * Deallocate the memory and set hMem to NULL to get to 238 * the clipboard empty code path. */ 239 GlobalUnlock(hMem); 240 GlobalFree(hMem); 241 hMem = NULL; 242 } 243 else if (cb > cbPrealloc) 244 { 245 GlobalUnlock(hMem); 246 247 /* The preallocated buffer is too small, adjust the size. */ 248 hMem = GlobalReAlloc(hMem, cb, 0); 249 LogFlowFunc(("Reallocated hMem = %p\n", hMem)); 250 251 if (hMem) 252 { 253 pMem = GlobalLock(hMem); 254 LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem))); 255 256 if (pMem) 257 { 258 /* Read the host data to the preallocated buffer. */ 259 uint32_t cbNew = 0; 260 vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cb, &cbNew); 261 LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew)); 262 263 if (RT_SUCCESS(vboxrc) && cbNew <= cb) 264 { 265 cb = cbNew; 266 } 267 else 268 { 269 GlobalUnlock(hMem); 270 GlobalFree(hMem); 271 hMem = NULL; 272 } 273 } 274 else 275 { 276 GlobalFree(hMem); 277 hMem = NULL; 278 } 279 } 280 } 281 282 if (hMem) 283 { 284 /* pMem is the address of the data. cb is the size of returned data. */ 285 /* Verify the size of returned text, the memory block for clipboard 286 * must have the exact string size. 287 */ 288 if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 289 { 290 size_t cbActual = 0; 291 HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual); 292 if (FAILED(hrc)) 293 { 294 /* Discard invalid data. */ 295 GlobalUnlock(hMem); 296 GlobalFree(hMem); 297 hMem = NULL; 298 } 299 else 300 { 301 /* cbActual is the number of bytes, excluding those used 302 * for the terminating null character. 303 */ 304 cb = (uint32_t)(cbActual + 2); 305 } 306 } 307 } 308 309 if (hMem) 310 { 311 GlobalUnlock(hMem); 312 313 hMem = GlobalReAlloc(hMem, cb, 0); 314 LogFlowFunc(("Reallocated hMem = %p\n", hMem)); 315 316 if (hMem) 317 { 318 /* 'hMem' contains the host clipboard data. 319 * size is 'cb' and format is 'format'. */ 320 HANDLE hClip = SetClipboardData(format, hMem); 321 LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip)); 322 323 if (hClip) 324 { 325 /* The hMem ownership has gone to the system. Finish the processing. */ 326 break; 327 } 328 329 /* Cleanup follows. */ 330 } 331 } 332 } 333 if (hMem) 334 GlobalUnlock(hMem); 335 } 336 if (hMem) 337 GlobalFree(hMem); 338 } 339 340 /* Something went wrong. */ 341 VBoxClipboardWinClear(); 342 } 343 } 344 break; 339 345 340 346 case WM_RENDERALLFORMATS: 341 347 { 342 /* Do nothing. The clipboard formats will be unavailable now, because the 343 * windows is to be destroyed and therefore the guest side becomes inactive. 344 */ 345 int vboxrc = VBoxClipboardWinOpen(hwnd); 346 if (RT_SUCCESS(vboxrc)) 347 { 348 VBoxClipboardWinClear(); 349 VBoxClipboardWinClose(); 350 } 351 } break; 348 /* Do nothing. The clipboard formats will be unavailable now, because the 349 * windows is to be destroyed and therefore the guest side becomes inactive. 350 */ 351 int vboxrc = VBoxClipboardWinOpen(hwnd); 352 if (RT_SUCCESS(vboxrc)) 353 { 354 VBoxClipboardWinClear(); 355 VBoxClipboardWinClose(); 356 } 357 } 358 break; 352 359 353 360 case VBOX_CLIPBOARD_WM_SET_FORMATS: 354 361 { 355 /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */ 356 uint32_t u32Formats = (uint32_t)lParam; 357 358 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: u32Formats=0x%x\n", u32Formats)); 359 360 int vboxrc = VBoxClipboardWinOpen(hwnd); 361 if (RT_SUCCESS(vboxrc)) 362 { 363 VBoxClipboardWinClear(); 364 365 HANDLE hClip = NULL; 366 367 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 368 hClip = SetClipboardData(CF_UNICODETEXT, NULL); 369 370 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 371 hClip = SetClipboardData(CF_DIB, NULL); 372 373 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 374 { 375 UINT format = RegisterClipboardFormat ("HTML Format"); 376 if (format != 0) 377 hClip = SetClipboardData(format, NULL); 378 } 379 380 VBoxClipboardWinClose(); 381 382 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError())); 383 } 384 } break; 362 /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */ 363 uint32_t u32Formats = (uint32_t)lParam; 364 365 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: u32Formats=0x%x\n", u32Formats)); 366 367 int vboxrc = VBoxClipboardWinOpen(hwnd); 368 if (RT_SUCCESS(vboxrc)) 369 { 370 VBoxClipboardWinClear(); 371 372 HANDLE hClip = NULL; 373 374 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 375 hClip = SetClipboardData(CF_UNICODETEXT, NULL); 376 377 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 378 hClip = SetClipboardData(CF_DIB, NULL); 379 380 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 381 { 382 UINT format = RegisterClipboardFormat("HTML Format"); 383 if (format != 0) 384 hClip = SetClipboardData(format, NULL); 385 } 386 387 VBoxClipboardWinClose(); 388 389 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError())); 390 } 391 } 392 break; 385 393 386 394 case VBOX_CLIPBOARD_WM_READ_DATA: 387 395 { 388 /* Send data in the specified format to the host. */ 389 uint32_t u32Formats = (uint32_t)lParam; 390 HANDLE hClip = NULL; 391 392 LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats)); 393 394 int vboxrc = VBoxClipboardWinOpen(hwnd); 395 if (RT_SUCCESS(vboxrc)) 396 { 397 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 398 { 399 hClip = GetClipboardData(CF_DIB); 400 401 if (hClip != NULL) 402 { 403 LPVOID lp = GlobalLock(hClip); 404 if (lp != NULL) 405 { 406 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, 407 lp, GlobalSize(hClip)); 408 GlobalUnlock(hClip); 409 } 410 else 411 { 412 hClip = NULL; 413 } 414 } 415 } 416 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 417 { 418 hClip = GetClipboardData(CF_UNICODETEXT); 419 420 if (hClip != NULL) 421 { 422 LPWSTR uniString = (LPWSTR)GlobalLock(hClip); 423 424 if (uniString != NULL) 425 { 426 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, 427 uniString, (lstrlenW(uniString) + 1) * 2); 428 GlobalUnlock(hClip); 429 } 430 else 431 { 432 hClip = NULL; 433 } 434 } 435 } 436 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 437 { 438 UINT format = RegisterClipboardFormat ("HTML Format"); 439 if (format != 0) 440 { 441 hClip = GetClipboardData(format); 442 if (hClip != NULL) 443 { 444 LPVOID lp = GlobalLock(hClip); 445 446 if (lp != NULL) 447 { 448 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML, 449 lp, GlobalSize(hClip)); 450 GlobalUnlock(hClip); 451 } 452 else 453 { 454 hClip = NULL; 455 } 456 } 457 } 458 } 459 460 VBoxClipboardWinClose(); 461 } 462 463 if (hClip == NULL) 464 { 465 /* Requested clipboard format is not available, send empty data. */ 466 VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0); 467 } 468 } break; 396 /* Send data in the specified format to the host. */ 397 uint32_t u32Formats = (uint32_t)lParam; 398 HANDLE hClip = NULL; 399 400 LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats)); 401 402 int vboxrc = VBoxClipboardWinOpen(hwnd); 403 if (RT_SUCCESS(vboxrc)) 404 { 405 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 406 { 407 hClip = GetClipboardData(CF_DIB); 408 409 if (hClip != NULL) 410 { 411 LPVOID lp = GlobalLock(hClip); 412 if (lp != NULL) 413 { 414 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, 415 lp, GlobalSize(hClip)); 416 GlobalUnlock(hClip); 417 } 418 else 419 { 420 hClip = NULL; 421 } 422 } 423 } 424 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 425 { 426 hClip = GetClipboardData(CF_UNICODETEXT); 427 428 if (hClip != NULL) 429 { 430 LPWSTR uniString = (LPWSTR)GlobalLock(hClip); 431 432 if (uniString != NULL) 433 { 434 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, 435 uniString, (lstrlenW(uniString) + 1) * 2); 436 GlobalUnlock(hClip); 437 } 438 else 439 { 440 hClip = NULL; 441 } 442 } 443 } 444 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 445 { 446 UINT format = RegisterClipboardFormat("HTML Format"); 447 if (format != 0) 448 { 449 hClip = GetClipboardData(format); 450 if (hClip != NULL) 451 { 452 LPVOID lp = GlobalLock(hClip); 453 454 if (lp != NULL) 455 { 456 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML, 457 lp, GlobalSize(hClip)); 458 GlobalUnlock(hClip); 459 } 460 else 461 { 462 hClip = NULL; 463 } 464 } 465 } 466 } 467 468 VBoxClipboardWinClose(); 469 } 470 471 if (hClip == NULL) 472 { 473 /* Requested clipboard format is not available, send empty data. */ 474 VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0); 475 } 476 } 477 break; 469 478 470 479 case WM_DESTROY: 471 480 { 472 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 473 if (pWinCtx->oldAPI.timerRefresh) 474 KillTimer(pWinCtx->hWnd, 0); 475 /* 476 * don't need to call PostQuitMessage cause 477 * the VBoxTray already finished a message loop 478 */ 479 } break; 481 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 482 if (pWinCtx->oldAPI.timerRefresh) 483 KillTimer(pWinCtx->hWnd, 0); 484 /* 485 * don't need to call PostQuitMessage cause 486 * the VBoxTray already finished a message loop 487 */ 488 } 489 break; 480 490 481 491 default: 482 492 { 483 rc = DefWindowProc(hwnd, msg, wParam, lParam); 484 } 493 rc = DefWindowProc(hwnd, msg, wParam, lParam); 494 } 495 break; 485 496 } 486 497 … … 660 671 switch (u32Msg) 661 672 { 662 case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: 663 { 664 /* The host has announced available clipboard formats. 665 * Forward the information to the window, so it can later 666 * respond to WM_RENDERFORMAT message. */ 667 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_SET_FORMATS, 0, u32Formats); 668 } break; 669 670 case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: 671 { 672 /* The host needs data in the specified format. */ 673 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_READ_DATA, 0, u32Formats); 674 } break; 675 676 case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT: 677 { 678 /* The host is terminating. */ 679 LogRel(("Clipboard: Terminating ...\n")); 680 ASMAtomicXchgBool(pfShutdown, true); 681 } break; 682 683 default: 684 { 685 LogFlowFunc(("Unsupported message from host, message=%RU32\n", u32Msg)); 686 687 /* Wait a bit before retrying. */ 688 RTThreadSleep(1000); 689 } break; 673 case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: 674 { 675 /* The host has announced available clipboard formats. 676 * Forward the information to the window, so it can later 677 * respond to WM_RENDERFORMAT message. */ 678 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_SET_FORMATS, 0, u32Formats); 679 } 680 break; 681 682 case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: 683 { 684 /* The host needs data in the specified format. */ 685 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_READ_DATA, 0, u32Formats); 686 } 687 break; 688 689 case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT: 690 { 691 /* The host is terminating. */ 692 LogRel(("Clipboard: Terminating ...\n")); 693 ASMAtomicXchgBool(pfShutdown, true); 694 } 695 break; 696 697 default: 698 { 699 LogFlowFunc(("Unsupported message from host, message=%RU32\n", u32Msg)); 700 701 /* Wait a bit before retrying. */ 702 RTThreadSleep(1000); 703 } 704 break; 690 705 } 691 706 }
Note:
See TracChangeset
for help on using the changeset viewer.