VirtualBox

Changeset 58604 in vbox


Ignore:
Timestamp:
Nov 6, 2015 12:59:50 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
103972
Message:

bugref:6466: Additions/SharedClipboard: Added support of new MS clipboard API

Location:
trunk/src/VBox
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r58144 r58604  
    2020
    2121#include <iprt/asm.h>
     22#include <iprt/ldr.h>
    2223
    2324#include <VBox/HostServices/VBoxClipboardSvc.h>
     
    3132#include <VBox/log.h>
    3233
    33 
     34 /* Dynamically load clipboard functions from User32.dll. */
     35typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND);
     36typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER;
     37
     38typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND);
     39typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER;
     40
     41#ifndef WM_CLIPBOARDUPDATE
     42#define WM_CLIPBOARDUPDATE 0x031D
     43#endif
    3444
    3545typedef struct _VBOXCLIPBOARDCONTEXT
     
    4252    UINT                  timerRefresh;
    4353    bool                  fCBChainPingInProcess;
     54    PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener;
     55    PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener;
    4456} VBOXCLIPBOARDCONTEXT, *PVBOXCLIPBOARDCONTEXT;
    4557
     
    5062
    5163enum { CBCHAIN_TIMEOUT = 5000 /* ms */ };
     64
     65static 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
     92static bool vboxClipboardIsNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)
     93{
     94    return pCtx->pfnAddClipboardFormatListener != NULL;
     95}
    5296
    5397static int vboxClipboardChanged(PVBOXCLIPBOARDCONTEXT pCtx)
     
    111155{
    112156    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);
    114161    /** @todo r=andy Return code?? */
    115162}
     
    120167    AssertPtrReturnVoid(pCtx);
    121168
    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    }
    124178    /** @todo r=andy Return code?? */
    125179}
     
    150204    switch (msg)
    151205    {
     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
    152217        case WM_CHANGECBCHAIN:
    153218        {
     219            if (vboxClipboardIsNewAPI(pCtx))
     220            {
     221                rc = DefWindowProc(hwnd, msg, wParam, lParam);
     222                break;
     223            }
     224
    154225            HWND hwndRemoved = (HWND)wParam;
    155226            HWND hwndNext    = (HWND)lParam;
     
    180251            LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pCtx->hwnd));
    181252
    182             if (GetClipboardOwner () != hwnd)
     253            if (GetClipboardOwner() != hwnd)
    183254            {
    184255                /* Clipboard was updated by another application. */
     
    189260            }
    190261
    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            }
    193267        } break;
    194268
    195269        case WM_TIMER:
    196270        {
     271            if (vboxClipboardIsNewAPI(pCtx))
     272                break;
     273
    197274            HWND hViewer = GetClipboardViewer();
    198275
     
    209286            hViewer = GetClipboardViewer();
    210287            if (hViewer)
    211                 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR) pCtx);
     288                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR)pCtx);
    212289        } break;
    213290
     
    591668
    592669            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);
    594672        }
    595673    }
     
    651729    RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT));
    652730    pCtx->pEnv = pEnv;
     731
     732    /* Check that new Clipboard API is available */
     733    vboxClipboardInitNewAPI(pCtx);
    653734
    654735    int rc = VbglR3ClipboardConnect(&pCtx->u32ClientID);
     
    798879    VBoxClipboardDestroy
    799880};
    800 
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp

    r44528 r58604  
    44
    55/*
    6  * Copyright (C) 2006-2011 Oracle Corporation
     6 * Copyright (C) 2006-2015 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2424#include <iprt/assert.h>
    2525#include <iprt/thread.h>
     26#include <iprt/ldr.h>
    2627#include <process.h>
    2728
     
    3334
    3435enum { CBCHAIN_TIMEOUT = 5000 /* ms */ };
     36
     37/* Dynamically load clipboard functions from User32.dll. */
     38typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND);
     39typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER;
     40
     41typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND);
     42typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER;
     43
     44#ifndef WM_CLIPBOARDUPDATE
     45#define WM_CLIPBOARDUPDATE 0x031D
     46#endif
    3547
    3648struct _VBOXCLIPBOARDCONTEXT
     
    4961
    5062    VBOXCLIPBOARDCLIENTDATA *pClient;
     63
     64    PFNADDCLIPBOARDFORMATLISTENER    pfnAddClipboardFormatListener;
     65    PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener;
     66
    5167};
    5268
     
    95111#endif /* LOG_ENABLED */
    96112
     113static 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
     140static bool vboxClipboardIsNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)
     141{
     142    return pCtx->pfnAddClipboardFormatListener != NULL;
     143}
     144
    97145static void vboxClipboardGetData (uint32_t u32Format, const void *pvSrc, uint32_t cbSrc,
    98146                                  void *pvDst, uint32_t cbDst, uint32_t *pcbActualDst)
     
    120168{
    121169    Assert(pCtx->pClient);
     170    Assert(pCtx->hRenderEvent);
    122171    Assert(pCtx->pClient->data.pv == NULL && pCtx->pClient->data.cb == 0 && pCtx->pClient->data.u32Format == 0);
    123172
     
    128177    vboxSvcClipboardReportMsg (pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, u32Format);
    129178
    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);
    133182
    134183    return VINF_SUCCESS;
     
    196245static void addToCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
    197246{
    198     pCtx->hwndNextInChain = SetClipboardViewer (pCtx->hwnd);
     247    if (vboxClipboardIsNewAPI(pCtx))
     248        pCtx->pfnAddClipboardFormatListener(pCtx->hwnd);
     249    else
     250        pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd);
    199251}
    200252
     
    202254static void removeFromCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
    203255{
    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    }
    206265}
    207266
     
    227286    switch (msg)
    228287    {
     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
    229299        case WM_CHANGECBCHAIN:
    230300        {
    231301            Log(("WM_CHANGECBCHAIN\n"));
     302
     303            if (vboxClipboardIsNewAPI(pCtx))
     304            {
     305                rc = DefWindowProc(hwnd, msg, wParam, lParam);
     306                break;
     307            }
    232308
    233309            HWND hwndRemoved = (HWND)wParam;
     
    256332        case WM_DRAWCLIPBOARD:
    257333        {
    258             Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->hwndNextInChain));
     334            Log(("WM_DRAWCLIPBOARD\n"));
    259335
    260336            if (GetClipboardOwner () != hwnd)
     
    266342            if (pCtx->hwndNextInChain)
    267343            {
     344                Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->hwndNextInChain));
    268345                /* Pass the message to next windows in the clipboard chain. */
    269346                DWORD_PTR dwResult;
     
    276353        case WM_TIMER:
    277354        {
     355            if (vboxClipboardIsNewAPI(pCtx))
     356                break;
     357
    278358            HWND hViewer = GetClipboardViewer();
    279359
     
    292372                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, CBChainPingProc, (ULONG_PTR) pCtx);
    293373        } break;
    294 
    295         case WM_CLOSE:
    296         {
    297             /* Do nothing. Ignore the message. */
    298         } break;
    299 
     374                       
    300375        case WM_RENDERFORMAT:
    301376        {
     
    344419            {
    345420                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));
    348424
    349425                if (   RT_SUCCESS (vboxrc)
     
    430506                 * because host clipboard has more priority.
    431507                 */
     508                Log(("WM_USER ignored\n"));
    432509                break;
    433510            }
     
    480557        } break;
    481558
     559        case WM_CLOSE:
     560        {
     561            /* Do nothing. Ignore the message. */
     562        } break;
     563
    482564        default:
    483565        {
    484566            Log(("WM_ %p\n", msg));
    485             rc = DefWindowProc (hwnd, msg, wParam, lParam);
     567            rc = DefWindowProc(hwnd, msg, wParam, lParam);
    486568        }
    487569    }
     
    500582    VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx;
    501583
    502     HINSTANCE hInstance = (HINSTANCE)GetModuleHandle (NULL);
     584    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
    503585
    504586    /* Register the Window Class. */
    505587    WNDCLASS wc;
     588    RT_ZERO(wc);
    506589
    507590    wc.style         = CS_NOCLOSE;
    508591    wc.lpfnWndProc   = vboxClipboardWndProc;
    509     wc.cbClsExtra    = 0;
    510     wc.cbWndExtra    = 0;
    511592    wc.hInstance     = hInstance;
    512     wc.hIcon         = NULL;
    513     wc.hCursor       = NULL;
    514593    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
    515     wc.lpszMenuName  = NULL;
    516594    wc.lpszClassName = gachWindowClassName;
    517595
    518     ATOM atomWindowClass = RegisterClass (&wc);
     596    ATOM atomWindowClass = RegisterClass(&wc);
    519597
    520598    if (atomWindowClass == 0)
     
    542620
    543621            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);
    545624
    546625            MSG msg;
     
    578657{
    579658    int rc = VINF_SUCCESS;
     659
     660    RT_ZERO(g_ctx);
     661
     662    /* Check that new Clipboard API is available */
     663    vboxClipboardInitNewAPI(&g_ctx);
    580664
    581665    g_ctx.hRenderEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette