* Added IPersistFolder2 interface to CMergedFolder, per MSDN suggestion.
* Changed the way the pidl info is stored to be more clean and readable.

svn path=/branches/shell-experiments/; revision=63669
This commit is contained in:
David Quintana 2014-06-29 13:54:08 +00:00
parent dec446e288
commit 80c7746313
2 changed files with 77 additions and 35 deletions

View file

@ -27,7 +27,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(CMergedFolder);
struct LocalPidlInfo
{
int side; // -1 local, 0 shared, 1 common
BOOL shared;
IShellFolder * parent;
LPITEMIDLIST pidl;
};
@ -205,28 +206,29 @@ HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags)
break;
}
LocalPidlInfo info;
LocalPidlInfo info = { FALSE };
if (order < 0)
{
info.side = -1;
info.parent = m_UserLocalFolder;
info.pidl = ILClone(pidl1);
ILFree(pidl1);
}
else if (order > 0)
{
info.side = 1;
info.parent = m_AllUSersFolder;
info.pidl = ILClone(pidl2);
ILFree(pidl2);
}
else // if (order == 0)
{
info.side = 0;
info.shared = TRUE;
info.parent = m_UserLocalFolder;
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);
TRACE("Inserting item %d with parent %p and pidl { cb=%d }\n", m_hDsaCount, info.parent, info.pidl->mkid.cb);
int idx = DSA_InsertItem(m_hDsa, DSA_APPEND, &info);
TRACE("New index: %d\n", idx);
@ -254,15 +256,9 @@ HRESULT CEnumMergedFolder::FindPidlInList(LPCITEMIDLIST pcidl, LocalPidlInfo * p
LocalPidlInfo info = *tinfo;
TRACE("Comparing with item at %d with side %d and pidl { cb=%d }\n", i, info.side, info.pidl->mkid.cb);
TRACE("Comparing with item at %d with parent %p and pidl { cb=%d }\n", i, info.parent, info.pidl->mkid.cb);
CComPtr<IShellFolder> fld;
if (info.side <= 0)
fld = m_UserLocalFolder;
else
fld = m_AllUSersFolder;
hr = m_AllUSersFolder->CompareIDs(0, info.pidl, pcidl);
hr = info.parent->CompareIDs(0, info.pidl, pcidl);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@ -299,7 +295,7 @@ HRESULT STDMETHODCALLTYPE CEnumMergedFolder::Next(
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);
TRACE("Returning next item at %d with parent %p and pidl { cb=%d }\n", m_hDsaIndex, info.parent, info.pidl->mkid.cb);
// FIXME: ILClone shouldn't be needed here! This should be causing leaks
if (rgelt) rgelt[i] = ILClone(info.pidl);
@ -404,11 +400,9 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::BindToObject(
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 (!info.shared)
return info.parent->BindToObject(pidl, pbcReserved, riid, ppvOut);
if (riid != IID_IShellFolder)
return E_FAIL;
@ -472,10 +466,7 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetAttributesOf(
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);
hr = info.parent->GetAttributesOf(1, &pidl, pinOut1);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@ -499,17 +490,18 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetUIObjectOf(
{
LPCITEMIDLIST pidl = apidl[i];
TRACE("Processing GetUIObjectOf item %d of %u...\n", i, cidl);
hr = m_EnumSource->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
TRACE("FindPidlInList succeeded with parent %p and pidl { db=%d }\n", info.parent, info.pidl->mkid.cb);
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);
hr = info.parent->GetUIObjectOf(hwndOwner, 1, &pidl, riid, pinOut1, ppvOut1);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@ -530,10 +522,7 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetDisplayNameOf(
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);
hr = info.parent->GetDisplayNameOf(pidl, uFlags, lpName);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@ -551,6 +540,28 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::SetNameOf(
return E_NOTIMPL;
}
// IPersist
HRESULT STDMETHODCALLTYPE CMergedFolder::GetClassID(CLSID *lpClassId)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
// IPersistFolder
HRESULT STDMETHODCALLTYPE CMergedFolder::Initialize(LPCITEMIDLIST pidl)
{
m_shellPidl = ILClone(pidl);
return S_OK;
}
// IPersistFolder2
HRESULT STDMETHODCALLTYPE CMergedFolder::GetCurFolder(LPITEMIDLIST * pidl)
{
if (pidl)
*pidl = m_shellPidl;
return S_OK;
}
// IShellFolder2
HRESULT STDMETHODCALLTYPE CMergedFolder::GetDefaultSearchGUID(
GUID *lpguid)

View file

@ -23,13 +23,25 @@ class CEnumMergedFolder;
class CMergedFolder :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2
public IShellFolder2,
//public IStorage,
//public IAugmentedShellFolder3, // -- undocumented
//public IShellService, // -- undocumented
//public ITranslateShellChangeNotify,// -- undocumented
public IPersistFolder2
//public IPersistPropertyBag,
//public IShellIconOverlay, // -- undocumented
//public ICompositeFolder, // -- undocumented
//public IItemNameLimits, // -- undocumented
{
private:
CComPtr<IShellFolder> m_UserLocal;
CComPtr<IShellFolder> m_AllUSers;
CComPtr<CEnumMergedFolder> m_EnumSource;
LPITEMIDLIST m_shellPidl;
public:
CMergedFolder() {}
virtual ~CMergedFolder() {}
@ -40,8 +52,19 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CMergedFolder)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
//COM_INTERFACE_ENTRY_IID(IID_IStorage, IStorage)
//COM_INTERFACE_ENTRY_IID(IID_IAugmentedShellFolder3, IAugmentedShellFolder3)
//COM_INTERFACE_ENTRY_IID(IID_IShellService, IShellService)
//COM_INTERFACE_ENTRY_IID(IID_ITranslateShellChangeNotify,ITranslateShellChangeNotify)
//COM_INTERFACE_ENTRY_IID(IID_IPersistPropertyBag,IPersistPropertyBag)
//COM_INTERFACE_ENTRY_IID(IID_IShellIconOverlay, IShellIconOverlay)
//COM_INTERFACE_ENTRY_IID(IID_ICompositeFolder, ICompositeFolder)
//COM_INTERFACE_ENTRY_IID(IID_IItemNameLimits, IItemNameLimits)
END_COM_MAP()
// IShellFolder
@ -135,4 +158,12 @@ public:
UINT iColumn,
SHCOLUMNID *pscid);
// IPersist
virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *lpClassId);
// IPersistFolder
virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidl);
// IPersistFolder2
virtual HRESULT STDMETHODCALLTYPE GetCurFolder(LPITEMIDLIST * pidl);
};