Author: dquintana
Date: Sat Jun 28 15:38:25 2014
New Revision: 63658

URL: http://svn.reactos.org/svn/reactos?rev=63658&view=rev
Log:
[RSHELL]
* Implement a rudimentary but mostly functional (for start menu purposes) 
CMergedFolder class. It's still disabled by default because clicking on an item 
in a merged folder appears to fail to execute it.

Modified:
    branches/shell-experiments/base/shell/rshell/CMakeLists.txt
    branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp
    branches/shell-experiments/base/shell/rshell/CMergedFolder.cpp
    branches/shell-experiments/base/shell/rshell/CMergedFolder.h
    branches/shell-experiments/include/psdk/commctrl.h

Modified: branches/shell-experiments/base/shell/rshell/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rshell/CMakeLists.txt?rev=63658&r1=63657&r2=63658&view=diff
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMakeLists.txt [iso-8859-1] 
(original)
+++ branches/shell-experiments/base/shell/rshell/CMakeLists.txt [iso-8859-1] 
Sat Jun 28 15:38:25 2014
@@ -31,6 +31,7 @@
     uxtheme
     shlwapi
     shell32
+    comctl32
     gdi32
     ole32
     user32

Modified: branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp?rev=63658&r1=63657&r2=63658&view=diff
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp      
[iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CMenuToolbars.cpp      
[iso-8859-1] Sat Jun 28 15:38:25 2014
@@ -1260,10 +1260,9 @@
     IEnumIDList * eidl;
     m_shellFolder->EnumObjects(GetToolbar(), SHCONTF_FOLDERS | 
SHCONTF_NONFOLDERS, &eidl);
 
-    LPITEMIDLIST item = 
static_cast<LPITEMIDLIST>(CoTaskMemAlloc(sizeof(ITEMIDLIST)));
-    ULONG fetched;
-    hr = eidl->Next(1, &item, &fetched);
-    while (SUCCEEDED(hr) && fetched > 0)
+    LPITEMIDLIST item = { 0 };
+    hr = eidl->Next(1, &item, NULL);
+    while (hr == S_OK)
     {
         INT index = 0;
         INT indexOpen = 0;
@@ -1286,13 +1285,13 @@
         DWORD_PTR dwData = reinterpret_cast<DWORD_PTR>(ILClone(item));
 
         // Fetch next item already, so we know if the current one is the last
-        hr = eidl->Next(1, &item, &fetched);
-
-        AddButton(++i, MenuString, attrs & SFGAO_FOLDER, index, dwData, 
FAILED(hr) || fetched == 0);
+        hr = eidl->Next(1, &item, NULL);
+
+        AddButton(++i, MenuString, attrs & SFGAO_FOLDER, index, dwData, hr != 
S_OK);
 
         CoTaskMemFree(MenuString);
     }
-    CoTaskMemFree(item);
+    ILFree(item);
 
     // If no items were added, show the "empty" placeholder
     if (i == 0)

Modified: branches/shell-experiments/base/shell/rshell/CMergedFolder.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rshell/CMergedFolder.cpp?rev=63658&r1=63657&r2=63658&view=diff
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMergedFolder.cpp      
[iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CMergedFolder.cpp      
[iso-8859-1] Sat Jun 28 15:38:25 2014
@@ -25,18 +25,33 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(CMergedFolder);
 
+struct LocalPidlInfo
+{
+    int side; // -1 local, 0 shared, 1 common
+    LPITEMIDLIST pidl;
+};
+
 class CEnumMergedFolder :
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IEnumIDList
 {
+
 private:
+    CComPtr<IShellFolder> m_UserLocalFolder;
+    CComPtr<IShellFolder> m_AllUSersFolder;
     CComPtr<IEnumIDList> m_UserLocal;
     CComPtr<IEnumIDList> m_AllUSers;
-    BOOL m_FirstDone;
+
+    HWND m_HwndOwner;
+    SHCONTF m_Flags;
+
+    HDSA m_hDsa;
+    UINT m_hDsaIndex;
+    UINT m_hDsaCount;
 
 public:
-    CEnumMergedFolder() : m_UserLocal(NULL), m_AllUSers(NULL), 
m_FirstDone(FALSE) {}
-    virtual ~CEnumMergedFolder() {}
+    CEnumMergedFolder();
+    virtual ~CEnumMergedFolder();
 
     DECLARE_NOT_AGGREGATABLE(CEnumMergedFolder)
     DECLARE_PROTECT_FINAL_CONSTRUCT()
@@ -45,83 +60,345 @@
         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
     END_COM_MAP()
 
-    HRESULT Begin(HWND hwndOwner, SHCONTF flags, IShellFolder * userLocal, 
IShellFolder * allUSers)
-    {
-        HRESULT hr;
-        hr = userLocal->EnumObjects(hwndOwner, flags, &m_UserLocal);
-        if (FAILED_UNEXPECTEDLY(hr))
-            return hr;
-        hr = userLocal->EnumObjects(hwndOwner, flags, &m_AllUSers);
-        if (FAILED_UNEXPECTEDLY(hr))
-        {
-            m_UserLocal = NULL;
-            return hr;
-        }
-        m_FirstDone = FALSE;
-        return S_OK;
-    }
+    int  DsaDeleteCallback(LocalPidlInfo * info);
+
+    static int CALLBACK s_DsaDeleteCallback(void *pItem, void *pData);
+
+    HRESULT SetSources(IShellFolder * userLocal, IShellFolder * allUSers);
+    HRESULT Begin(HWND hwndOwner, SHCONTF flags);
+    HRESULT FindPidlInList(LPCITEMIDLIST pcidl, LocalPidlInfo * pinfo);
 
     virtual HRESULT STDMETHODCALLTYPE Next(
         ULONG celt,
         LPITEMIDLIST *rgelt,
-        ULONG *pceltFetched)
+        ULONG *pceltFetched);
+
+    virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt);
+    virtual HRESULT STDMETHODCALLTYPE Reset();
+    virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum);
+};
+
+CEnumMergedFolder::CEnumMergedFolder() :
+    m_UserLocalFolder(NULL),
+    m_AllUSersFolder(NULL),
+    m_UserLocal(NULL),
+    m_AllUSers(NULL),
+    m_HwndOwner(NULL),
+    m_Flags(0),
+    m_hDsaIndex(0)
+{
+    m_hDsa = DSA_Create(sizeof(LocalPidlInfo), 10);
+}
+    
+CEnumMergedFolder::~CEnumMergedFolder()
+{
+    DSA_DestroyCallback(m_hDsa, s_DsaDeleteCallback, this);
+}
+
+int  CEnumMergedFolder::DsaDeleteCallback(LocalPidlInfo * info)
+{
+    ILFree(info->pidl);
+    return 0;
+}
+    
+int CALLBACK CEnumMergedFolder::s_DsaDeleteCallback(void *pItem, void *pData)
+{
+    CEnumMergedFolder * mf = (CEnumMergedFolder*) pData;
+    LocalPidlInfo  * item = (LocalPidlInfo*) pItem;
+    return mf->DsaDeleteCallback(item);
+}
+
+HRESULT CEnumMergedFolder::SetSources(IShellFolder * userLocal, IShellFolder * 
allUSers)
+{
+    m_UserLocalFolder = userLocal;
+    m_AllUSersFolder = allUSers;
+    return S_OK;
+}
+
+HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags)
+{
+    HRESULT hr;
+
+    if (m_HwndOwner == hwndOwner && m_Flags == flags)
     {
-        HRESULT hr;
-
-        *pceltFetched = 0;
-
-        if (!m_FirstDone)
-        {
-            hr = m_UserLocal->Next(celt, rgelt, pceltFetched);
+        return Reset();
+    }
+
+    TRACE("Search conditions changed, recreating list...\n");
+
+    hr = m_UserLocalFolder->EnumObjects(hwndOwner, flags, &m_UserLocal);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+    hr = m_AllUSersFolder->EnumObjects(hwndOwner, flags, &m_AllUSers);
+    if (FAILED_UNEXPECTEDLY(hr))
+    {
+        m_UserLocal = NULL;
+        return hr;
+    }
+
+    DSA_EnumCallback(m_hDsa, s_DsaDeleteCallback, this);
+    DSA_DeleteAllItems(m_hDsa);
+    m_hDsaCount = 0;
+
+    HRESULT hr1 = S_OK;
+    HRESULT hr2 = S_OK;
+    LPITEMIDLIST pidl1 = NULL;
+    LPITEMIDLIST pidl2 = NULL;
+    int order = 0;
+    do
+    {
+        if (order <= 0)
+        {
+            if (hr1 == S_OK)
+            {
+                hr1 = m_UserLocal->Next(1, &pidl1, NULL);
+                if (FAILED_UNEXPECTEDLY(hr1))
+                    return hr1;
+            }
+            else
+            {
+                pidl1 = NULL;
+            }
+        }
+        if (order >= 0)
+        {
+            if (hr2 == S_OK)
+            {
+                hr2 = m_AllUSers->Next(1, &pidl2, NULL);
+                if (FAILED_UNEXPECTEDLY(hr2))
+                    return hr2;
+            }
+            else
+            {
+                pidl2 = NULL;
+            }
+        }
+
+        if (hr1 == S_OK && hr2 == S_OK)
+        {
+            LPWSTR name1;
+            LPWSTR name2;
+            STRRET str1 = { STRRET_WSTR };
+            STRRET str2 = { STRRET_WSTR };
+            hr = m_UserLocalFolder->GetDisplayNameOf(pidl1, SHGDN_FORPARSING | 
SHGDN_INFOLDER, &str1);
+            if (FAILED(hr))
+                return hr;
+            hr = m_AllUSersFolder->GetDisplayNameOf(pidl2, SHGDN_FORPARSING | 
SHGDN_INFOLDER, &str2);
+            if (FAILED(hr))
+                return hr;
+            StrRetToStrW(&str1, pidl1, &name1);
+            StrRetToStrW(&str2, pidl2, &name2);
+            order = StrCmpW(name1, name2);
+            CoTaskMemFree(name1);
+            CoTaskMemFree(name2);
+        }
+        else if (hr1 == S_OK)
+        {
+            order = -1;
+        }
+        else if (hr2 == S_OK)
+        {
+            order = 1;
+        }
+        else
+        {
+            break;
+        }
+
+        LocalPidlInfo info;
+        if (order < 0)
+        {
+            info.side = -1;
+            info.pidl = ILClone(pidl1);
+            ILFree(pidl1);
+        }
+        else if (order > 0)
+        {
+            info.side = 1;
+            info.pidl = ILClone(pidl2);
+            ILFree(pidl2);
+        }
+        else // if (order == 0)
+        {
+            info.side = 0;
+            info.pidl = ILClone(pidl1);
+            ILFree(pidl1);
+            ILFree(pidl2);
+        }
+
+        TRACE("Inserting item %d with side %d and pidl { cb=%d }\n", 
m_hDsaCount, info.side, info.pidl->mkid.cb);
+        int idx = DSA_InsertItem(m_hDsa, DSA_APPEND, &info);
+        TRACE("New index: %d\n", idx);
+
+        m_hDsaCount++;
+
+    } while (hr1 == S_OK || hr2 == S_OK);
+
+    m_HwndOwner = hwndOwner;
+    m_Flags = flags;
+        
+    return Reset();
+}
+
+HRESULT CEnumMergedFolder::FindPidlInList(LPCITEMIDLIST pcidl, LocalPidlInfo * 
pinfo)
+{
+    HRESULT hr;
+
+    TRACE("Searching for pidl { cb=%d } in a list of %d items\n", 
pcidl->mkid.cb, m_hDsaCount);
+
+    for (int i = 0; i < (int)m_hDsaCount; i++)
+    {
+        LocalPidlInfo * tinfo = (LocalPidlInfo *)DSA_GetItemPtr(m_hDsa, i);
+        if (!tinfo)
+            return E_FAIL;
+
+        LocalPidlInfo info = *tinfo;
+
+        TRACE("Comparing with item at %d with side %d and pidl { cb=%d }\n", 
i, info.side, info.pidl->mkid.cb);
+
+        if (info.side <= 0)
+        {
+#if 0
+            LPWSTR name1;
+            LPWSTR name2;
+            STRRET str1 = { STRRET_WSTR, 0 };
+            STRRET str2 = { STRRET_WSTR, 0 };
+            hr = m_UserLocalFolder->GetDisplayNameOf(info->pidl, 
SHGDN_FORPARSING | SHGDN_INFOLDER, &str1);
+            if (FAILED(hr))
+                return hr;
+            hr = m_UserLocalFolder->GetDisplayNameOf(pcidl, SHGDN_FORPARSING | 
SHGDN_INFOLDER, &str2);
+            if (FAILED(hr))
+                return hr;
+            StrRetToStrW(&str1, info->pidl, &name1);
+            StrRetToStrW(&str2, pcidl, &name2);
+            int order = StrCmpW(name1, name2);
+            CoTaskMemFree(name1);
+            CoTaskMemFree(name2);
+
+            if (order == 0)
+            {
+                *pinfo = *info;
+                return S_OK;
+            }
+#else
+            // FIXME: This works in windows.
+            hr = m_UserLocalFolder->CompareIDs(0, info.pidl, pcidl);
             if (FAILED_UNEXPECTEDLY(hr))
                 return hr;
-            if (hr == S_FALSE)
-                m_FirstDone = true;
-            else if (celt < 2)
-                return hr;
-        }
-
-        DWORD offset = *pceltFetched;
-        if (*pceltFetched < celt)
-        {
-            rgelt += *pceltFetched;
-            celt = (celt - *pceltFetched);
-            *pceltFetched = 0;
-
-            hr = m_AllUSers->Next(celt, rgelt, pceltFetched);
+            if (hr == S_OK)
+            {
+                *pinfo = info;
+                return S_OK;
+            }
+            else
+            {
+                TRACE("Comparison returned %d\n", (int) (short) (hr & 0xFFFF));
+            }
+#endif
+        }
+        else
+        {
+#if 0
+            LPWSTR name1;
+            LPWSTR name2;
+            STRRET str1 = { STRRET_WSTR, 0 };
+            STRRET str2 = { STRRET_WSTR, 0 };
+            hr = m_AllUSersFolder->GetDisplayNameOf(info->pidl, 
SHGDN_FORPARSING | SHGDN_INFOLDER, &str1);
+            if (FAILED(hr))
+                return hr;
+            hr = m_AllUSersFolder->GetDisplayNameOf(pcidl, SHGDN_FORPARSING | 
SHGDN_INFOLDER, &str2);
+            if (FAILED(hr))
+                return hr;
+            StrRetToStrW(&str1, info->pidl, &name1);
+            StrRetToStrW(&str2, pcidl, &name2);
+            int order = StrCmpW(name1, name2);
+            CoTaskMemFree(name1);
+            CoTaskMemFree(name2);
+
+            if (order == 0)
+            {
+                *pinfo = *info;
+                return S_OK;
+            }
+#else
+            // FIXME: This works in windows.
+            hr = m_AllUSersFolder->CompareIDs(0, info.pidl, pcidl);
             if (FAILED_UNEXPECTEDLY(hr))
                 return hr;
-
-            *pceltFetched += offset;
-
-            return hr;
-        }
-
-        return S_OK;
+            if (hr == S_OK)
+            {
+                *pinfo = info;
+                return S_OK;
+            }
+            else
+            {
+                TRACE("Comparison returned %d\n", (int) (short) (hr & 0xFFFF));
+            }
+#endif
+        }
     }
 
-    virtual HRESULT STDMETHODCALLTYPE Skip(
-        ULONG celt)
+    TRACE("Pidl not found\n");
+    return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+}
+
+HRESULT STDMETHODCALLTYPE CEnumMergedFolder::Next(
+    ULONG celt,
+    LPITEMIDLIST *rgelt,
+    ULONG *pceltFetched)
+{
+    if (pceltFetched) *pceltFetched = 0;
+
+    if (m_hDsaIndex == m_hDsaCount)
+        return S_FALSE;
+
+    for (int i = 0; i < (int)celt;)
     {
-        UNIMPLEMENTED;
-        return E_NOTIMPL;
+        LocalPidlInfo * tinfo = (LocalPidlInfo *) DSA_GetItemPtr(m_hDsa, 
m_hDsaIndex);
+        if (!tinfo)
+            return E_FAIL;
+
+        LocalPidlInfo info = *tinfo;
+
+        TRACE("Returning next item at %d with side %d and pidl { cb=%d }\n", 
m_hDsaIndex, info.side, info.pidl->mkid.cb);
+
+        // FIXME: ILClone shouldn't be needed here! This should be causing 
leaks
+        if (rgelt) rgelt[i] = ILClone(info.pidl);
+
+        m_hDsaIndex++;
+        i++;
+
+        if (m_hDsaIndex == m_hDsaCount)
+        {
+            if (pceltFetched) *pceltFetched = i;
+            return (i == (int)celt) ? S_OK : S_FALSE;
+        }
     }
 
-    virtual HRESULT STDMETHODCALLTYPE Reset(
-        )
-    {
-        if (m_FirstDone)
-            m_AllUSers->Reset();
-        return m_UserLocal->Reset();
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE Clone(
-        IEnumIDList **ppenum)
-    {
-        UNIMPLEMENTED;
-        return E_NOTIMPL;
-    }
-};
+    if (pceltFetched) *pceltFetched = celt;
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CEnumMergedFolder::Skip(ULONG celt)
+{
+    return Next(celt, NULL, NULL);
+}
+
+HRESULT STDMETHODCALLTYPE CEnumMergedFolder::Reset()
+{
+    m_hDsaIndex = 0;
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE CEnumMergedFolder::Clone(
+    IEnumIDList **ppenum)
+{
+    UNIMPLEMENTED;
+    return E_NOTIMPL;
+}
+
+//-----------------------------------------------------------------------------
+// CMergedFolder
 
 extern "C"
 HRESULT WINAPI CMergedFolder_Constructor(IShellFolder* userLocal, 
IShellFolder* allUsers, REFIID riid, LPVOID *ppv)
@@ -148,7 +425,8 @@
 {
     m_UserLocal = userLocal;
     m_AllUSers = allUsers;
-    return S_OK;
+    m_EnumSource = new CComObject<CEnumMergedFolder>();
+    return m_EnumSource->SetSources(m_UserLocal, m_AllUSers);
 }
 
 // IShellFolder
@@ -169,9 +447,10 @@
     SHCONTF grfFlags,
     IEnumIDList **ppenumIDList)
 {
-    CEnumMergedFolder * merged = new CComObject<CEnumMergedFolder>();
-    *ppenumIDList = merged;
-    return merged->Begin(hwndOwner, grfFlags, m_UserLocal, m_AllUSers);
+    HRESULT hr = m_EnumSource->QueryInterface(IID_PPV_ARG(IEnumIDList, 
ppenumIDList));
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+    return m_EnumSource->Begin(hwndOwner, grfFlags);
 }
 
 HRESULT STDMETHODCALLTYPE CMergedFolder::BindToObject(
@@ -180,15 +459,33 @@
     REFIID riid,
     void **ppvOut)
 {
+    LocalPidlInfo info;
     HRESULT hr;
 
-    hr = m_UserLocal->BindToObject(pidl, pbcReserved, riid, ppvOut);
-    if (SUCCEEDED(hr))
-        return hr;
-
-    hr = m_AllUSers->BindToObject(pidl, pbcReserved, riid, ppvOut);
-
-    return hr;
+    hr = m_EnumSource->FindPidlInList(pidl, &info);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+    
+    if (info.side < 0)
+        return m_UserLocal->BindToObject(pidl, pbcReserved, riid, ppvOut);
+    if (info.side > 0)
+        return m_AllUSers->BindToObject(pidl, pbcReserved, riid, ppvOut);
+
+    if (riid != IID_IShellFolder)
+        return E_FAIL;
+
+    CComPtr<IShellFolder> fld1;
+    CComPtr<IShellFolder> fld2;
+
+    hr = m_UserLocal->BindToObject(pidl, pbcReserved, 
IID_PPV_ARG(IShellFolder, &fld1));
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    hr = m_AllUSers->BindToObject(pidl, pbcReserved, IID_PPV_ARG(IShellFolder, 
&fld2));
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    return CMergedFolder_Constructor(fld1, fld2, riid, ppvOut);
 }
 
 HRESULT STDMETHODCALLTYPE CMergedFolder::BindToStorage(
@@ -206,8 +503,7 @@
     LPCITEMIDLIST pidl1,
     LPCITEMIDLIST pidl2)
 {
-    UNIMPLEMENTED;
-    return E_NOTIMPL;
+    return m_UserLocal->CompareIDs(lParam, pidl1, pidl2);
 }
 
 HRESULT STDMETHODCALLTYPE CMergedFolder::CreateViewObject(
@@ -224,16 +520,29 @@
     LPCITEMIDLIST *apidl,
     SFGAOF *rgfInOut)
 {
+    LocalPidlInfo info;
     HRESULT hr;
 
-    hr = m_UserLocal->GetAttributesOf(cidl, apidl, rgfInOut);
-    if (SUCCEEDED(hr))
-        return hr;
-
-    *rgfInOut = 0;
-    hr = m_AllUSers->GetAttributesOf(cidl, apidl, rgfInOut);
-
-    return hr;
+    for (int i = 0; i < (int)cidl; i++)
+    {
+        LPCITEMIDLIST pidl = apidl[i];
+
+        hr = m_EnumSource->FindPidlInList(pidl, &info);
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+
+        SFGAOF * pinOut1 = rgfInOut ? rgfInOut + i : NULL;
+
+        if (info.side <= 0)
+            hr = m_UserLocal->GetAttributesOf(1, &pidl, pinOut1);
+        else
+            hr = m_AllUSers->GetAttributesOf(1, &pidl, pinOut1);
+
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+    }
+
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CMergedFolder::GetUIObjectOf(
@@ -244,15 +553,30 @@
     UINT *prgfInOut,
     void **ppvOut)
 {
+    LocalPidlInfo info;
     HRESULT hr;
 
-    hr = m_UserLocal->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, 
ppvOut);
-    if (SUCCEEDED(hr))
-        return hr;
-
-    hr = m_AllUSers->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, 
ppvOut);
-
-    return hr;
+    for (int i = 0; i < (int)cidl; i++)
+    {
+        LPCITEMIDLIST pidl = apidl[i];
+
+        hr = m_EnumSource->FindPidlInList(pidl, &info);
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+
+        UINT * pinOut1 = prgfInOut ? prgfInOut+i : NULL;
+        void** ppvOut1 = ppvOut ? ppvOut + i : NULL;
+
+        if (info.side <= 0)
+            hr = m_UserLocal->GetUIObjectOf(hwndOwner, 1, &pidl, riid, 
pinOut1, ppvOut1);
+        else
+            hr = m_AllUSers->GetUIObjectOf(hwndOwner, 1, &pidl, riid, pinOut1, 
ppvOut1);
+
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+    }
+
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CMergedFolder::GetDisplayNameOf(
@@ -260,15 +584,21 @@
     SHGDNF uFlags,
     STRRET *lpName)
 {
+    LocalPidlInfo info;
     HRESULT hr;
 
-    hr = m_UserLocal->GetDisplayNameOf(pidl, uFlags, lpName);
-    if (SUCCEEDED(hr))
-        return hr;
-
-    hr = m_AllUSers->GetDisplayNameOf(pidl, uFlags, lpName);
-
-    return hr;
+    hr = m_EnumSource->FindPidlInList(pidl, &info);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    if (info.side <= 0)
+        hr = m_UserLocal->GetDisplayNameOf(pidl, uFlags, lpName);
+    else
+        hr = m_AllUSers->GetDisplayNameOf(pidl, uFlags, lpName);
+
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CMergedFolder::SetNameOf(

Modified: branches/shell-experiments/base/shell/rshell/CMergedFolder.h
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/rshell/CMergedFolder.h?rev=63658&r1=63657&r2=63658&view=diff
==============================================================================
--- branches/shell-experiments/base/shell/rshell/CMergedFolder.h        
[iso-8859-1] (original)
+++ branches/shell-experiments/base/shell/rshell/CMergedFolder.h        
[iso-8859-1] Sat Jun 28 15:38:25 2014
@@ -19,6 +19,8 @@
  */
 #pragma once
 
+class CEnumMergedFolder;
+
 class CMergedFolder :
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IShellFolder2
@@ -26,6 +28,7 @@
 private:
     CComPtr<IShellFolder> m_UserLocal;
     CComPtr<IShellFolder> m_AllUSers;
+    CComPtr<CEnumMergedFolder> m_EnumSource;
 
 public:
     CMergedFolder() {}

Modified: branches/shell-experiments/include/psdk/commctrl.h
URL: 
http://svn.reactos.org/svn/reactos/branches/shell-experiments/include/psdk/commctrl.h?rev=63658&r1=63657&r2=63658&view=diff
==============================================================================
--- branches/shell-experiments/include/psdk/commctrl.h  [iso-8859-1] (original)
+++ branches/shell-experiments/include/psdk/commctrl.h  [iso-8859-1] Sat Jun 28 
15:38:25 2014
@@ -4716,7 +4716,17 @@
     _In_ PFNDSAENUMCALLBACK pfnCB,
     _In_opt_ void *pData);
 
+  WINCOMMCTRLAPI
+  VOID
+  WINAPI
+  DSA_EnumCallback(
+    _In_ HDSA hdsa,
+    _In_ PFNDSAENUMCALLBACK enumProc,
+    _In_opt_ LPVOID lParam);
+
   WINCOMMCTRLAPI PVOID WINAPI DSA_GetItemPtr(_In_ HDSA hdsa, int i);
+
+  WINCOMMCTRLAPI BOOL WINAPI DSA_DeleteAllItems(_In_ HDSA hdsa);
 
   WINCOMMCTRLAPI
   int


Reply via email to