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/rs…
==============================================================================
--- 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/rs…
==============================================================================
--- 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/rs…
==============================================================================
--- 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/rs…
==============================================================================
--- 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/…
==============================================================================
--- 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