VirtualBox

Changeset 50305 in vbox for trunk/src/VBox/Additions/WINNT


Ignore:
Timestamp:
Feb 3, 2014 10:47:45 AM (11 years ago)
Author:
vboxsync
Message:

DnD: Update.

Location:
trunk/src/VBox/Additions/WINNT/VBoxTray
Files:
3 edited

Legend:

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

    r50266 r50305  
    515515                    reset();
    516516                    rc = VINF_SUCCESS; /** @todo GUEST_DND_GH_EVT_ERROR */
     517#else
     518                    rc = VERR_NOT_SUPPORTED;
     519#endif
     520                    break;
     521                }
     522
     523                case DragAndDropSvc::HOST_DND_GH_RECV_DIR:
     524                {
     525                    LogFlowThisFunc(("HOST_DND_GH_RECV_DIR\n"));
     526#ifdef VBOX_WITH_DRAG_AND_DROP_GH
     527                    if (mMode == GH)
     528                    {
     529                        rc = OnGhSendDir(pEvent->Event.pszFormats,
     530                                         pEvent->Event.cbFormats,
     531                                         pEvent->Event.u.a.uDefAction);
     532                    }
     533                    else
     534                        rc = VERR_WRONG_ORDER;
     535#else
     536                    rc = VERR_NOT_SUPPORTED;
     537#endif
     538                    break;
     539                }
     540
     541                case DragAndDropSvc::HOST_DND_GH_RECV_FILE:
     542                {
     543                    LogFlowThisFunc(("HOST_DND_GH_RECV_FILE\n"));
     544#ifdef VBOX_WITH_DRAG_AND_DROP_GH
     545                    if (mMode == GH)
     546                    {
     547                        rc = OnGhSendFile(pEvent->Event.pszFormats,
     548                                          pEvent->Event.cbFormats,
     549                                          pEvent->Event.u.a.uDefAction);
     550                    }
     551                    else
     552                        rc = VERR_WRONG_ORDER;
    517553#else
    518554                    rc = VERR_NOT_SUPPORTED;
     
    934970#endif
    935971
    936 #if 1
    937972        /** @todo Multi-monitor setups? */
    938973        int iScreenX = GetSystemMetrics(SM_CXSCREEN) - 1;
     
    963998        else
    964999            LogFlowFunc(("Unable to send input, error=0x%x\n", GetLastError()));
    965 #else
    966         SetCursorPos(p.x, p.y);
    967 #endif
    9681000
    9691001#ifdef DEBUG_andy
     
    9811013    if (RT_SUCCESS(rc))
    9821014    {
     1015        uint32_t uDefAction = DND_IGNORE_ACTION;
     1016
    9831017        AssertPtr(pDropTarget);
    984 
    985         uint32_t uDefAction = DND_IGNORE_ACTION;
    986         RTCString strFormat = "unknown";
    987         if (pDropTarget->HasData())
     1018        RTCString strFormats = pDropTarget->Formats();
     1019        if (!strFormats.isEmpty())
    9881020        {
    9891021            uDefAction = DND_COPY_ACTION;
    9901022            uAllActions = uDefAction;
    9911023
    992             /** @todo There can be more than one format, separated
    993              *        with \r\n. */
    994             strFormat = "text/plain;charset=utf-8";
    995 
    996             LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormat=%s\n",
    997                          pDropTarget, uDefAction, uAllActions, strFormat.c_str()));
     1024            LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormats=%s\n",
     1025                         pDropTarget, uDefAction, uAllActions, strFormats.c_str()));
    9981026            rc = VbglR3DnDGHAcknowledgePending(mClientID,
    999                                                uDefAction, uAllActions, strFormat.c_str());
    1000         }
     1027                                               uDefAction, uAllActions, strFormats.c_str());
     1028        }
     1029        else
     1030            LogFlowFunc(("No format data available yet\n"));
    10011031    }
    10021032
     
    10081038                            uint32_t uDefAction)
    10091039{
    1010     LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, cbFormats=%RU32, uDefAction=0x%x\n",
    1011                      mMode, mState, pDropTarget, cbFormats, uDefAction));
     1040    AssertPtrReturn(pszFormats, VERR_INVALID_POINTER);
     1041    AssertReturn(cbFormats, VERR_INVALID_PARAMETER);
     1042
     1043    LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, uDefAction=0x%x\n",
     1044                     mMode, mState, pDropTarget, uDefAction));
     1045#ifdef DEBUG
     1046    RTCList<RTCString> lstFormats =
     1047        RTCString(pszFormats, cbFormats - 1).split("\r\n");
     1048
     1049    LogFlow(("cbFormats=%RU32: ", cbFormats));
     1050    for (size_t i = 0; i < lstFormats.size(); i++)
     1051        LogFlow(("'%s' ", lstFormats.at(i).c_str()));
     1052    LogFlow(("\n"));
     1053#endif
     1054
    10121055    int rc;
    10131056    if (mState == Dragging)
    10141057    {
    10151058        AssertPtr(pDropTarget);
    1016         rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout */);
     1059        rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
    10171060        if (RT_SUCCESS(rc))
    10181061        {
     
    10351078        rc = VERR_WRONG_ORDER;
    10361079
     1080    LogFlowFuncLeaveRC(rc);
     1081    return rc;
     1082}
     1083
     1084int VBoxDnDWnd::OnGhSendDir(const char *pszFormats, uint32_t cbFormats,
     1085                            uint32_t uDefAction)
     1086{
     1087    int rc = 0;
     1088    LogFlowFuncLeaveRC(rc);
     1089    return rc;
     1090}
     1091
     1092int VBoxDnDWnd::OnGhSendFile(const char *pszFormats, uint32_t cbFormats,
     1093                             uint32_t uDefAction)
     1094{
     1095    int rc = 0;
    10371096    LogFlowFuncLeaveRC(rc);
    10381097    return rc;
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h

    r50265 r50305  
    155155public:
    156156
    157     bool HasData(void) { return RT_BOOL(mFormatEtc.cfFormat != 0); }
    158157    void *DataMutableRaw(void) { return mpvData; }
    159158    uint32_t DataSize(void) { return mcbData; }
     159    RTCString Formats(void);
    160160    int WaitForDrop(RTMSINTERVAL msTimeout);
    161161
     
    170170     *        DVTARGETDEVICE here! */
    171171    FORMATETC mFormatEtc;
     172    RTCString mFormats;
    172173    void *mpvData;
    173174    uint32_t mcbData;
     
    338339    int OnGhIsDnDPending(uint32_t uScreenID);
    339340    int OnGhDropped(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
     341    int OnGhSendDir(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
     342    int OnGhSendFile(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
    340343#endif
    341344
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp

    r50265 r50305  
    1717#include <windows.h>
    1818#include <new> /* For bad_alloc. */
     19#include <Shlobj.h> /* For DROPFILES and friends. */
    1920
    2021#include "VBoxTray.h"
     
    107108    reset();
    108109
     110    /** @todo At the moment we only support one DnD format at a time. */
     111
    109112    /* Try different formats. CF_HDROP is the most common one, so start
    110113     * with this. */
    111     /** @todo At the moment we only support TYMED_HGLOBAL. */
    112114    FORMATETC fmtEtc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
    113115    HRESULT hr = pDataObject->QueryGetData(&fmtEtc);
    114     if (hr != S_OK)
     116    if (hr == S_OK)
     117    {
     118        mFormats = "text/uri-list";
     119    }
     120    else
    115121    {
    116122        LogFlowFunc(("CF_HDROP not supported, hr=%Rhrc\n", hr));
     
    125131            fmtEtc.cfFormat = 0; /* Mark it to not supported. */
    126132        }
     133        else
     134        {
     135            mFormats = "text/plain;charset=utf-8";
     136        }
    127137    }
    128138
     
    130140    if (fmtEtc.cfFormat)
    131141    {
    132         LogFlowFunc(("Found supported format %RI16\n", fmtEtc.cfFormat));
     142        LogFlowFunc(("Found supported format %RI16 (%s)\n",
     143                     fmtEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(fmtEtc.cfFormat)));
    133144
    134145        /* Make a copy of the FORMATETC structure so that we later can
    135146         * use this for comparrison and stuff. */
    136         /** Note: The DVTARGETDEVICE member only is a shallow copy! */
     147        /** Note: The DVTARGETDEVICE member only is a shallow copy for now! */
    137148        memcpy(&mFormatEtc, &fmtEtc, sizeof(FORMATETC));
    138149
     
    164175                    while (pEnumFormats->Next(1, &curFormatEtc,
    165176                                              NULL /* pceltFetched */) == S_OK)
    166                         {
     177                    {
    167178                        WCHAR wszCfName[128]; /* 128 chars should be enough, rest will be truncated. */
    168179                        hr2 = GetClipboardFormatNameW(curFormatEtc.cfFormat, wszCfName,
    169180                                                      sizeof(wszCfName) / sizeof(WCHAR));
    170                         LogRel(("\tcfFormat=%RI16, tyMed=%RI32, dwAspect=%RI32, strCustomName=%ls, hr=%Rhrc\n",
     181                        LogRel(("\tcfFormat=%RI16 (%s), tyMed=%RI32, dwAspect=%RI32, strCustomName=%ls, hr=%Rhrc\n",
    171182                                curFormatEtc.cfFormat,
     183                                VBoxDnDDataObject::ClipboardFormatToString(curFormatEtc.cfFormat),
    172184                                curFormatEtc.tymed,
    173185                                curFormatEtc.dwAspect,
     
    176188
    177189                    pEnumFormats->Release();
    178                 }
     190                }
    179191
    180192                break;
     
    236248
    237249#ifdef DEBUG
    238     LogFlowFunc(("mFormatEtc.cfFormat=%RI16, pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld\n",
    239                  mFormatEtc.cfFormat, pDataObject, grfKeyState, pt.x, pt.y));
     250    LogFlowFunc(("mFormatEtc.cfFormat=%RI16 (%s), pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld\n",
     251                 mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
     252                 pDataObject, grfKeyState, pt.x, pt.y));
    240253#endif
    241254    HRESULT hr = S_OK;
     
    248261        hr = pDataObject->QueryGetData(&mFormatEtc);
    249262        AssertMsg(SUCCEEDED(hr),
    250                   ("Data format changed between DragEnter() and Drop(), cfFormat=%RI16, hr=%Rhrc\n",
    251                   mFormatEtc.cfFormat, hr));
    252     }
     263                  ("Data format changed between DragEnter() and Drop(), cfFormat=%RI16 (%s), hr=%Rhrc\n",
     264                  mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
     265                  hr));
     266    }
     267
     268    int rc = VINF_SUCCESS;
    253269
    254270    if (SUCCEEDED(hr))
     
    272288                        LogFlowFunc(("Locking HGLOBAL storage failed with %Rrc\n",
    273289                                     RTErrConvertFromWin32(GetLastError())));
    274                         hr = ERROR_INVALID_HANDLE;
     290                        rc = VERR_INVALID_HANDLE;
     291                        hr = E_INVALIDARG; /* Set special hr for OLE. */
    275292                    }
    276293                    break;
     
    279296                    AssertMsgFailed(("Storage medium type %RI32 supported\n",
    280297                                     mFormatEtc.tymed));
    281                     hr = ERROR_NOT_SUPPORTED;
     298                    rc = VERR_NOT_SUPPORTED;
     299                    hr = DV_E_TYMED; /* Set special hr for OLE. */
    282300                    break;
    283301            }
    284302
    285             if (SUCCEEDED(hr))
     303            if (RT_SUCCESS(rc))
    286304            {
    287305                /* Second stage: Do the actual copying of the data object's data,
     
    289307                switch (mFormatEtc.cfFormat)
    290308                {
     309                    /* Handling CF_TEXT means that the system already did some marshalling
     310                     * to convert RTF or unicode text to plain ANSI text. */
    291311                    case CF_TEXT:
    292312                    {
    293                         LogFlowFunc(("pvData=%s\n", (char*)pvData));
    294 
    295                         uint32_t cbSize = strlen((char*)pvData); /** @todo Evil hack, fix this! */
    296                         mpvData = RTMemDup(pvData, cbSize);
    297                         mcbData = cbSize;
     313                        AssertPtr(pvData);
     314                        size_t cbSize = GlobalSize(pvData);
     315                        LogFlowFunc(("CF_TEXT 0x%p got %zu bytes\n", pvData, cbSize));
     316                        if (cbSize)
     317                        {
     318                            char *pszText = NULL;
     319                            rc = RTStrCurrentCPToUtf8(&pszText, (char *)pvData);
     320                            if (RT_SUCCESS(rc))
     321                            {
     322                                mpvData = (void *)pszText;
     323                                mcbData = strlen(pszText) + 1;
     324                            }
     325                        }
     326
    298327                        break;
    299328                    }
    300329
    301330                    case CF_HDROP:
     331                    {
     332                        AssertPtr(pvData);
     333
     334                        /* Convert to a string list, separated by \r\n. */
     335                        DROPFILES *pDropFiles = (DROPFILES *)pvData;
     336                        AssertPtr(pDropFiles);
     337                        bool fUnicode = RT_BOOL(pDropFiles->fWide);
     338
     339                        /* Get the offset of the file list. */
     340                        Assert(pDropFiles->pFiles >= sizeof(DROPFILES));
     341                        /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only
     342                         *       will work with the plain storage medium pointer! */
     343                        HDROP hDrop = (HDROP)(pvData);
     344
     345                        /* First, get the file count. */
     346                        /** @todo Does this work on Windows 2000 / NT4? */
     347                        char *pszFiles = NULL;
     348                        uint32_t cchFiles = 0;
     349                        UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */,
     350                                                    NULL /* lpszFile */, 0 /* cchFile */);
     351                        LogFlowFunc(("CF_HDROP got %RU16 file(s)\n", cFiles));
     352
     353                        for (UINT i = 0; i < cFiles; i++)
     354                        {
     355                            UINT cch = DragQueryFile(hDrop, i /* File index */,
     356                                                     NULL /* Query size first */,
     357                                                     0 /* cchFile */);
     358                            Assert(cch);
     359
     360                            /* Add separation between filenames. */
     361                            if (i > 0)
     362                            {
     363                                rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
     364                                                     "\r\n", 2 /* Bytes */);
     365                                if (RT_SUCCESS(rc))
     366                                    cchFiles += 2; /* Include \r\n */
     367                            }
     368
     369                            if (RT_FAILURE(rc))
     370                                return rc;
     371
     372                            char *pszFile = NULL; /* UTF-8 version. */
     373                            UINT cchFile = 0;
     374                            if (fUnicode)
     375                            {
     376                                /* Allocate enough space (including terminator). */
     377                                WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cch + 1) * sizeof(WCHAR));
     378                                if (pwszFile)
     379                                {
     380                                    cchFile = DragQueryFileW(hDrop, i /* File index */,
     381                                                             pwszFile, cch + 1 /* Include terminator */);
     382                                    AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n",
     383                                                               cchFile, cch));
     384                                    int rc2 = RTUtf16ToUtf8(pwszFile, &pszFile);
     385                                    AssertRC(rc2);
     386                                }
     387                                else
     388                                    rc = VERR_NO_MEMORY;
     389                            }
     390                            else /* ANSI */
     391                            {
     392                                /* Allocate enough space (including terminator). */
     393                                pszFile = (char *)RTMemAlloc((cch + 1) * sizeof(char));
     394                                if (pszFile)
     395                                {
     396                                    cchFile = DragQueryFileA(hDrop, i /* File index */,
     397                                                             pszFile, cchFile + 1 /* Include terminator */);
     398                                    AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n",
     399                                                               cchFile, cch));
     400                                }
     401                                else
     402                                    rc = VERR_NO_MEMORY;
     403                            }
     404
     405                            if (RT_SUCCESS(rc))
     406                            {
     407                                LogFlowFunc(("\tFile: %s (%RU32 characters)\n",
     408                                             pszFile, cchFile));
     409
     410                                rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
     411                                                     pszFile, cchFile);
     412                            }
     413
     414                            /* Termination. */
     415                            pszFiles[cchFiles] = '\0';
     416
     417                            if (pszFile)
     418                                RTMemFree(pszFile);
     419
     420                            if (RT_FAILURE(rc))
     421                                break;
     422                        }
     423
     424                        if (RT_SUCCESS(rc))
     425                        {
     426                            uint32_t cbSize = cchFiles * sizeof(char);
     427                            Assert(cbSize);
     428
     429                            mpvData = RTMemDup(pszFiles, cbSize);
     430                            mcbData = cbSize;
     431                        }
     432
     433                        LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n",
     434                                     rc, pszFiles, cFiles, cchFiles));
     435
     436                        if (pszFiles)
     437                            RTStrFree(pszFiles);
    302438                        break;
     439                    }
    303440
    304441                    default:
    305                         AssertMsgFailed(("Format of type %RI16 supported\n",
    306                                          mFormatEtc.cfFormat));
     442                        AssertMsgFailed(("Format of type %RI16 (%s) not supported\n",
     443                                         mFormatEtc.cfFormat,
     444                                         VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat)));
    307445                        hr = ERROR_NOT_SUPPORTED;
     446                        hr = DV_E_CLIPFORMAT; /* Set special hr for OLE. */
    308447                        break;
    309448                }
     
    320459
    321460                default:
    322                     AssertMsgFailed(("Storage medium type %RI32 supported\n",
    323                                      mFormatEtc.tymed));
    324                     hr = ERROR_NOT_SUPPORTED;
     461                    AssertMsgFailed(("Really should not happen -- see init stage!\n"));
    325462                    break;
    326463            }
     
    329466            ReleaseStgMedium(&stgMed);
    330467
    331             if (SUCCEEDED(hr))
     468            /** @todo Signal in any case to avoid hangs/timeouts? */
     469            if (RT_SUCCESS(rc))
    332470            {
    333471                RTSemEventSignal(hEventDrop);
     
    349487        mpWndParent->hide();
    350488
    351     LogFlowFunc(("Returning with mFormatEtc.cfFormat=%RI16, fCanDrop=%RTbool, *pdwEffect=%RI32\n",
    352                  mFormatEtc.cfFormat, fCanDrop, *pdwEffect));
     489    LogFlowFunc(("Returning with rc=%Rrc, mFormatEtc.cfFormat=%RI16 (%s), fCanDrop=%RTbool, *pdwEffect=%RI32\n",
     490                 rc, mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
     491                 fCanDrop, *pdwEffect));
     492
    353493    return hr;
    354494}
     
    395535    mcbData = 0;
    396536    RT_ZERO(mFormatEtc);
     537    mFormats = "";
     538}
     539
     540RTCString VBoxDnDDropTarget::Formats(void)
     541{
     542    return mFormats;
    397543}
    398544
Note: See TracChangeset for help on using the changeset viewer.

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