Changeset 78151 in vbox for trunk/src/VBox/Additions/WINNT
- Timestamp:
- Apr 17, 2019 12:03:42 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 130066
- Location:
- trunk/src/VBox/Additions/WINNT/VBoxTray
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk
r76553 r78151 37 37 VBoxDispIf.cpp \ 38 38 VBoxSeamless.cpp \ 39 VBoxClipboard.cpp \40 39 VBoxDisplay.cpp \ 41 40 VBoxVRDP.cpp \ … … 46 45 VBoxTray_VBOX_IMPORT_CHECKER.win.x86 = nt4 #nt350 47 46 VBoxTray_VBOX_IMPORT_CHECKER.win.amd64 = xp64 47 ifdef VBOX_WITH_SHARED_CLIPBOARD 48 VBoxTray_DEFS += \ 49 VBOX_WITH_SHARED_CLIPBOARD 50 VBoxTray_SOURCES += \ 51 VBoxClipboard.cpp \ 52 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp 53 endif 48 54 ifdef VBOX_WITH_DRAG_AND_DROP 49 55 VBoxTray_DEFS += \ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
r78142 r78151 27 27 #include <iprt/ldr.h> 28 28 29 #include <VBox/HostServices/VBoxClipboardSvc.h> 29 #include <VBox/GuestHost/SharedClipboard.h> 30 #include <VBox/GuestHost/SharedClipboard-win.h> 30 31 #include <strsafe.h> 31 32 … … 36 37 * Structures and Typedefs * 37 38 *********************************************************************************************************************************/ 38 /* Dynamically load clipboard functions from User32.dll. */ 39 typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND); 40 typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER; 41 42 typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND); 43 typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER; 44 45 #ifndef WM_CLIPBOARDUPDATE 46 #define WM_CLIPBOARDUPDATE 0x031D 47 #endif 48 49 /** Sets announced clipboard formats from the host. */ 50 #define VBOX_WM_SHCLPB_SET_FORMATS WM_USER 51 /** Reads data from the clipboard and sends it to the host. */ 52 #define VBOX_WM_SHCLPB_READ_DATA WM_USER + 1 53 54 typedef struct _VBOXCLIPBOARDCONTEXT 55 { 56 const VBOXSERVICEENV *pEnv; 57 uint32_t u32ClientID; 58 ATOM wndClass; 59 HWND hwnd; 60 HWND hwndNextInChain; 61 UINT timerRefresh; 62 bool fCBChainPingInProcess; 63 PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener; 64 PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener; 65 } VBOXCLIPBOARDCONTEXT, *PVBOXCLIPBOARDCONTEXT; 66 67 enum { CBCHAIN_TIMEOUT = 5000 /* ms */ }; 68 39 40 struct _VBOXCLIPBOARDCONTEXT 41 { 42 /** Pointer to the VBoxClient service environment. */ 43 const VBOXSERVICEENV *pEnv; 44 /** Client ID the service is connected to the HGCM service with. */ 45 uint32_t u32ClientID; 46 /** Windows-specific context data. */ 47 VBOXCLIPBOARDWINCTX Win; 48 }; 69 49 70 50 /********************************************************************************************************************************* 71 * Header Files*51 * Static variables * 72 52 *********************************************************************************************************************************/ 73 /** Static since it is the single instance. Directly used in the windows proc. */53 /** Static clipboard context (since it is the single instance). Directly used in the windows proc. */ 74 54 static VBOXCLIPBOARDCONTEXT g_Ctx = { NULL }; 75 76 static char s_szClipWndClassName[] = "VBoxSharedClipboardClass"; 77 78 79 static void vboxClipboardInitNewAPI(VBOXCLIPBOARDCONTEXT *pCtx) 80 { 81 RTLDRMOD hUser32 = NIL_RTLDRMOD; 82 int rc = RTLdrLoadSystem("User32.dll", /* fNoUnload = */ true, &hUser32); 83 if (RT_SUCCESS(rc)) 84 { 85 rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void**)&pCtx->pfnAddClipboardFormatListener); 86 if (RT_SUCCESS(rc)) 87 { 88 rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void**)&pCtx->pfnRemoveClipboardFormatListener); 89 } 90 91 RTLdrClose(hUser32); 92 } 93 94 if (RT_SUCCESS(rc)) 95 { 96 Log(("New Clipboard API is enabled\n")); 97 } 98 else 99 { 100 pCtx->pfnAddClipboardFormatListener = NULL; 101 pCtx->pfnRemoveClipboardFormatListener = NULL; 102 Log(("New Clipboard API is not available. rc = %Rrc\n", rc)); 103 } 104 } 105 106 static bool vboxClipboardIsNewAPI(VBOXCLIPBOARDCONTEXT *pCtx) 107 { 108 return pCtx->pfnAddClipboardFormatListener != NULL; 109 } 110 111 112 static int vboxOpenClipboard(HWND hWnd) 113 { 114 /* "OpenClipboard fails if another window has the clipboard open." 115 * So try a few times and wait up to 1 second. 116 */ 117 BOOL fOpened = FALSE; 118 119 LogFlowFunc(("hWnd=%p\n", hWnd)); 120 121 int i = 0; 122 for (;;) 123 { 124 if (OpenClipboard(hWnd)) 125 { 126 fOpened = TRUE; 127 break; 128 } 129 130 if (i >= 10) /* sleep interval = [1..512] ms */ 131 break; 132 133 RTThreadSleep(1 << i); 134 ++i; 135 } 136 137 #ifdef LOG_ENABLED 138 if (i > 0) 139 LogFlowFunc(("%d times tried to open clipboard\n", i + 1)); 140 #endif 141 142 int rc; 143 if (fOpened) 144 rc = VINF_SUCCESS; 145 else 146 { 147 const DWORD dwLastErr = GetLastError(); 148 rc = RTErrConvertFromWin32(dwLastErr); 149 LogRel(("Clipboard: Failed to open clipboard! Error=%ld (%Rrc)\n", dwLastErr, rc)); 150 } 151 152 return rc; 153 } 154 155 156 static int vboxClipboardChanged(PVBOXCLIPBOARDCONTEXT pCtx) 55 /** Static window class name. */ 56 static char s_szClipWndClassName[] = VBOX_CLIPBOARD_WNDCLASS_NAME; 57 58 59 static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 157 60 { 158 61 AssertPtr(pCtx); 159 62 160 /* Query list of available formats and report to host. */ 161 int rc = vboxOpenClipboard(pCtx->hwnd); 162 if (RT_SUCCESS(rc)) 163 { 164 uint32_t u32Formats = 0; 165 UINT format = 0; 166 167 while ((format = EnumClipboardFormats(format)) != 0) 168 { 169 LogFlowFunc(("vboxClipboardChanged: format = 0x%08X\n", format)); 170 switch (format) 171 { 172 case CF_UNICODETEXT: 173 case CF_TEXT: 174 u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT; 175 break; 176 177 case CF_DIB: 178 case CF_BITMAP: 179 u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP; 180 break; 181 182 default: 183 { 184 if (format >= 0xC000) 185 { 186 TCHAR szFormatName[256]; 187 188 int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR)); 189 if (cActual) 190 { 191 if (strcmp (szFormatName, "HTML Format") == 0) 192 { 193 u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_HTML; 194 } 195 } 196 } 197 break; 198 } 199 } 200 } 201 202 CloseClipboard(); 203 rc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, u32Formats); 204 } 205 return rc; 206 } 207 208 /* Add ourselves into the chain of cliboard listeners */ 209 static void vboxClipboardAddToCBChain(PVBOXCLIPBOARDCONTEXT pCtx) 210 { 211 AssertPtrReturnVoid(pCtx); 212 if (vboxClipboardIsNewAPI(pCtx)) 213 pCtx->pfnAddClipboardFormatListener(pCtx->hwnd); 214 else 215 pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd); 216 /** @todo r=andy Return code?? */ 217 } 218 219 /* Remove ourselves from the chain of cliboard listeners */ 220 static void vboxClipboardRemoveFromCBChain(PVBOXCLIPBOARDCONTEXT pCtx) 221 { 222 AssertPtrReturnVoid(pCtx); 223 224 if (vboxClipboardIsNewAPI(pCtx)) 225 { 226 pCtx->pfnRemoveClipboardFormatListener(pCtx->hwnd); 227 } 228 else 229 { 230 ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain); 231 pCtx->hwndNextInChain = NULL; 232 } 233 /** @todo r=andy Return code?? */ 234 } 235 236 /* Callback which is invoked when we have successfully pinged ourselves down the 237 * clipboard chain. We simply unset a boolean flag to say that we are responding. 238 * There is a race if a ping returns after the next one is initiated, but nothing 239 * very bad is likely to happen. */ 240 VOID CALLBACK vboxClipboardChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult) 241 { 242 NOREF(hWnd); 243 NOREF(uMsg); 244 NOREF(lResult); 245 246 /** @todo r=andy Why not using SetWindowLongPtr for keeping the context? */ 247 PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)dwData; 248 AssertPtr(pCtx); 249 250 pCtx->fCBChainPingInProcess = FALSE; 251 } 252 253 static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 254 { 255 AssertPtr(pCtx); 63 const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win; 256 64 257 65 LRESULT rc = 0; … … 266 74 { 267 75 /* Clipboard was updated by another application. */ 268 vboxClipboardChanged(pCtx); 76 uint32_t uFormats; 77 int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats); 78 if (RT_SUCCESS(vboxrc)) 79 vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats); 269 80 } 270 81 } break; … … 272 83 case WM_CHANGECBCHAIN: 273 84 { 274 if ( vboxClipboardIsNewAPI(pCtx))85 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 275 86 { 276 87 rc = DefWindowProc(hwnd, msg, wParam, lParam); … … 278 89 } 279 90 280 HWND h wndRemoved = (HWND)wParam;281 HWND h wndNext = (HWND)lParam;282 283 LogFlowFunc(("WM_CHANGECBCHAIN: h wndRemoved %p, hwndNext %p, hwnd %p\n", hwndRemoved, hwndNext, pCtx->hwnd));284 285 if (h wndRemoved == pCtx->hwndNextInChain)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) 286 97 { 287 98 /* The window that was next to our in the chain is being removed. 288 99 * Relink to the new next window. */ 289 p Ctx->hwndNextInChain = hwndNext;100 pWinCtx->hWndNextInChain = hWndNext; 290 101 } 291 102 else 292 103 { 293 if (p Ctx->hwndNextInChain)104 if (pWinCtx->hWndNextInChain) 294 105 { 295 106 /* Pass the message further. */ 296 107 DWORD_PTR dwResult; 297 rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult); 108 rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, 109 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult); 298 110 if (!rc) 299 111 rc = (LRESULT) dwResult; … … 304 116 case WM_DRAWCLIPBOARD: 305 117 { 306 LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", p Ctx->hwnd));118 LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd)); 307 119 308 120 if (GetClipboardOwner() != hwnd) … … 310 122 /* Clipboard was updated by another application. */ 311 123 /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */ 312 int vboxrc = vboxClipboardChanged(pCtx); 313 if (RT_FAILURE(vboxrc)) 314 LogFlowFunc(("vboxClipboardChanged failed, rc = %Rrc\n", vboxrc)); 315 } 316 317 if (pCtx->hwndNextInChain) 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) 318 131 { 319 132 /* Pass the message to next windows in the clipboard chain. */ 320 SendMessageTimeout(p Ctx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, NULL);133 SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL); 321 134 } 322 135 } break; … … 324 137 case WM_TIMER: 325 138 { 326 if ( vboxClipboardIsNewAPI(pCtx))139 if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 327 140 break; 328 141 … … 331 144 /* Re-register ourselves in the clipboard chain if our last ping 332 145 * timed out or there seems to be no valid chain. */ 333 if (!hViewer || pCtx->fCBChainPingInProcess) 334 { 335 vboxClipboardRemoveFromCBChain(pCtx); 336 vboxClipboardAddToCBChain(pCtx); 337 } 146 if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess) 147 { 148 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 149 VBoxClipboardWinAddToCBChain(pWinCtx); 150 } 151 338 152 /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be 339 153 * processed by ourselves to the chain. */ 340 pCtx->fCBChainPingInProcess = TRUE; 154 pWinCtx->oldAPI.fCBChainPingInProcess = TRUE; 155 341 156 hViewer = GetClipboardViewer(); 342 157 if (hViewer) 343 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR)pCtx); 158 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain, 159 VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx); 344 160 } break; 345 161 … … 387 203 /* Unsupported clipboard format is requested. */ 388 204 LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format)); 389 EmptyClipboard();205 VBoxClipboardWinClear(); 390 206 } 391 207 else … … 518 334 519 335 /* Something went wrong. */ 520 EmptyClipboard();336 VBoxClipboardWinClear(); 521 337 } 522 338 } break; … … 527 343 * windows is to be destroyed and therefore the guest side becomes inactive. 528 344 */ 529 int vboxrc = vboxOpenClipboard(hwnd);345 int vboxrc = VBoxClipboardWinOpen(hwnd); 530 346 if (RT_SUCCESS(vboxrc)) 531 347 { 532 EmptyClipboard();533 CloseClipboard();534 } 535 } break; 536 537 case VBOX_ WM_SHCLPB_SET_FORMATS:348 VBoxClipboardWinClear(); 349 VBoxClipboardWinClose(); 350 } 351 } break; 352 353 case VBOX_CLIPBOARD_WM_SET_FORMATS: 538 354 { 539 355 /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */ … … 542 358 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: u32Formats=0x%x\n", u32Formats)); 543 359 544 int vboxrc = vboxOpenClipboard(hwnd);360 int vboxrc = VBoxClipboardWinOpen(hwnd); 545 361 if (RT_SUCCESS(vboxrc)) 546 362 { 547 EmptyClipboard();363 VBoxClipboardWinClear(); 548 364 549 365 HANDLE hClip = NULL; … … 562 378 } 563 379 564 CloseClipboard();380 VBoxClipboardWinClose(); 565 381 566 382 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError())); … … 568 384 } break; 569 385 570 case VBOX_ WM_SHCLPB_READ_DATA:386 case VBOX_CLIPBOARD_WM_READ_DATA: 571 387 { 572 388 /* Send data in the specified format to the host. */ … … 576 392 LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats)); 577 393 578 int vboxrc = vboxOpenClipboard(hwnd);394 int vboxrc = VBoxClipboardWinOpen(hwnd); 579 395 if (RT_SUCCESS(vboxrc)) 580 396 { … … 642 458 } 643 459 644 CloseClipboard();460 VBoxClipboardWinClose(); 645 461 } 646 462 … … 654 470 case WM_DESTROY: 655 471 { 656 vboxClipboardRemoveFromCBChain(pCtx);657 if (p Ctx->timerRefresh)658 KillTimer(p Ctx->hwnd, 0);472 VBoxClipboardWinRemoveFromCBChain(pWinCtx); 473 if (pWinCtx->oldAPI.timerRefresh) 474 KillTimer(pWinCtx->hWnd, 0); 659 475 /* 660 476 * don't need to call PostQuitMessage cause … … 699 515 wc.lpszClassName = s_szClipWndClassName; 700 516 701 pCtx->wndClass = RegisterClassEx(&wc);702 if ( pCtx->wndClass == 0)517 ATOM wndClass = RegisterClassEx(&wc); 518 if (wndClass == 0) 703 519 rc = RTErrConvertFromWin32(GetLastError()); 704 520 } … … 706 522 if (RT_SUCCESS(rc)) 707 523 { 524 const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win; 525 708 526 /* Create the window. */ 709 p Ctx->hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,710 s_szClipWndClassName, s_szClipWndClassName,711 WS_POPUPWINDOW,712 -200, -200, 100, 100, NULL, NULL, hInstance, NULL);713 if (p Ctx->hwnd == NULL)527 pWinCtx->hWnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST, 528 s_szClipWndClassName, s_szClipWndClassName, 529 WS_POPUPWINDOW, 530 -200, -200, 100, 100, NULL, NULL, hInstance, NULL); 531 if (pWinCtx->hWnd == NULL) 714 532 { 715 533 rc = VERR_NOT_SUPPORTED; … … 717 535 else 718 536 { 719 SetWindowPos(p Ctx->hwnd, HWND_TOPMOST, -200, -200, 0, 0,537 SetWindowPos(pWinCtx->hWnd, HWND_TOPMOST, -200, -200, 0, 0, 720 538 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE); 721 539 722 vboxClipboardAddToCBChain(pCtx);723 if (! vboxClipboardIsNewAPI(pCtx))724 p Ctx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL);540 VBoxClipboardWinAddToCBChain(pWinCtx); 541 if (!VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI)) 542 pWinCtx->oldAPI.timerRefresh = SetTimer(pWinCtx->hWnd, 0, 10 * 1000 /* 10s */, NULL); 725 543 } 726 544 } … … 734 552 AssertPtrReturnVoid(pCtx); 735 553 736 if (pCtx->hwnd) 554 const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win; 555 556 if (pWinCtx->hWnd) 737 557 { 738 DestroyWindow(p Ctx->hwnd);739 p Ctx->hwnd = NULL;558 DestroyWindow(pWinCtx->hWnd); 559 pWinCtx->hWnd = NULL; 740 560 } 741 561 742 if (pCtx->wndClass != 0) 743 { 744 UnregisterClass(s_szClipWndClassName, pCtx->pEnv->hInstance); 745 pCtx->wndClass = 0; 746 } 562 UnregisterClass(s_szClipWndClassName, pCtx->pEnv->hInstance); 747 563 } 748 564 … … 777 593 778 594 RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT)); 595 779 596 pCtx->pEnv = pEnv; 780 597 781 598 /* Check that new Clipboard API is available */ 782 vboxClipboardInitNewAPI(pCtx);599 VBoxClipboardWinCheckAndInitNewAPI(&pCtx->Win.newAPI); 783 600 784 601 int rc = VbglR3ClipboardConnect(&pCtx->u32ClientID); … … 811 628 RTThreadUserSignal(RTThreadSelf()); 812 629 813 PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)pInstance;630 const PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)pInstance; 814 631 AssertPtr(pCtx); 632 633 const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win; 815 634 816 635 int rc; … … 846 665 * Forward the information to the window, so it can later 847 666 * respond to WM_RENDERFORMAT message. */ 848 ::PostMessage(p Ctx->hwnd, VBOX_WM_SHCLPB_SET_FORMATS, 0, u32Formats);667 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_SET_FORMATS, 0, u32Formats); 849 668 } break; 850 669 … … 852 671 { 853 672 /* The host needs data in the specified format. */ 854 ::PostMessage(p Ctx->hwnd, VBOX_WM_SHCLPB_READ_DATA, 0, u32Formats);673 ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_READ_DATA, 0, u32Formats); 855 674 } break; 856 675 … … 927 746 VBoxClipboardDestroy 928 747 }; 748
Note:
See TracChangeset
for help on using the changeset viewer.