mirror of
https://github.com/reactos/reactos.git
synced 2025-06-20 04:07:08 +00:00
[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. svn path=/branches/shell-experiments/; revision=63658
This commit is contained in:
parent
9ebe8b2e4e
commit
f03fef66d1
5 changed files with 449 additions and 106 deletions
|
@ -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,84 +60,346 @@ public:
|
|||
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)
|
||||
{
|
||||
HRESULT hr;
|
||||
ULONG *pceltFetched);
|
||||
|
||||
*pceltFetched = 0;
|
||||
|
||||
if (!m_FirstDone)
|
||||
{
|
||||
hr = m_UserLocal->Next(celt, rgelt, pceltFetched);
|
||||
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 (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
*pceltFetched += offset;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Skip(
|
||||
ULONG celt)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Reset(
|
||||
)
|
||||
{
|
||||
if (m_FirstDone)
|
||||
m_AllUSers->Reset();
|
||||
return m_UserLocal->Reset();
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Clone(
|
||||
IEnumIDList **ppenum)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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_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;
|
||||
if (hr == S_OK)
|
||||
{
|
||||
*pinfo = info;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Comparison returned %d\n", (int) (short) (hr & 0xFFFF));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
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;)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ HRESULT CMergedFolder::_SetSources(IShellFolder* userLocal, IShellFolder* allUse
|
|||
{
|
||||
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 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::EnumObjects(
|
|||
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 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::BindToObject(
|
|||
REFIID riid,
|
||||
void **ppvOut)
|
||||
{
|
||||
LocalPidlInfo info;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_UserLocal->BindToObject(pidl, pbcReserved, riid, ppvOut);
|
||||
if (SUCCEEDED(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, riid, ppvOut);
|
||||
hr = m_AllUSers->BindToObject(pidl, pbcReserved, IID_PPV_ARG(IShellFolder, &fld2));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
return hr;
|
||||
return CMergedFolder_Constructor(fld1, fld2, riid, ppvOut);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CMergedFolder::BindToStorage(
|
||||
|
@ -206,8 +503,7 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::CompareIDs(
|
|||
LPCITEMIDLIST pidl1,
|
||||
LPCITEMIDLIST pidl2)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return E_NOTIMPL;
|
||||
return m_UserLocal->CompareIDs(lParam, pidl1, pidl2);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CMergedFolder::CreateViewObject(
|
||||
|
@ -224,16 +520,29 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetAttributesOf(
|
|||
LPCITEMIDLIST *apidl,
|
||||
SFGAOF *rgfInOut)
|
||||
{
|
||||
LocalPidlInfo info;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_UserLocal->GetAttributesOf(cidl, apidl, rgfInOut);
|
||||
if (SUCCEEDED(hr))
|
||||
return hr;
|
||||
for (int i = 0; i < (int)cidl; i++)
|
||||
{
|
||||
LPCITEMIDLIST pidl = apidl[i];
|
||||
|
||||
*rgfInOut = 0;
|
||||
hr = m_AllUSers->GetAttributesOf(cidl, apidl, rgfInOut);
|
||||
hr = m_EnumSource->FindPidlInList(pidl, &info);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return 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 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetUIObjectOf(
|
|||
UINT *prgfInOut,
|
||||
void **ppvOut)
|
||||
{
|
||||
LocalPidlInfo info;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_UserLocal->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
|
||||
if (SUCCEEDED(hr))
|
||||
return hr;
|
||||
for (int i = 0; i < (int)cidl; i++)
|
||||
{
|
||||
LPCITEMIDLIST pidl = apidl[i];
|
||||
|
||||
hr = m_AllUSers->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
|
||||
hr = m_EnumSource->FindPidlInList(pidl, &info);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return 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 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetDisplayNameOf(
|
|||
SHGDNF uFlags,
|
||||
STRRET *lpName)
|
||||
{
|
||||
LocalPidlInfo info;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_UserLocal->GetDisplayNameOf(pidl, uFlags, lpName);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = m_EnumSource->FindPidlInList(pidl, &info);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
hr = m_AllUSers->GetDisplayNameOf(pidl, uFlags, lpName);
|
||||
if (info.side <= 0)
|
||||
hr = m_UserLocal->GetDisplayNameOf(pidl, uFlags, lpName);
|
||||
else
|
||||
hr = m_AllUSers->GetDisplayNameOf(pidl, uFlags, lpName);
|
||||
|
||||
return hr;
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CMergedFolder::SetNameOf(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue