https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8f8ab050db7fde50f09995f63d580f70645bece8

commit 8f8ab050db7fde50f09995f63d580f70645bece8
Author:     Giannis Adamopoulos <[email protected]>
AuthorDate: Sat Feb 17 19:29:20 2018 +0200
Commit:     Giannis Adamopoulos <[email protected]>
CommitDate: Sat Feb 17 20:30:37 2018 +0200

    [SHELL32] CDefView: Implement several methods needed for drop targets
    Set the view object as the site of the drop target.
    Implement GetItemPosition, SelectAndPositionItems, IsDropOnSource, 
GetDragPoint.
    Use DROPEFFECT_COPY only when the item supports it.
---
 dll/win32/shell32/CDefView.cpp | 62 +++++++++++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 16 deletions(-)

diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp
index c3d37e5c0e..280be9606a 100644
--- a/dll/win32/shell32/CDefView.cpp
+++ b/dll/win32/shell32/CDefView.cpp
@@ -101,6 +101,7 @@ class CDefView :
         UINT                      m_cScrollDelay;       /* Send a WM_*SCROLL 
msg every 250 ms during drag-scroll */
         POINT                     m_ptLastMousePos;     /* Mouse position at 
last DragOver call */
         POINT                     m_ptFirstMousePos;    /* Mouse position when 
the drag operation started */
+        DWORD                     m_grfKeyState;
         //
         CComPtr<IContextMenu>     m_pCM;
 
@@ -1765,8 +1766,8 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, 
LPARAM lParam, BOOL &bHandl
             if (GetSelections())
             {
                 CComPtr<IDataObject> pda;
-                DWORD dwAttributes = SFGAO_CANLINK;
-                DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
+                DWORD dwAttributes = SFGAO_CANCOPY | SFGAO_CANLINK;
+                DWORD dwEffect = DROPEFFECT_MOVE;
 
                 if (SUCCEEDED(m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, 
m_apidl, IID_NULL_PPV_ARG(IDataObject, &pda))))
                 {
@@ -1774,10 +1775,7 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, 
LPARAM lParam, BOOL &bHandl
 
                     if (SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, 
m_apidl, &dwAttributes)))
                     {
-                        if (dwAttributes & SFGAO_CANLINK)
-                        {
-                            dwEffect |= DROPEFFECT_LINK;
-                        }
+                        dwEffect |= dwAttributes & (SFGAO_CANCOPY | 
SFGAO_CANLINK);
                     }
                     
                     CComPtr<IAsyncOperation> piaso;
@@ -2423,7 +2421,12 @@ HRESULT STDMETHODCALLTYPE CDefView::GetFocusedItem(int 
*piItem)
 
 HRESULT STDMETHODCALLTYPE CDefView::GetItemPosition(PCUITEMID_CHILD pidl, 
POINT *ppt)
 {
-    return E_NOTIMPL;
+    int lvIndex = LV_FindItemByPidl(pidl);
+    if (lvIndex == -1 || ppt == NULL)
+        return E_INVALIDARG;
+
+    m_ListView.GetItemPosition(lvIndex, ppt);
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CDefView::GetSpacing(POINT *ppt)
@@ -2488,7 +2491,21 @@ HRESULT STDMETHODCALLTYPE CDefView::SelectItem(int 
iItem, DWORD dwFlags)
 
 HRESULT STDMETHODCALLTYPE CDefView::SelectAndPositionItems(UINT cidl, 
PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD dwFlags)
 {
-    return E_NOTIMPL;
+    /* Reset the selection */
+    m_ListView.SetItemState(-1, 0, LVIS_SELECTED);
+
+    int lvIndex;
+    for (UINT i = 0 ; i < m_cidl; i++)
+    {
+        lvIndex = LV_FindItemByPidl(apidl[i]);
+        if (lvIndex != -1)
+        {
+            SelectItem(lvIndex, dwFlags);
+            m_ListView.SetItemPosition(lvIndex, &apt[i]);
+        }
+    }
+
+    return S_OK;
 }
 
 /**********************************************************
@@ -2717,14 +2734,22 @@ HRESULT STDMETHODCALLTYPE 
CDefView::GetSelectedObjects(PCUITEMID_CHILD **pidl, U
 
 HRESULT STDMETHODCALLTYPE CDefView::IsDropOnSource(IDropTarget *drop_target)
 {
-    FIXME("(%p)->(%p) stub\n", this, drop_target);
-    return E_NOTIMPL;
+    if ((m_iDragOverItem == -1 || m_pCurDropTarget == NULL) && 
+        (m_pSourceDataObject.p))
+    {
+        return S_OK;
+    }
+
+    return S_FALSE;
 }
 
 HRESULT STDMETHODCALLTYPE CDefView::GetDragPoint(POINT *pt)
 {
-    FIXME("(%p)->(%p) stub\n", this, pt);
-    return E_NOTIMPL;
+    if (!pt)
+        return E_INVALIDARG;
+
+    *pt = m_ptFirstMousePos;
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CDefView::GetDropPoint(POINT *pt)
@@ -2887,6 +2912,11 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, 
POINTL pt, DWORD *pdwEf
     HRESULT hr;
     RECT clientRect;
 
+    /* The key state on drop doesn't have MK_LBUTTON or MK_RBUTTON because it
+       reflects the key state after the user released the button, so we need
+       to remember the last key state when the button was pressed */
+    m_grfKeyState = grfKeyState;
+
     /* Map from global to client coordinates and query the index of the 
listview-item, which is
      * currently under the mouse cursor. */
     LVHITTESTINFO htinfo = {{pt.x, pt.y}, LVHT_ONITEM};
@@ -2972,6 +3002,8 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, 
POINTL pt, DWORD *pdwEf
         hr = m_pSFParent->GetUIObjectOf(m_ListView, 1, &pidl, 
IID_NULL_PPV_ARG(IDropTarget, &m_pCurDropTarget));
     }
 
+    IUnknown_SetSite(m_pCurDropTarget, (IShellView *)this);
+
     /* If anything failed, m_pCurDropTarget should be NULL now, which ought to 
be a save state. */
     if (FAILED(hr))
     {
@@ -3039,11 +3071,9 @@ HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, 
DWORD grfKeyState, POINT
     ImageList_DragLeave(m_hWnd);
     ImageList_EndDrag();
 
-    if ((m_iDragOverItem == -1 || m_pCurDropTarget == NULL) && 
+    if ((IsDropOnSource(NULL) == S_OK) && 
         (*pdwEffect & DROPEFFECT_MOVE) && 
-        /*(GetKeyState(VK_LBUTTON) != 0) &&*/
-        (m_pSourceDataObject.p) && 
-        (SHIsSameObject(pDataObject, m_pSourceDataObject)))
+        (m_grfKeyState & MK_LBUTTON))
     {
         if (m_pCurDropTarget)
         {

Reply via email to