https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8f8ab050db7fde50f09995...
commit 8f8ab050db7fde50f09995f63d580f70645bece8 Author: Giannis Adamopoulos gadamopoulos@reactos.org AuthorDate: Sat Feb 17 19:29:20 2018 +0200 Commit: Giannis Adamopoulos gadamopoulos@reactos.org 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) {