Changeset 58604 in vbox
- Timestamp:
- Nov 6, 2015 12:59:50 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 103972
- Location:
- trunk/src/VBox
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
r58144 r58604 20 20 21 21 #include <iprt/asm.h> 22 #include <iprt/ldr.h> 22 23 23 24 #include <VBox/HostServices/VBoxClipboardSvc.h> … … 31 32 #include <VBox/log.h> 32 33 33 34 /* Dynamically load clipboard functions from User32.dll. */ 35 typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND); 36 typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER; 37 38 typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND); 39 typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER; 40 41 #ifndef WM_CLIPBOARDUPDATE 42 #define WM_CLIPBOARDUPDATE 0x031D 43 #endif 34 44 35 45 typedef struct _VBOXCLIPBOARDCONTEXT … … 42 52 UINT timerRefresh; 43 53 bool fCBChainPingInProcess; 54 PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener; 55 PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener; 44 56 } VBOXCLIPBOARDCONTEXT, *PVBOXCLIPBOARDCONTEXT; 45 57 … … 50 62 51 63 enum { CBCHAIN_TIMEOUT = 5000 /* ms */ }; 64 65 static void vboxClipboardInitNewAPI(VBOXCLIPBOARDCONTEXT *pCtx) 66 { 67 RTLDRMOD hUser32 = NIL_RTLDRMOD; 68 int rc = RTLdrLoadSystem("User32.dll", /* fNoUnload = */ true, &hUser32); 69 if (RT_SUCCESS(rc)) 70 { 71 rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void**)&pCtx->pfnAddClipboardFormatListener); 72 if (RT_SUCCESS(rc)) 73 { 74 rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void**)&pCtx->pfnRemoveClipboardFormatListener); 75 } 76 77 RTLdrClose(hUser32); 78 } 79 80 if (RT_SUCCESS(rc)) 81 { 82 Log(("New Clipboard API is enabled\n")); 83 } 84 else 85 { 86 pCtx->pfnAddClipboardFormatListener = NULL; 87 pCtx->pfnRemoveClipboardFormatListener = NULL; 88 Log(("New Clipboard API is not available. rc = %Rrc\n", rc)); 89 } 90 } 91 92 static bool vboxClipboardIsNewAPI(VBOXCLIPBOARDCONTEXT *pCtx) 93 { 94 return pCtx->pfnAddClipboardFormatListener != NULL; 95 } 52 96 53 97 static int vboxClipboardChanged(PVBOXCLIPBOARDCONTEXT pCtx) … … 111 155 { 112 156 AssertPtrReturnVoid(pCtx); 113 pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd); 157 if (vboxClipboardIsNewAPI(pCtx)) 158 pCtx->pfnAddClipboardFormatListener(pCtx->hwnd); 159 else 160 pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd); 114 161 /** @todo r=andy Return code?? */ 115 162 } … … 120 167 AssertPtrReturnVoid(pCtx); 121 168 122 ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain); 123 pCtx->hwndNextInChain = NULL; 169 if (vboxClipboardIsNewAPI(pCtx)) 170 { 171 pCtx->pfnRemoveClipboardFormatListener(pCtx->hwnd); 172 } 173 else 174 { 175 ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain); 176 pCtx->hwndNextInChain = NULL; 177 } 124 178 /** @todo r=andy Return code?? */ 125 179 } … … 150 204 switch (msg) 151 205 { 206 case WM_CLIPBOARDUPDATE: 207 { 208 Log(("WM_CLIPBOARDUPDATE\n")); 209 210 if (GetClipboardOwner() != hwnd) 211 { 212 /* Clipboard was updated by another application. */ 213 vboxClipboardChanged(pCtx); 214 } 215 } break; 216 152 217 case WM_CHANGECBCHAIN: 153 218 { 219 if (vboxClipboardIsNewAPI(pCtx)) 220 { 221 rc = DefWindowProc(hwnd, msg, wParam, lParam); 222 break; 223 } 224 154 225 HWND hwndRemoved = (HWND)wParam; 155 226 HWND hwndNext = (HWND)lParam; … … 180 251 LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pCtx->hwnd)); 181 252 182 if (GetClipboardOwner 253 if (GetClipboardOwner() != hwnd) 183 254 { 184 255 /* Clipboard was updated by another application. */ … … 189 260 } 190 261 191 /* Pass the message to next windows in the clipboard chain. */ 192 SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, NULL); 262 if (pCtx->hwndNextInChain) 263 { 264 /* Pass the message to next windows in the clipboard chain. */ 265 SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, NULL); 266 } 193 267 } break; 194 268 195 269 case WM_TIMER: 196 270 { 271 if (vboxClipboardIsNewAPI(pCtx)) 272 break; 273 197 274 HWND hViewer = GetClipboardViewer(); 198 275 … … 209 286 hViewer = GetClipboardViewer(); 210 287 if (hViewer) 211 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR) 288 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR)pCtx); 212 289 } break; 213 290 … … 591 668 592 669 vboxClipboardAddToCBChain(pCtx); 593 pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL); 670 if (!vboxClipboardIsNewAPI(pCtx)) 671 pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL); 594 672 } 595 673 } … … 651 729 RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT)); 652 730 pCtx->pEnv = pEnv; 731 732 /* Check that new Clipboard API is available */ 733 vboxClipboardInitNewAPI(pCtx); 653 734 654 735 int rc = VbglR3ClipboardConnect(&pCtx->u32ClientID); … … 798 879 VBoxClipboardDestroy 799 880 }; 800 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp
r44528 r58604 4 4 5 5 /* 6 * Copyright (C) 2006-201 1Oracle Corporation6 * Copyright (C) 2006-2015 Oracle Corporation 7 7 * 8 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 24 24 #include <iprt/assert.h> 25 25 #include <iprt/thread.h> 26 #include <iprt/ldr.h> 26 27 #include <process.h> 27 28 … … 33 34 34 35 enum { CBCHAIN_TIMEOUT = 5000 /* ms */ }; 36 37 /* Dynamically load clipboard functions from User32.dll. */ 38 typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND); 39 typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER; 40 41 typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND); 42 typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER; 43 44 #ifndef WM_CLIPBOARDUPDATE 45 #define WM_CLIPBOARDUPDATE 0x031D 46 #endif 35 47 36 48 struct _VBOXCLIPBOARDCONTEXT … … 49 61 50 62 VBOXCLIPBOARDCLIENTDATA *pClient; 63 64 PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener; 65 PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener; 66 51 67 }; 52 68 … … 95 111 #endif /* LOG_ENABLED */ 96 112 113 static void vboxClipboardInitNewAPI(VBOXCLIPBOARDCONTEXT *pCtx) 114 { 115 RTLDRMOD hUser32 = NIL_RTLDRMOD; 116 int rc = RTLdrLoadSystem("User32.dll", /* fNoUnload = */ true, &hUser32); 117 if (RT_SUCCESS(rc)) 118 { 119 rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void**)&pCtx->pfnAddClipboardFormatListener); 120 if (RT_SUCCESS(rc)) 121 { 122 rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void**)&pCtx->pfnRemoveClipboardFormatListener); 123 } 124 125 RTLdrClose(hUser32); 126 } 127 128 if (RT_SUCCESS(rc)) 129 { 130 Log(("New Clipboard API is enabled\n")); 131 } 132 else 133 { 134 pCtx->pfnAddClipboardFormatListener = NULL; 135 pCtx->pfnRemoveClipboardFormatListener = NULL; 136 Log(("New Clipboard API is not available. rc = %Rrc\n", rc)); 137 } 138 } 139 140 static bool vboxClipboardIsNewAPI(VBOXCLIPBOARDCONTEXT *pCtx) 141 { 142 return pCtx->pfnAddClipboardFormatListener != NULL; 143 } 144 97 145 static void vboxClipboardGetData (uint32_t u32Format, const void *pvSrc, uint32_t cbSrc, 98 146 void *pvDst, uint32_t cbDst, uint32_t *pcbActualDst) … … 120 168 { 121 169 Assert(pCtx->pClient); 170 Assert(pCtx->hRenderEvent); 122 171 Assert(pCtx->pClient->data.pv == NULL && pCtx->pClient->data.cb == 0 && pCtx->pClient->data.u32Format == 0); 123 172 … … 128 177 vboxSvcClipboardReportMsg (pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, u32Format); 129 178 130 WaitForSingleObject(pCtx->hRenderEvent, INFINITE);131 132 LogFlow(("vboxClipboardReadDataFromClient wait completed\n"));179 DWORD ret = WaitForSingleObject(pCtx->hRenderEvent, INFINITE); 180 LogFlow(("vboxClipboardReadDataFromClient wait completed, ret 0x%08X, err %d\n", 181 ret, GetLastError())); NOREF(ret); 133 182 134 183 return VINF_SUCCESS; … … 196 245 static void addToCBChain (VBOXCLIPBOARDCONTEXT *pCtx) 197 246 { 198 pCtx->hwndNextInChain = SetClipboardViewer (pCtx->hwnd); 247 if (vboxClipboardIsNewAPI(pCtx)) 248 pCtx->pfnAddClipboardFormatListener(pCtx->hwnd); 249 else 250 pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd); 199 251 } 200 252 … … 202 254 static void removeFromCBChain (VBOXCLIPBOARDCONTEXT *pCtx) 203 255 { 204 ChangeClipboardChain (pCtx->hwnd, pCtx->hwndNextInChain); 205 pCtx->hwndNextInChain = NULL; 256 if (vboxClipboardIsNewAPI(pCtx)) 257 { 258 pCtx->pfnRemoveClipboardFormatListener(pCtx->hwnd); 259 } 260 else 261 { 262 ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain); 263 pCtx->hwndNextInChain = NULL; 264 } 206 265 } 207 266 … … 227 286 switch (msg) 228 287 { 288 case WM_CLIPBOARDUPDATE: 289 { 290 Log(("WM_CLIPBOARDUPDATE\n")); 291 292 if (GetClipboardOwner() != hwnd) 293 { 294 /* Clipboard was updated by another application. */ 295 vboxClipboardChanged(pCtx); 296 } 297 } break; 298 229 299 case WM_CHANGECBCHAIN: 230 300 { 231 301 Log(("WM_CHANGECBCHAIN\n")); 302 303 if (vboxClipboardIsNewAPI(pCtx)) 304 { 305 rc = DefWindowProc(hwnd, msg, wParam, lParam); 306 break; 307 } 232 308 233 309 HWND hwndRemoved = (HWND)wParam; … … 256 332 case WM_DRAWCLIPBOARD: 257 333 { 258 Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->hwndNextInChain));334 Log(("WM_DRAWCLIPBOARD\n")); 259 335 260 336 if (GetClipboardOwner () != hwnd) … … 266 342 if (pCtx->hwndNextInChain) 267 343 { 344 Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->hwndNextInChain)); 268 345 /* Pass the message to next windows in the clipboard chain. */ 269 346 DWORD_PTR dwResult; … … 276 353 case WM_TIMER: 277 354 { 355 if (vboxClipboardIsNewAPI(pCtx)) 356 break; 357 278 358 HWND hViewer = GetClipboardViewer(); 279 359 … … 292 372 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, CBChainPingProc, (ULONG_PTR) pCtx); 293 373 } break; 294 295 case WM_CLOSE: 296 { 297 /* Do nothing. Ignore the message. */ 298 } break; 299 374 300 375 case WM_RENDERFORMAT: 301 376 { … … 344 419 { 345 420 int vboxrc = vboxClipboardReadDataFromClient (pCtx, u32Format); 346 347 dprintf(("vboxClipboardReadDataFromClient vboxrc = %d\n", vboxrc)); 421 422 dprintf(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n", 423 vboxrc, pCtx->pClient->data.pv, pCtx->pClient->data.cb, pCtx->pClient->data.u32Format)); 348 424 349 425 if ( RT_SUCCESS (vboxrc) … … 430 506 * because host clipboard has more priority. 431 507 */ 508 Log(("WM_USER ignored\n")); 432 509 break; 433 510 } … … 480 557 } break; 481 558 559 case WM_CLOSE: 560 { 561 /* Do nothing. Ignore the message. */ 562 } break; 563 482 564 default: 483 565 { 484 566 Log(("WM_ %p\n", msg)); 485 rc = DefWindowProc 567 rc = DefWindowProc(hwnd, msg, wParam, lParam); 486 568 } 487 569 } … … 500 582 VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx; 501 583 502 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle 584 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); 503 585 504 586 /* Register the Window Class. */ 505 587 WNDCLASS wc; 588 RT_ZERO(wc); 506 589 507 590 wc.style = CS_NOCLOSE; 508 591 wc.lpfnWndProc = vboxClipboardWndProc; 509 wc.cbClsExtra = 0;510 wc.cbWndExtra = 0;511 592 wc.hInstance = hInstance; 512 wc.hIcon = NULL;513 wc.hCursor = NULL;514 593 wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); 515 wc.lpszMenuName = NULL;516 594 wc.lpszClassName = gachWindowClassName; 517 595 518 ATOM atomWindowClass = RegisterClass 596 ATOM atomWindowClass = RegisterClass(&wc); 519 597 520 598 if (atomWindowClass == 0) … … 542 620 543 621 addToCBChain(pCtx); 544 pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL); 622 if (!vboxClipboardIsNewAPI(pCtx)) 623 pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL); 545 624 546 625 MSG msg; … … 578 657 { 579 658 int rc = VINF_SUCCESS; 659 660 RT_ZERO(g_ctx); 661 662 /* Check that new Clipboard API is available */ 663 vboxClipboardInitNewAPI(&g_ctx); 580 664 581 665 g_ctx.hRenderEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
Note:
See TracChangeset
for help on using the changeset viewer.