https://git.reactos.org/?p=reactos.git;a=commitdiff;h=332ca5f5727945d14d8b7…
commit 332ca5f5727945d14d8b780d8cb7c0886a01688b
Author:     Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Fri Mar 15 22:31:13 2019 +0900
Commit:     GitHub <noreply(a)github.com>
CommitDate: Fri Mar 15 22:31:13 2019 +0900
    [OLE32] Implement WS_EX_ACCEPTFILES (#1403)
    The window that has WS_EX_ACCEPTFILES extended style, should pretend like a drop
target that accepts CF_HDROP data. CORE-11238
---
 dll/win32/ole32/ole2.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 143 insertions(+)
diff --git a/dll/win32/ole32/ole2.c b/dll/win32/ole32/ole2.c
index 2de9edbb80..f145982995 100644
--- a/dll/win32/ole32/ole2.c
+++ b/dll/win32/ole32/ole2.c
@@ -70,6 +70,9 @@ typedef struct tagTrackerWindowInfo
   BOOL       escPressed;
   HWND       curTargetHWND;    /* window the mouse is hovering over */
   IDropTarget* curDragTarget;
+#ifdef __REACTOS__
+  HWND       accepterHWND;
+#endif
   POINTL     curMousePos;       /* current position of the mouse in screen coordinates */
   DWORD      dwKeyState;        /* current state of the shift and ctrl keys and the mouse
buttons */
 } TrackerWindowInfo;
@@ -293,6 +296,12 @@ static inline BOOL is_droptarget(HWND hwnd)
     return get_droptarget_handle(hwnd) != 0;
 }
+#ifdef __REACTOS__
+static inline BOOL is_acceptfiles(HWND hwnd)
+{
+    return !!(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES);
+}
+#endif
 /*************************************************************
  *           get_droptarget_local_handle
  *
@@ -772,6 +781,9 @@ HRESULT WINAPI DoDragDrop (
   trackerInfo.escPressed        = FALSE;
   trackerInfo.curTargetHWND     = 0;
   trackerInfo.curDragTarget     = 0;
+#ifdef __REACTOS__
+  trackerInfo.accepterHWND      = NULL;
+#endif
   hwndTrackWindow = CreateWindowW(OLEDD_DRAGTRACKERCLASS, trackerW,
                                   WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
@@ -2182,14 +2194,107 @@ static LRESULT WINAPI OLEDD_DragTrackerWindowProc(
   return DefWindowProcW (hwnd, uMsg, wParam, lParam);
 }
+#ifdef __REACTOS__
+static HRESULT WINAPI DefaultDragEnter(HWND hwndTarget,
+                                       IDataObject* pDataObj,
+                                       DWORD grfKeyState,
+                                       POINTL pt,
+                                       DWORD* pdwEffect)
+{
+    HRESULT hr;
+    FORMATETC fme;
+
+    ZeroMemory(&fme, sizeof(fme));
+    fme.cfFormat = CF_HDROP;
+    fme.ptd = NULL;
+    fme.dwAspect = DVASPECT_CONTENT;
+    fme.lindex = -1;
+    fme.tymed = TYMED_HGLOBAL;
+    hr = pDataObj->lpVtbl->QueryGetData(pDataObj, &fme);
+
+    *pdwEffect = SUCCEEDED(hr) ? DROPEFFECT_COPY : DROPEFFECT_NONE;
+
+    if (*pdwEffect == DROPEFFECT_NONE)
+        return DRAGDROP_S_CANCEL;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI DefaultDrop(HWND hwndAccepter,
+                                  IDataObject* pDataObj,
+                                  DWORD grfKeyState,
+                                  POINTL pt,
+                                  DWORD* pdwEffect)
+{
+    FORMATETC fme;
+    STGMEDIUM stgm;
+    HRESULT hr;
+    HGLOBAL hGlobal = NULL;
+
+    ZeroMemory(&fme, sizeof(fme));
+    fme.cfFormat = CF_HDROP;
+    fme.ptd = NULL;
+    fme.dwAspect = DVASPECT_CONTENT;
+    fme.lindex = -1;
+    fme.tymed = TYMED_HGLOBAL;
+    hr = pDataObj->lpVtbl->QueryGetData(pDataObj, &fme);
+    if (FAILED(hr))
+        return hr;
+
+    ZeroMemory(&stgm, sizeof(stgm));
+    hr = pDataObj->lpVtbl->GetData(pDataObj, &fme, &stgm);
+    if (SUCCEEDED(hr))
+    {
+        hGlobal = stgm.DUMMYUNIONNAME.hGlobal;
+        if (hGlobal)
+        {
+            if (IsWindowUnicode(hwndAccepter))
+                PostMessageW(hwndAccepter, WM_DROPFILES, (WPARAM)hGlobal, 0);
+            else
+                PostMessageA(hwndAccepter, WM_DROPFILES, (WPARAM)hGlobal, 0);
+        }
+        ReleaseStgMedium(&stgm);
+    }
+
+    return hr;
+}
+#endif
+
 static void drag_enter( TrackerWindowInfo *info, HWND new_target )
 {
     HRESULT hr;
+#ifdef __REACTOS__
+    DWORD dwEffect = *info->pdwEffect;
+#endif
     info->curTargetHWND = new_target;
+#ifdef __REACTOS__
+    info->accepterHWND = NULL;
+    while (new_target && !is_droptarget( new_target ))
+    {
+        if (is_acceptfiles(new_target))
+        {
+            dwEffect = info->dwOKEffect;
+            hr = DefaultDragEnter(new_target, info->dataObject,
+                                  info->dwKeyState, info->curMousePos,
+                                  &dwEffect);
+            dwEffect &= info->dwOKEffect;
+
+            if (hr == S_OK)
+            {
+                info->accepterHWND = new_target;
+                info->curDragTarget = NULL;
+                *info->pdwEffect = dwEffect;
+                return;
+            }
+        }
+        new_target = GetParent( new_target );
+    }
+#else
     while (new_target && !is_droptarget( new_target ))
         new_target = GetParent( new_target );
+#endif
     info->curDragTarget = get_droptarget_pointer( new_target );
@@ -2207,6 +2312,9 @@ static void drag_enter( TrackerWindowInfo *info, HWND new_target )
             IDropTarget_Release( info->curDragTarget );
             info->curDragTarget = NULL;
             info->curTargetHWND = NULL;
+#ifdef __REACTOS__
+            info->accepterHWND = NULL;
+#endif
         }
     }
 }
@@ -2239,6 +2347,27 @@ static void drag_end( TrackerWindowInfo *info )
         IDropTarget_Release( info->curDragTarget );
         info->curDragTarget = NULL;
     }
+#ifdef __REACTOS__
+    else if (info->accepterHWND)
+    {
+        if (info->returnValue == DRAGDROP_S_DROP &&
+            *info->pdwEffect != DROPEFFECT_NONE)
+        {
+            *info->pdwEffect = info->dwOKEffect;
+            hr = DefaultDrop(info->accepterHWND, info->dataObject,
info->dwKeyState,
+                             info->curMousePos, info->pdwEffect);
+            *info->pdwEffect &= info->dwOKEffect;
+
+            if (FAILED( hr ))
+                info->returnValue = hr;
+        }
+        else
+        {
+            *info->pdwEffect = DROPEFFECT_NONE;
+        }
+        info->accepterHWND = NULL;
+    }
+#endif
     else
         *info->pdwEffect = DROPEFFECT_NONE;
 }
@@ -2249,8 +2378,13 @@ static HRESULT give_feedback( TrackerWindowInfo *info )
     int res;
     HCURSOR cur;
+#ifdef __REACTOS__
+    if (info->curDragTarget == NULL && info->accepterHWND == NULL)
+        *info->pdwEffect = DROPEFFECT_NONE;
+#else
     if (info->curDragTarget == NULL)
         *info->pdwEffect = DROPEFFECT_NONE;
+#endif
     hr = IDropSource_GiveFeedback( info->dropSource, *info->pdwEffect );
@@ -2309,6 +2443,9 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
       trackerInfo->curDragTarget = NULL;
       trackerInfo->curTargetHWND = NULL;
     }
+#ifdef __REACTOS__
+    trackerInfo->accepterHWND = NULL;
+#endif
     if (hwndNewTarget)
       drag_enter( trackerInfo, hwndNewTarget );
@@ -2328,6 +2465,12 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
                            trackerInfo->pdwEffect);
       *trackerInfo->pdwEffect &= trackerInfo->dwOKEffect;
     }
+#ifdef __REACTOS__
+    else if (trackerInfo->accepterHWND)
+    {
+      *trackerInfo->pdwEffect = trackerInfo->dwOKEffect;
+    }
+#endif
     give_feedback( trackerInfo );
   }
   else