[SHELL32]
[reactos.git] / dll / win32 / shell32 / folders / desktop.cpp
index 968bc35..4311e12 100644 (file)
@@ -300,7 +300,7 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
     LPBC pbc,
     LPOLESTR lpszDisplayName,
     DWORD *pchEaten,
-    LPITEMIDLIST *ppidl,
+    PIDLIST_RELATIVE *ppidl,
     DWORD *pdwAttributes)
 {
     WCHAR szElement[MAX_PATH];
@@ -421,48 +421,16 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
 /**************************************************************************
  *        CDesktopFolder::EnumObjects
  */
-HRESULT WINAPI CDesktopFolder::EnumObjects(
-    HWND hwndOwner,
-    DWORD dwFlags,
-    LPENUMIDLIST *ppEnumIDList)
+HRESULT WINAPI CDesktopFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
 {
-    CComObject<CDesktopFolderEnum>            *theEnumerator;
-    CComPtr<IEnumIDList>                    result;
-    HRESULT                                    hResult;
-
-    TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner, dwFlags, ppEnumIDList);
-
-    if (ppEnumIDList == NULL)
-        return E_POINTER;
-    *ppEnumIDList = NULL;
-
-    ATLTRY (theEnumerator = new CComObject<CDesktopFolderEnum>);
-
-    if (theEnumerator == NULL)
-        return E_OUTOFMEMORY;
-
-    hResult = theEnumerator->QueryInterface(IID_PPV_ARG(IEnumIDList, &result));
-    if (FAILED (hResult))
-    {
-        delete theEnumerator;
-        return hResult;
-    }
-
-    hResult = theEnumerator->Initialize (this, hwndOwner, dwFlags);
-    if (FAILED (hResult))
-        return hResult;
-    *ppEnumIDList = result.Detach ();
-
-    TRACE ("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList);
-
-    return S_OK;
+    return ShellObjectCreatorInit<CDesktopFolderEnum>(this, hwndOwner, dwFlags, IID_IEnumIDList, ppEnumIDList);
 }
 
 /**************************************************************************
  *        CDesktopFolder::BindToObject
  */
 HRESULT WINAPI CDesktopFolder::BindToObject(
-    LPCITEMIDLIST pidl,
+    PCUIDLIST_RELATIVE pidl,
     LPBC pbcReserved,
     REFIID riid,
     LPVOID *ppvOut)
@@ -477,7 +445,7 @@ HRESULT WINAPI CDesktopFolder::BindToObject(
  *    CDesktopFolder::BindToStorage
  */
 HRESULT WINAPI CDesktopFolder::BindToStorage(
-    LPCITEMIDLIST pidl,
+    PCUIDLIST_RELATIVE pidl,
     LPBC pbcReserved,
     REFIID riid,
     LPVOID *ppvOut)
@@ -492,7 +460,7 @@ HRESULT WINAPI CDesktopFolder::BindToStorage(
 /**************************************************************************
  *     CDesktopFolder::CompareIDs
  */
-HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
 {
     int nReturn;
 
@@ -545,7 +513,7 @@ HRESULT WINAPI CDesktopFolder::CreateViewObject(
  */
 HRESULT WINAPI CDesktopFolder::GetAttributesOf(
     UINT cidl,
-    LPCITEMIDLIST *apidl,
+    PCUITEMID_CHILD_ARRAY apidl,
     DWORD *rgfInOut)
 {
     HRESULT hr = S_OK;
@@ -609,7 +577,7 @@ HRESULT WINAPI CDesktopFolder::GetAttributesOf(
 HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
     HWND hwndOwner,
     UINT cidl,
-    LPCITEMIDLIST *apidl,
+    PCUITEMID_CHILD_ARRAY apidl,
     REFIID riid,
     UINT *prgfInOut,
     LPVOID *ppvOut)
@@ -637,23 +605,26 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
     else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1))
     {
         pidl = ILCombine (pidlRoot, apidl[0]);
-        pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
+        pObj = IExtractIconA_Constructor (pidl);
         SHFree (pidl);
         hr = S_OK;
     }
     else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1))
     {
         pidl = ILCombine (pidlRoot, apidl[0]);
-        pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
+        pObj = IExtractIconW_Constructor (pidl);
         SHFree (pidl);
         hr = S_OK;
     }
     else if (IsEqualIID (riid, IID_IDropTarget))
     {
         /* only interested in attempting to bind to shell folders, not files, semicolon intentionate */
-        if (cidl == 1 && SUCCEEDED(this->BindToObject(apidl[0], NULL, IID_IDropTarget, (LPVOID*)&pObj)));
-        else
-            hr = this->QueryInterface(IID_IDropTarget, (LPVOID*)&pObj);
+        if (cidl != 1 || FAILED(hr = this->_GetDropTarget(apidl[0], (LPVOID*) &pObj)))
+        {
+            IDropTarget * pDt = NULL;
+            hr = this->QueryInterface(IID_PPV_ARG(IDropTarget, &pDt));
+            pObj = pDt;
+        }
     }
     else if ((IsEqualIID(riid, IID_IShellLinkW) ||
               IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1))
@@ -679,7 +650,7 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
  * NOTES
  *    special case: pidl = null gives desktop-name back
  */
-HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
+HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
 {
     HRESULT hr = S_OK;
     LPWSTR pszPath;
@@ -708,7 +679,7 @@ HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlag
 
         if ((clsid = _ILGetGUIDPointer (pidl)))
         {
-            if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)
+            if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
             {
                 int bWantsForParsing;
 
@@ -854,10 +825,10 @@ HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlag
  */
 HRESULT WINAPI CDesktopFolder::SetNameOf(
     HWND hwndOwner,
-    LPCITEMIDLIST pidl,    /* simple pidl */
+    PCUITEMID_CHILD pidl,    /* simple pidl */
     LPCOLESTR lpName,
     DWORD dwFlags,
-    LPITEMIDLIST *pPidlOut)
+    PITEMID_CHILD *pPidlOut)
 {
     CComPtr<IShellFolder2>                psf;
     HRESULT hr;
@@ -963,7 +934,7 @@ HRESULT WINAPI CDesktopFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFla
 }
 
 HRESULT WINAPI CDesktopFolder::GetDetailsEx(
-    LPCITEMIDLIST pidl,
+    PCUITEMID_CHILD pidl,
     const SHCOLUMNID *pscid,
     VARIANT *pv)
 {
@@ -973,7 +944,7 @@ HRESULT WINAPI CDesktopFolder::GetDetailsEx(
 }
 
 HRESULT WINAPI CDesktopFolder::GetDetailsOf(
-    LPCITEMIDLIST pidl,
+    PCUITEMID_CHILD pidl,
     UINT iColumn,
     SHELLDETAILS *psd)
 {
@@ -1451,7 +1422,7 @@ HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject,
     else
     {
         InitFormatEtc (formatetc, CF_HDROP, TYMED_HGLOBAL);
-        if SUCCEEDED(pDataObject->QueryGetData(&formatetc));
+        if (SUCCEEDED(pDataObject->QueryGetData(&formatetc)))
         {
             passthroughtofs = TRUE;
         }
@@ -1473,8 +1444,8 @@ HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject,
 
         if (SUCCEEDED(hr))
         {
-            IDropTarget *pDT;
-            hr = this->BindToObject(pidl, NULL, IID_IDropTarget, (LPVOID*)&pDT);
+            CComPtr<IDropTarget> pDT;
+            hr = this->BindToObject(pidl, NULL, IID_PPV_ARG(IDropTarget, &pDT));
             CoTaskMemFree(pidl);
             if (SUCCEEDED(hr))
                 SHSimulateDrop(pDT, pDataObject, dwKeyState, NULL, pdwEffect);
@@ -1488,4 +1459,52 @@ HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject,
     /* Todo, rewrite the registry such that the icons are well placed.
     Blocked by no bags implementation. */
     return hr;
+}
+
+HRESULT WINAPI CDesktopFolder::_GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut) {
+    HRESULT hr;
+
+    TRACE("CFSFolder::_GetDropTarget entered\n");
+
+    if (_ILGetGUIDPointer (pidl) || _ILIsFolder (pidl))
+        return this->BindToObject(pidl, NULL, IID_IDropTarget, ppvOut);
+
+    LPITEMIDLIST pidlNext = NULL;
+
+    STRRET strFile;
+    hr = this->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strFile);
+    if (SUCCEEDED(hr))
+    {
+        WCHAR wszPath[MAX_PATH];
+        hr = StrRetToBufW(&strFile, pidl, wszPath, _countof(wszPath));
+
+        if (SUCCEEDED(hr))
+        {
+            PathRemoveFileSpecW (wszPath);
+            hr = this->ParseDisplayName(NULL, NULL, wszPath, NULL, &pidlNext, NULL);
+
+            if (SUCCEEDED(hr))
+            {
+                CComPtr<IShellFolder> psf;
+                hr = this->BindToObject(pidlNext, NULL, IID_PPV_ARG(IShellFolder, &psf));
+                CoTaskMemFree(pidlNext);
+                if (SUCCEEDED(hr))
+                {
+                    hr = psf->GetUIObjectOf(NULL, 1, &pidl, IID_IDropTarget, NULL, ppvOut);
+                    if (FAILED(hr))
+                        ERR("FS GetUIObjectOf failed: %x\n", hr);
+                }
+                else 
+                    ERR("BindToObject failed: %x\n", hr);
+            }
+            else
+                ERR("ParseDisplayName failed: %x\n", hr);
+        }
+        else
+            ERR("StrRetToBufW failed: %x\n", hr);
+    }    
+    else
+        ERR("GetDisplayNameOf failed: %x\n", hr);
+
+    return hr;
 }
\ No newline at end of file