VirtualBox

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


Ignore:
Timestamp:
Feb 10, 2014 4:21:09 PM (11 years ago)
Author:
vboxsync
Message:

DnD/VBoxTray: Only works on NT4 SP3+, bugfixes.

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

Legend:

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

    r50305 r50399  
    4646#define WM_VBOXTRAY_DND_MESSAGE       WM_APP + 401
    4747
     48/** Function pointer for SendInput(). This only is available starting
     49 *  at NT4 SP3+. */
     50typedef BOOL (WINAPI *PFNSENDINPUT)(UINT, LPINPUT, int);
     51
     52/** Static pointer to SendInput() function. */
     53static PFNSENDINPUT s_pfnSendInput = NULL;
     54
    4855static LRESULT CALLBACK vboxDnDWndProcInstance(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    4956static LRESULT CALLBACK vboxDnDWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
     
    335342                    HRESULT hr = DoDragDrop(startupInfo.pDataObject, startupInfo.pDropSource,
    336343                                            startupInfo.dwOKEffects, &dwEffect);
    337                     LogFlowThisFunc(("rc=%Rhrc, dwEffect=%RI32\n", hr, dwEffect));
     344                    LogFlowThisFunc(("hr=%Rhrc, dwEffect=%RI32\n", hr, dwEffect));
    338345                    switch (hr)
    339346                    {
     
    773780                     u32xPos, u32yPos, uAction));
    774781
    775     /** @todo Put this block into a function! */
    776     /** @todo Multi-monitor setups? */
    777     int iScreenX = GetSystemMetrics(SM_CXSCREEN) - 1;
    778     int iScreenY = GetSystemMetrics(SM_CYSCREEN) - 1;
    779 
    780     INPUT Input[1] = { 0 };
    781     Input[0].type       = INPUT_MOUSE;
    782     Input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE;
    783     Input[0].mi.dx      = u32xPos * (65535 / iScreenX);
    784     Input[0].mi.dy      = u32yPos * (65535 / iScreenY);
    785     SendInput(1, Input, sizeof(INPUT));
    786 
    787 #ifdef DEBUG_andy
    788     POINT p;
    789     GetCursorPos(&p);
    790     LogFlowThisFunc(("curX=%d, curY=%d\n", p.x, p.y));
    791 #endif
     782    int rc = mouseMove(u32xPos, u32yPos, MOUSEEVENTF_LEFTDOWN);
    792783
    793784    uint32_t uActionNotify = DND_IGNORE_ACTION;
    794     int rc = RTCritSectEnter(&mCritSect);
     785    if (RT_SUCCESS(rc))
     786        rc = RTCritSectEnter(&mCritSect);
    795787    if (RT_SUCCESS(rc))
    796788    {
     
    889881    }
    890882
    891     int rc2 = dragRelease();
     883    int rc2 = mouseRelease();
    892884    if (RT_SUCCESS(rc))
    893885        rc = rc2;
     
    908900    }
    909901
    910     int rc2 = dragRelease();
     902    int rc2 = mouseRelease();
    911903    if (RT_SUCCESS(rc))
    912904        rc = rc2;
     
    936928             * get into our (invisible) proxy window.
    937929             */
    938             dragRelease();
     930            mouseRelease();
    939931
    940932            /*
     
    980972        if (py <= 0)
    981973            py = 1;
    982         //px++; py++;
    983         LogFlowThisFunc(("px=%ld, py=%ld\n", px, py));
    984 
    985         INPUT Input[1] = { 0 };
    986         Input[0].type       = INPUT_MOUSE;
    987         Input[0].mi.dwFlags = MOUSEEVENTF_MOVE | /*MOUSEEVENTF_LEFTDOWN |*/ MOUSEEVENTF_ABSOLUTE;
    988         Input[0].mi.dx      = px * (65535 / iScreenX);
    989         Input[0].mi.dy      = py * (65535 / iScreenY);
    990         UINT uiProcessed = SendInput(1, Input, sizeof(INPUT));
    991         if (uiProcessed)
    992         {
     974
     975        rc = mouseMove(px, py, 0 /* dwMouseInputFlags */);
     976    }
     977
     978    if (RT_SUCCESS(rc))
     979    {
     980        uint32_t uDefAction = DND_IGNORE_ACTION;
     981
     982        AssertPtr(pDropTarget);
     983        RTCString strFormats = pDropTarget->Formats();
     984        if (!strFormats.isEmpty())
     985        {
     986            uDefAction = DND_COPY_ACTION;
     987            uAllActions = uDefAction;
     988
     989            LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormats=%s\n",
     990                         pDropTarget, uDefAction, uAllActions, strFormats.c_str()));
     991            rc = VbglR3DnDGHAcknowledgePending(mClientID,
     992                                               uDefAction, uAllActions, strFormats.c_str());
     993        }
     994        else
     995            LogFlowFunc(("No format data available yet\n"));
     996    }
     997
     998    LogFlowFuncLeaveRC(rc);
     999    return rc;
     1000}
     1001
     1002int VBoxDnDWnd::OnGhDropped(const char *pszFormat, uint32_t cbFormats,
     1003                            uint32_t uDefAction)
     1004{
     1005    AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
     1006    AssertReturn(cbFormats, VERR_INVALID_PARAMETER);
     1007
     1008    LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, uDefAction=0x%x\n",
     1009                     mMode, mState, pDropTarget, uDefAction));
     1010
     1011    int rc;
     1012    if (mState == Dragging)
     1013    {
     1014        AssertPtr(pDropTarget);
     1015        rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
     1016        if (RT_SUCCESS(rc))
     1017        {
     1018            /** @todo Respect uDefAction. */
     1019            /** @todo Do data checking / conversion based on pszFormats. */
     1020
     1021            void *pvData = pDropTarget->DataMutableRaw();
     1022            AssertPtr(pvData);
     1023            uint32_t cbData = pDropTarget->DataSize();
     1024            Assert(cbData);
     1025
     1026            rc = VbglR3DnDGHSendData(mClientID, pvData, cbData);
     1027            LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n",
     1028                         pvData, cbData, rc));
     1029        }
     1030
     1031        reset();
     1032    }
     1033    else
     1034        rc = VERR_WRONG_ORDER;
     1035
     1036    LogFlowFuncLeaveRC(rc);
     1037    return rc;
     1038}
     1039
     1040int VBoxDnDWnd::OnGhSendDir(const char *pszFormats, uint32_t cbFormats,
     1041                            uint32_t uDefAction)
     1042{
     1043    int rc = 0;
     1044    LogFlowFuncLeaveRC(rc);
     1045    return rc;
     1046}
     1047
     1048int VBoxDnDWnd::OnGhSendFile(const char *pszFormats, uint32_t cbFormats,
     1049                             uint32_t uDefAction)
     1050{
     1051    int rc = 0;
     1052    LogFlowFuncLeaveRC(rc);
     1053    return rc;
     1054}
     1055#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
     1056
     1057int VBoxDnDWnd::ProcessEvent(PVBOXDNDEVENT pEvent)
     1058{
     1059    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
     1060
     1061    PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
     1062                0 /* wParm */, (LPARAM)pEvent /* lParm */);
     1063
     1064    return VINF_SUCCESS;
     1065}
     1066
     1067int VBoxDnDWnd::hide(void)
     1068{
    9931069#ifdef DEBUG_andy
    994             LogFlowFunc(("Sent %RU16 mouse input(s), x=%ld, y=%ld, flags=0x%x\n",
    995                          uiProcessed, Input[0].mi.dx, Input[0].mi.dy, Input[0].mi.dwFlags));
    996 #endif
     1070    LogFlowFunc(("\n"));
     1071#endif
     1072    ShowWindow(hWnd, SW_HIDE);
     1073
     1074    return VINF_SUCCESS;
     1075}
     1076
     1077int VBoxDnDWnd::makeFullscreen(void)
     1078{
     1079    int rc = VINF_SUCCESS;
     1080
     1081    RECT r;
     1082    RT_ZERO(r);
     1083
     1084    BOOL fRc;
     1085    HDC hDC = GetDC(NULL /* Entire screen */);
     1086    if (hDC)
     1087    {
     1088        fRc = EnumDisplayMonitors(hDC, NULL, VBoxDnDWnd::MonitorEnumProc,
     1089                                  (LPARAM)&r);
     1090        if (!fRc)
     1091            rc = VERR_NOT_FOUND;
     1092        ReleaseDC(NULL, hDC);
     1093    }
     1094    else
     1095        rc = VERR_ACCESS_DENIED;
     1096
     1097    if (RT_FAILURE(rc))
     1098    {
     1099        /* If multi-monitor enumeration failed above, try getting at least the
     1100         * primary monitor as a fallback. */
     1101        MONITORINFO monitor_info;
     1102        monitor_info.cbSize = sizeof(monitor_info);
     1103        if (GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST),
     1104                           &monitor_info))
     1105        {
     1106
     1107            r = monitor_info.rcMonitor;
     1108            rc = VINF_SUCCESS;
     1109        }
     1110    }
     1111
     1112    if (RT_SUCCESS(rc))
     1113    {
     1114        LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
     1115        SetWindowLong(hWnd, GWL_STYLE,
     1116                      lStyle & ~(WS_CAPTION | WS_THICKFRAME));
     1117        LONG lExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
     1118        SetWindowLong(hWnd, GWL_EXSTYLE,
     1119                      lExStyle & ~(  WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE
     1120                                   | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
     1121
     1122        fRc = SetWindowPos(hWnd, HWND_TOPMOST,
     1123                           r.left,
     1124                           r.top,
     1125                           r.right  - r.left,
     1126                           r.bottom - r.top,
     1127#ifdef VBOX_DND_DEBUG_WND
     1128                           SWP_SHOWWINDOW | SWP_FRAMECHANGED);
     1129#else
     1130                           SWP_SHOWWINDOW | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);
     1131#endif
     1132        if (fRc)
     1133        {
     1134            LogFlowFunc(("Virtual screen is %ld,%ld,%ld,%ld (%ld x %ld)\n",
     1135                         r.left, r.top, r.right, r.bottom,
     1136                         r.right - r.left, r.bottom - r.top));
    9971137        }
    9981138        else
    999             LogFlowFunc(("Unable to send input, error=0x%x\n", GetLastError()));
    1000 
     1139        {
     1140            DWORD dwErr = GetLastError();
     1141            LogRel(("DnD: Failed to set proxy window position, rc=%Rrc\n",
     1142                    RTErrConvertFromWin32(dwErr)));
     1143        }
     1144    }
     1145    else
     1146        LogRel(("DnD: Failed to determine virtual screen size, rc=%Rrc\n", rc));
     1147
     1148    LogFlowFuncLeaveRC(rc);
     1149    return rc;
     1150}
     1151
     1152int VBoxDnDWnd::mouseMove(int x, int y, DWORD dwMouseInputFlags)
     1153{
     1154    int iScreenX = GetSystemMetrics(SM_CXSCREEN) - 1;
     1155    int iScreenY = GetSystemMetrics(SM_CYSCREEN) - 1;
     1156
     1157    INPUT Input[1] = { 0 };
     1158    Input[0].type       = INPUT_MOUSE;
     1159    Input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE
     1160                        | dwMouseInputFlags;
     1161    Input[0].mi.dx      = x * (65535 / iScreenX);
     1162    Input[0].mi.dy      = y * (65535 / iScreenY);
     1163
     1164    int rc;
     1165    if (s_pfnSendInput(1 /* Number of inputs */,
     1166                       Input, sizeof(INPUT)))
     1167    {
    10011168#ifdef DEBUG_andy
    10021169        CURSORINFO ci;
     
    10091176                             ci.hCursor, ci.ptScreenPos.x, ci.ptScreenPos.y));
    10101177#endif
    1011     }
    1012 
    1013     if (RT_SUCCESS(rc))
    1014     {
    1015         uint32_t uDefAction = DND_IGNORE_ACTION;
    1016 
    1017         AssertPtr(pDropTarget);
    1018         RTCString strFormats = pDropTarget->Formats();
    1019         if (!strFormats.isEmpty())
    1020         {
    1021             uDefAction = DND_COPY_ACTION;
    1022             uAllActions = uDefAction;
    1023 
    1024             LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormats=%s\n",
    1025                          pDropTarget, uDefAction, uAllActions, strFormats.c_str()));
    1026             rc = VbglR3DnDGHAcknowledgePending(mClientID,
    1027                                                uDefAction, uAllActions, strFormats.c_str());
    1028         }
    1029         else
    1030             LogFlowFunc(("No format data available yet\n"));
    1031     }
    1032 
    1033     LogFlowFuncLeaveRC(rc);
    1034     return rc;
    1035 }
    1036 
    1037 int VBoxDnDWnd::OnGhDropped(const char *pszFormats, uint32_t cbFormats,
    1038                             uint32_t uDefAction)
    1039 {
    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 
    1055     int rc;
    1056     if (mState == Dragging)
    1057     {
    1058         AssertPtr(pDropTarget);
    1059         rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
    1060         if (RT_SUCCESS(rc))
    1061         {
    1062             /** @todo Respect uDefAction. */
    1063             /** @todo Do data checking / conversion based on pszFormats. */
    1064 
    1065             void *pvData = pDropTarget->DataMutableRaw();
    1066             AssertPtr(pvData);
    1067             uint32_t cbData = pDropTarget->DataSize();
    1068             Assert(cbData);
    1069 
    1070             rc = VbglR3DnDGHSendData(mClientID, pvData, cbData);
    1071             LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n",
    1072                          pvData, cbData, rc));
    1073         }
    1074 
    1075         reset();
     1178        rc = VINF_SUCCESS;
    10761179    }
    10771180    else
    1078         rc = VERR_WRONG_ORDER;
    1079 
    1080     LogFlowFuncLeaveRC(rc);
    1081     return rc;
    1082 }
    1083 
    1084 int 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 
    1092 int VBoxDnDWnd::OnGhSendFile(const char *pszFormats, uint32_t cbFormats,
    1093                              uint32_t uDefAction)
    1094 {
    1095     int rc = 0;
    1096     LogFlowFuncLeaveRC(rc);
    1097     return rc;
    1098 }
    1099 #endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    1100 
    1101 int VBoxDnDWnd::ProcessEvent(PVBOXDNDEVENT pEvent)
    1102 {
    1103     AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
    1104 
    1105     PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
    1106                 0 /* wParm */, (LPARAM)pEvent /* lParm */);
    1107 
    1108     return VINF_SUCCESS;
    1109 }
    1110 
    1111 int VBoxDnDWnd::dragRelease(void)
     1181    {
     1182        DWORD dwErr = GetLastError();
     1183        rc = RTErrConvertFromWin32(dwErr);
     1184        LogFlowFunc(("SendInput failed with rc=%Rrc\n", rc));
     1185    }
     1186
     1187    return rc;
     1188}
     1189
     1190int VBoxDnDWnd::mouseRelease(void)
    11121191{
    11131192#ifdef DEBUG_andy
    11141193    LogFlowFunc(("\n"));
    11151194#endif
     1195    int rc;
     1196
    11161197    /* Release mouse button in the guest to start the "drop"
    11171198     * action at the current mouse cursor position. */
     
    11191200    Input[0].type       = INPUT_MOUSE;
    11201201    Input[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;
    1121     SendInput(1, Input, sizeof(INPUT));
    1122 
    1123     return VINF_SUCCESS;
    1124 }
    1125 
    1126 int VBoxDnDWnd::hide(void)
    1127 {
    1128 #ifdef DEBUG_andy
    1129     LogFlowFunc(("\n"));
    1130 #endif
    1131     ShowWindow(hWnd, SW_HIDE);
    1132 
    1133     return VINF_SUCCESS;
    1134 }
    1135 
    1136 int VBoxDnDWnd::makeFullscreen(void)
    1137 {
    1138     int rc = VINF_SUCCESS;
    1139 
    1140     RECT r;
    1141     RT_ZERO(r);
    1142 
    1143     BOOL fRc;
    1144     HDC hDC = GetDC(NULL /* Entire screen */);
    1145     if (hDC)
    1146     {
    1147         fRc = EnumDisplayMonitors(hDC, NULL, VBoxDnDWnd::MonitorEnumProc,
    1148                                   (LPARAM)&r);
    1149         if (!fRc)
    1150             rc = VERR_NOT_FOUND;
    1151         ReleaseDC(NULL, hDC);
     1202    if (!s_pfnSendInput(1, Input, sizeof(INPUT)))
     1203    {
     1204        DWORD dwErr = GetLastError();
     1205        rc = RTErrConvertFromWin32(dwErr);
     1206        LogFlowFunc(("SendInput failed with rc=%Rrc\n", rc));
    11521207    }
    11531208    else
    1154         rc = VERR_ACCESS_DENIED;
    1155 
    1156     if (RT_FAILURE(rc))
    1157     {
    1158         /* If multi-monitor enumeration failed above, try getting at least the
    1159          * primary monitor as a fallback. */
    1160         MONITORINFO monitor_info;
    1161         monitor_info.cbSize = sizeof(monitor_info);
    1162         if (GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST),
    1163                            &monitor_info))
    1164         {
    1165 
    1166             r = monitor_info.rcMonitor;
    1167             rc = VINF_SUCCESS;
    1168         }
    1169     }
    1170 
    1171     if (RT_SUCCESS(rc))
    1172     {
    1173         LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
    1174         SetWindowLong(hWnd, GWL_STYLE,
    1175                       lStyle & ~(WS_CAPTION | WS_THICKFRAME));
    1176         LONG lExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
    1177         SetWindowLong(hWnd, GWL_EXSTYLE,
    1178                       lExStyle & ~(  WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE
    1179                                    | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
    1180 
    1181         fRc = SetWindowPos(hWnd, HWND_TOPMOST,
    1182                            r.left,
    1183                            r.top,
    1184                            r.right  - r.left,
    1185                            r.bottom - r.top,
    1186 #ifdef VBOX_DND_DEBUG_WND
    1187                            SWP_SHOWWINDOW | SWP_FRAMECHANGED);
    1188 #else
    1189                            SWP_SHOWWINDOW | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);
    1190 #endif
    1191         if (fRc)
    1192         {
    1193             LogFlowFunc(("Virtual screen is %ld,%ld,%ld,%ld (%ld x %ld)\n",
    1194                          r.left, r.top, r.right, r.bottom,
    1195                          r.right - r.left, r.bottom - r.top));
    1196         }
    1197         else
    1198         {
    1199             DWORD dwErr = GetLastError();
    1200             LogRel(("DnD: Failed to set proxy window position, rc=%Rrc\n",
    1201                     RTErrConvertFromWin32(dwErr)));
    1202         }
    1203     }
    1204     else
    1205         LogRel(("DnD: Failed to determine virtual screen size, rc=%Rrc\n", rc));
    1206 
    1207     LogFlowFuncLeaveRC(rc);
     1209        rc = VINF_SUCCESS;
     1210
    12081211    return rc;
    12091212}
     
    12721275
    12731276    int rc;
    1274 
    1275     /* Create the proxy window. At the moment we
    1276      * only support one window at a time. */
    1277     VBoxDnDWnd *pWnd = NULL;
    1278     try
    1279     {
    1280         pWnd = new VBoxDnDWnd();
    1281         rc = pWnd->Initialize(pCtx);
    1282 
    1283         /* Add proxy window to our proxy windows list. */
    1284         if (RT_SUCCESS(rc))
    1285             pCtx->lstWnd.append(pWnd);
    1286     }
    1287     catch (std::bad_alloc)
    1288     {
    1289         rc = VERR_NO_MEMORY;
     1277    bool fSupportedOS = true;
     1278
     1279    s_pfnSendInput = (PFNSENDINPUT)
     1280        RTLdrGetSystemSymbol("User32.dll", "SendInput");
     1281    fSupportedOS = !RT_BOOL(s_pfnSendInput == NULL);
     1282
     1283    if (!fSupportedOS)
     1284    {
     1285        LogRel(("DnD: Not supported Windows version, disabling drag'n drop support\n"));
     1286        rc = VERR_NOT_SUPPORTED;
     1287    }
     1288    else
     1289        rc = VINF_SUCCESS;
     1290
     1291    if (RT_SUCCESS(rc))
     1292    {
     1293        /* Create the proxy window. At the moment we
     1294         * only support one window at a time. */
     1295        VBoxDnDWnd *pWnd = NULL;
     1296        try
     1297        {
     1298            pWnd = new VBoxDnDWnd();
     1299            rc = pWnd->Initialize(pCtx);
     1300
     1301            /* Add proxy window to our proxy windows list. */
     1302            if (RT_SUCCESS(rc))
     1303                pCtx->lstWnd.append(pWnd);
     1304        }
     1305        catch (std::bad_alloc)
     1306        {
     1307            rc = VERR_NO_MEMORY;
     1308        }
    12901309    }
    12911310
     
    13381357
    13391358    int rc = VINF_SUCCESS;
     1359
     1360    /** @todo At the moment we only have one DnD proxy window. */
     1361    Assert(pCtx->lstWnd.size() == 1);
     1362    VBoxDnDWnd *pWnd = pCtx->lstWnd.first();
     1363    if (pWnd)
     1364        delete pWnd;
     1365
     1366    if (pCtx->hEvtQueueSem != NIL_RTSEMEVENT)
     1367        RTSemEventDestroy(pCtx->hEvtQueueSem);
    13401368
    13411369    LogFunc(("Destroyed pInstance=%p, rc=%Rrc\n",
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h

    r50305 r50399  
    174174    uint32_t mcbData;
    175175    RTSEMEVENT hEventDrop;
     176    int mDroppedRc;
    176177};
    177178
     
    338339    /* G->H */
    339340    int OnGhIsDnDPending(uint32_t uScreenID);
    340     int OnGhDropped(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
     341    int OnGhDropped(const char *pszFormat, uint32_t cbFormats, uint32_t uDefAction);
    341342    int OnGhSendDir(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
    342343    int OnGhSendFile(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
     
    351352protected:
    352353
    353     int dragRelease(void);
    354354    int makeFullscreen(void);
    355355    void reset(void);
     356    int mouseMove(int x, int y, DWORD dwMouseInputFlags);
     357    int mouseRelease(void);
    356358
    357359public: /** @todo Make protected! */
     
    386388#else
    387389    /** @todo Implement me. */
    388 #endif
     390#endif /* RT_OS_WINDOWS */
    389391
    390392    /** The window's own HGCM client ID. */
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp

    r50305 r50399  
    254254    HRESULT hr = S_OK;
    255255
    256     bool fCanDrop = false;
    257256    if (mFormatEtc.cfFormat) /* Did we get a supported format yet? */
    258257    {
     
    368367
    369368                            if (RT_FAILURE(rc))
    370                                 return rc;
     369                                break;
    371370
    372371                            char *pszFile = NULL; /* UTF-8 version. */
     
    405404                            if (RT_SUCCESS(rc))
    406405                            {
    407                                 LogFlowFunc(("\tFile: %s (%RU32 characters)\n",
     406                                LogFlowFunc(("\tFile: %s (cchFile=%RU32)\n",
    408407                                             pszFile, cchFile));
    409408
    410409                                rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
    411410                                                     pszFile, cchFile);
     411                                if (RT_SUCCESS(rc))
     412                                    cchFiles += cchFile;
    412413                            }
    413 
    414                             /* Termination. */
    415                             pszFiles[cchFiles] = '\0';
    416414
    417415                            if (pszFile)
     
    428426
    429427                            mpvData = RTMemDup(pszFiles, cbSize);
    430                             mcbData = cbSize;
     428                            if (mpvData)
     429                            {
     430                                mcbData = cbSize;
     431                            }
     432                            else
     433                                rc = VERR_NO_MEMORY;
    431434                        }
    432435
     
    440443
    441444                    default:
     445                        /* Note: Should not happen due to the checks done in DragEnter(). */
    442446                        AssertMsgFailed(("Format of type %RI16 (%s) not supported\n",
    443447                                         mFormatEtc.cfFormat,
    444448                                         VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat)));
    445                         hr = ERROR_NOT_SUPPORTED;
    446449                        hr = DV_E_CLIPFORMAT; /* Set special hr for OLE. */
    447450                        break;
    448451                }
     452
     453                /*
     454                 * Third stage: Release access to the storage medium again.
     455                 */
     456                switch (mFormatEtc.tymed)
     457                {
     458                    case TYMED_HGLOBAL:
     459                        GlobalUnlock(stgMed.hGlobal);
     460                        break;
     461
     462                    default:
     463                        AssertMsgFailed(("Really should not happen -- see init stage!\n"));
     464                        break;
     465                }
    449466            }
    450467
    451             /*
    452              * Third stage: Release access to the storage medium again.
    453              */
    454             switch (mFormatEtc.tymed)
    455             {
    456                 case TYMED_HGLOBAL:
    457                     GlobalUnlock(stgMed.hGlobal);
    458                     break;
    459 
    460                 default:
    461                     AssertMsgFailed(("Really should not happen -- see init stage!\n"));
    462                     break;
    463             }
     468            /* Signal waiters. */
     469            mDroppedRc = rc;
     470            RTSemEventSignal(hEventDrop);
    464471
    465472            /* Release storage medium again. */
    466473            ReleaseStgMedium(&stgMed);
    467 
    468             /** @todo Signal in any case to avoid hangs/timeouts? */
    469             if (RT_SUCCESS(rc))
    470             {
    471                 RTSemEventSignal(hEventDrop);
    472                 fCanDrop = true;
    473             }
    474474        }
    475475    }
    476476
    477     if (fCanDrop)
     477    if (RT_SUCCESS(rc))
    478478    {
    479479        /* Note: pt is not used since we don't need to differentiate within our
     
    487487        mpWndParent->hide();
    488488
    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));
     489    LogFlowFunc(("Returning with hr=%Rhrc (%Rrc), mFormatEtc.cfFormat=%RI16 (%s), *pdwEffect=%RI32\n",
     490                 hr, rc, mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
     491                 *pdwEffect));
    492492
    493493    return hr;
     
    546546{
    547547    LogFlowFunc(("msTimeout=%RU32\n", msTimeout));
     548
    548549    int rc = RTSemEventWait(hEventDrop, msTimeout);
     550    if (RT_SUCCESS(rc))
     551        rc = mDroppedRc;
     552
    549553    LogFlowFuncLeaveRC(rc);
    550554    return rc;
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