VirtualBox

Changeset 32333 in vbox for trunk/src/VBox/HostServices


Ignore:
Timestamp:
Sep 9, 2010 8:56:42 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
65675
Message:

HostServices/SharedClipboard: try to spot and fix a broken clipboard chain on Windows hosts

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp

    r28800 r32333  
    3232static char gachWindowClassName[] = "VBoxSharedClipboardClass";
    3333
     34enum { CBCHAIN_TIMEOUT = 5000 /* ms */ };
     35
    3436struct _VBOXCLIPBOARDCONTEXT
    3537{
    3638    HWND    hwnd;
    3739    HWND    hwndNextInChain;
     40
     41    UINT     timerRefresh;
     42
     43    bool     fCBChainPingInProcess;
    3844
    3945    RTTHREAD thread;
     
    187193}
    188194
     195/* Add ourselves into the chain of cliboard listeners */
     196static void addToCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
     197{
     198    pCtx->hwndNextInChain = SetClipboardViewer (pCtx->hwnd);
     199}
     200
     201/* Remove ourselves from the chain of cliboard listeners */
     202static void removeFromCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
     203{
     204    ChangeClipboardChain (pCtx->hwnd, pCtx->hwndNextInChain);
     205    pCtx->hwndNextInChain = NULL;
     206}
     207
     208/* Callback which is invoked when we have successfully pinged ourselves down the
     209 * clipboard chain.  We simply unset a boolean flag to say that we are responding.
     210 * There is a race if a ping returns after the next one is initiated, but nothing
     211 * very bad is likely to happen. */
     212VOID CALLBACK CBChainPingProc(HWND hwnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)
     213{
     214    (void) hwnd;
     215    (void) uMsg;
     216    (void) lResult;
     217    VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)dwData;
     218    pCtx->fCBChainPingInProcess = FALSE;
     219}
     220
    189221static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    190222{
     
    214246                {
    215247                    /* Pass the message further. */
    216                     rc = SendMessage (pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam);
     248                    DWORD_PTR dwResult;
     249                    rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
     250                    if (!rc)
     251                        rc = (LRESULT)dwResult;
    217252                }
    218253            }
     
    232267            {
    233268                /* Pass the message to next windows in the clipboard chain. */
    234                 rc = SendMessage (pCtx->hwndNextInChain, msg, wParam, lParam);
    235             }
     269                DWORD_PTR dwResult;
     270                rc = SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
     271                if (!rc)
     272                    rc = dwResult;
     273            }
     274        } break;
     275
     276        case WM_TIMER:
     277        {
     278            HWND hViewer = GetClipboardViewer();
     279
     280            /* Re-register ourselves in the clipboard chain if our last ping
     281             * timed out or there seems to be no valid chain. */
     282            if (!hViewer || pCtx->fCBChainPingInProcess)
     283            {
     284                removeFromCBChain(pCtx);
     285                addToCBChain(pCtx);
     286            }
     287            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
     288             * processed by ourselves to the chain. */
     289            pCtx->fCBChainPingInProcess = TRUE;
     290            hViewer = GetClipboardViewer();
     291            if (hViewer)
     292                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, CBChainPingProc, (ULONG_PTR) pCtx);
    236293        } break;
    237294
     
    484541                         SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
    485542
    486             pCtx->hwndNextInChain = SetClipboardViewer (pCtx->hwnd);
     543            addToCBChain(pCtx);
     544            pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL);
    487545
    488546            MSG msg;
     
    497555    if (pCtx->hwnd)
    498556    {
    499         ChangeClipboardChain (pCtx->hwnd, pCtx->hwndNextInChain);
    500         pCtx->hwndNextInChain = NULL;
     557        removeFromCBChain(pCtx);
     558        if (pCtx->timerRefresh)
     559            KillTimer(pCtx->hwnd, 0);
    501560
    502561        DestroyWindow (pCtx->hwnd);
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