[SHELL32] Expose IID_CDefView in our CDefView implementation, this fixes a crash...
[reactos.git] / reactos / dll / win32 / shell32 / CDefView.cpp
index 7d77890..09cd0aa 100644 (file)
@@ -325,6 +325,7 @@ class CDefView :
         // Windows returns E_NOINTERFACE for IOleWindow
         // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
         COM_INTERFACE_ENTRY_IID(IID_IShellView, IShellView)
+        COM_INTERFACE_ENTRY_IID(IID_CDefView, IShellView)
         COM_INTERFACE_ENTRY_IID(IID_IShellView2, IShellView2)
         COM_INTERFACE_ENTRY_IID(IID_IFolderView, IFolderView)
         COM_INTERFACE_ENTRY_IID(IID_IShellFolderView, IShellFolderView)
@@ -1740,6 +1741,8 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
 
                 if (SUCCEEDED(m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &pda))))
                 {
+                    LPNMLISTVIEW params = (LPNMLISTVIEW)lParam;
+
                     if (SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &dwAttributes)))
                     {
                         if (dwAttributes & SFGAO_CANLINK)
@@ -1757,9 +1760,18 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
                     DWORD dwEffect2;
 
                     m_pSourceDataObject = pda;
-                    m_ptFirstMousePos = ((LPNMLISTVIEW)lParam)->ptAction;
+                    m_ptFirstMousePos = params->ptAction;
                     ClientToScreen(&m_ptFirstMousePos);
 
+                    HIMAGELIST big_icons, small_icons;
+                    Shell_GetImageLists(&big_icons, &small_icons);
+                    PCUITEMID_CHILD pidl = _PidlByItem(params->iItem);
+                    int iIcon = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0);
+                    POINT ptItem;
+                    m_ListView.GetItemPosition(params->iItem, &ptItem);
+
+                    ImageList_BeginDrag(big_icons, iIcon, params->ptAction.x - ptItem.x, params->ptAction.y - ptItem.y);
+
                     DoDragDrop(pda, this, dwEffect, &dwEffect2);
 
                     m_pSourceDataObject.Release();
@@ -2828,7 +2840,7 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf
 
     /* 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};
+    LVHITTESTINFO htinfo = {{pt.x, pt.y}, LVHT_ONITEM};
     ScreenToClient(&htinfo.pt);
     lResult = m_ListView.HitTest(&htinfo);
 
@@ -2913,17 +2925,18 @@ HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEf
 
     /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
     if (FAILED(hr))
+    {
+        *pdwEffect = DROPEFFECT_NONE;
         return hr;
+    }
 
-    /* Notify the item just entered via DragEnter. */
-    hr = m_pCurDropTarget->DragEnter(m_pCurDataObject, grfKeyState, pt, pdwEffect);
-
-    if (m_iDragOverItem != -1 && pdwEffect != DROPEFFECT_NONE)
+    if (m_iDragOverItem != -1)
     {
         SelectItem(m_iDragOverItem, SVSI_SELECT);
     }
 
-    return hr;
+    /* Notify the item just entered via DragEnter. */
+    return m_pCurDropTarget->DragEnter(m_pCurDataObject, grfKeyState, pt, pdwEffect);
 }
 
 HRESULT WINAPI CDefView::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
@@ -2931,16 +2944,29 @@ HRESULT WINAPI CDefView::DragEnter(IDataObject *pDataObject, DWORD grfKeyState,
     /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
     m_pCurDataObject = pDataObject;
 
-    return drag_notify_subitem(grfKeyState, pt, pdwEffect);
+    HRESULT hr = drag_notify_subitem(grfKeyState, pt, pdwEffect);    
+    if (SUCCEEDED(hr))
+    {
+        POINT ptClient = {pt.x, pt.y};
+        ScreenToClient(&ptClient);
+        ImageList_DragEnter(m_hWnd, ptClient.x, ptClient.y);
+    }
+
+    return hr;
 }
 
 HRESULT WINAPI CDefView::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
 {
+    POINT ptClient = {pt.x, pt.y};
+    ScreenToClient(&ptClient);
+    ImageList_DragMove(ptClient.x, ptClient.y);
     return drag_notify_subitem(grfKeyState, pt, pdwEffect);
 }
 
 HRESULT WINAPI CDefView::DragLeave()
 {
+    ImageList_DragLeave(m_hWnd);
+
     if (m_pCurDropTarget)
     {
         m_pCurDropTarget->DragLeave();
@@ -2961,6 +2987,9 @@ HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINT
 {
     ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON));
 
+    ImageList_DragLeave(m_hWnd);
+    ImageList_EndDrag();
+
     if ((m_iDragOverItem == -1 || m_pCurDropTarget == NULL) && 
         (*pdwEffect & DROPEFFECT_MOVE) && 
         /*(GetKeyState(VK_LBUTTON) != 0) &&*/
@@ -3129,7 +3158,7 @@ HRESULT CDefView::_MergeToolbar()
  */
 HRESULT WINAPI IShellView_Constructor(IShellFolder *pFolder, IShellView **newView)
 {
-    return ShellObjectCreatorInit<CDefView>(pFolder, IID_IShellView, newView);
+    return ShellObjectCreatorInit<CDefView>(pFolder, IID_PPV_ARG(IShellView, newView));
 }
 
 HRESULT WINAPI CDefView_Constructor(IShellFolder *pFolder, REFIID riid, LPVOID * ppvOut)