* Now that CMergedFolder works, try to make it more like windows.
* CMergedFolder: Declare and expose the undocumented IAugmentedShellFolder2 (all methods unimplemented yet). It will require major changes to the way I implemented it, but it will be for the best.
* CStartMenu: Make use of the real CMergedFolder in Windows 2003 (does not exist in win7).

svn path=/branches/shell-experiments/; revision=63703
This commit is contained in:
David Quintana 2014-07-09 23:05:37 +00:00
parent 0ffe346179
commit 9804a12eff
3 changed files with 243 additions and 56 deletions

View file

@ -30,6 +30,7 @@ struct LocalPidlInfo
BOOL shared; BOOL shared;
IShellFolder * parent; IShellFolder * parent;
LPITEMIDLIST pidl; LPITEMIDLIST pidl;
LPITEMIDLIST pidlCommon;
}; };
class CEnumMergedFolder : class CEnumMergedFolder :
@ -67,7 +68,7 @@ public:
HRESULT SetSources(IShellFolder * userLocal, IShellFolder * allUSers); HRESULT SetSources(IShellFolder * userLocal, IShellFolder * allUSers);
HRESULT Begin(HWND hwndOwner, SHCONTF flags); HRESULT Begin(HWND hwndOwner, SHCONTF flags);
HRESULT FindPidlInList(LPCITEMIDLIST pcidl, LocalPidlInfo * pinfo); HRESULT FindPidlInList(HWND hwndOwner, LPCITEMIDLIST pcidl, LocalPidlInfo * pinfo);
virtual HRESULT STDMETHODCALLTYPE Next( virtual HRESULT STDMETHODCALLTYPE Next(
ULONG celt, ULONG celt,
@ -86,9 +87,10 @@ CEnumMergedFolder::CEnumMergedFolder() :
m_AllUSers(NULL), m_AllUSers(NULL),
m_HwndOwner(NULL), m_HwndOwner(NULL),
m_Flags(0), m_Flags(0),
m_hDsaIndex(0) m_hDsa(NULL),
m_hDsaIndex(0),
m_hDsaCount(0)
{ {
m_hDsa = DSA_Create(sizeof(LocalPidlInfo), 10);
} }
CEnumMergedFolder::~CEnumMergedFolder() CEnumMergedFolder::~CEnumMergedFolder()
@ -119,8 +121,8 @@ HRESULT CEnumMergedFolder::SetSources(IShellFolder * userLocal, IShellFolder * a
HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags) HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags)
{ {
HRESULT hr; HRESULT hr;
if (m_HwndOwner == hwndOwner && m_Flags == flags) if (m_hDsa && m_HwndOwner == hwndOwner && m_Flags == flags)
{ {
return Reset(); return Reset();
} }
@ -137,6 +139,11 @@ HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags)
return hr; return hr;
} }
if (!m_hDsa)
{
m_hDsa = DSA_Create(sizeof(LocalPidlInfo), 10);
}
DSA_EnumCallback(m_hDsa, s_DsaDeleteCallback, this); DSA_EnumCallback(m_hDsa, s_DsaDeleteCallback, this);
DSA_DeleteAllItems(m_hDsa); DSA_DeleteAllItems(m_hDsa);
m_hDsaCount = 0; m_hDsaCount = 0;
@ -242,10 +249,15 @@ HRESULT CEnumMergedFolder::Begin(HWND hwndOwner, SHCONTF flags)
return Reset(); return Reset();
} }
HRESULT CEnumMergedFolder::FindPidlInList(LPCITEMIDLIST pcidl, LocalPidlInfo * pinfo) HRESULT CEnumMergedFolder::FindPidlInList(HWND hwndOwner, LPCITEMIDLIST pcidl, LocalPidlInfo * pinfo)
{ {
HRESULT hr; HRESULT hr;
if (!m_hDsa)
{
Begin(hwndOwner, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS);
}
TRACE("Searching for pidl { cb=%d } in a list of %d items\n", pcidl->mkid.cb, m_hDsaCount); 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++) for (int i = 0; i < (int)m_hDsaCount; i++)
@ -299,10 +311,9 @@ HRESULT STDMETHODCALLTYPE CEnumMergedFolder::Next(
// FIXME: ILClone shouldn't be needed here! This should be causing leaks // FIXME: ILClone shouldn't be needed here! This should be causing leaks
if (rgelt) rgelt[i] = ILClone(info.pidl); if (rgelt) rgelt[i] = ILClone(info.pidl);
m_hDsaIndex++;
i++; i++;
m_hDsaIndex++;
if (m_hDsaIndex == m_hDsaCount) if (m_hDsaIndex == m_hDsaCount)
{ {
if (pceltFetched) *pceltFetched = i; if (pceltFetched) *pceltFetched = i;
@ -376,6 +387,37 @@ HRESULT CMergedFolder::_SetSources(IShellFolder* userLocal, IShellFolder* allUse
return m_EnumSource->SetSources(m_UserLocal, m_AllUSers); return m_EnumSource->SetSources(m_UserLocal, m_AllUSers);
} }
// IAugmentedShellFolder2
HRESULT STDMETHODCALLTYPE CMergedFolder::AddNameSpace(LPGUID lpGuid, IShellFolder * psf, LPCITEMIDLIST pcidl, ULONG dwUnknown)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CMergedFolder::GetNameSpaceID(LPCITEMIDLIST pcidl, LPGUID lpGuid)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CMergedFolder::QueryNameSpace(ULONG dwUnknown, LPGUID lpGuid, IShellFolder ** ppsf)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CMergedFolder::EnumNameSpace(ULONG dwUnknown, PULONG lpUnknown)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CMergedFolder::UnWrapIDList(LPCITEMIDLIST pcidl, LONG lUnknown, IShellFolder ** ppsf, LPITEMIDLIST * ppidl1, LPITEMIDLIST *ppidl2, LONG * lpUnknown)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
// IShellFolder // IShellFolder
HRESULT STDMETHODCALLTYPE CMergedFolder::ParseDisplayName( HRESULT STDMETHODCALLTYPE CMergedFolder::ParseDisplayName(
HWND hwndOwner, HWND hwndOwner,
@ -385,8 +427,34 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::ParseDisplayName(
LPITEMIDLIST *ppidl, LPITEMIDLIST *ppidl,
ULONG *pdwAttributes) ULONG *pdwAttributes)
{ {
UNIMPLEMENTED; HRESULT hr;
return E_NOTIMPL; LocalPidlInfo info;
if (!ppidl) return E_FAIL;
if (pchEaten) *pchEaten = 0;
if (pdwAttributes) *pdwAttributes = 0;
hr = m_UserLocal->ParseDisplayName(hwndOwner, pbcReserved, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
if (SUCCEEDED(hr))
{
hr = m_EnumSource->FindPidlInList(hwndOwner, *ppidl, &info);
if (SUCCEEDED(hr))
return hr;
}
hr = m_AllUSers->ParseDisplayName(hwndOwner, pbcReserved, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
if (SUCCEEDED(hr))
{
hr = m_EnumSource->FindPidlInList(hwndOwner, *ppidl, &info);
if (SUCCEEDED(hr))
return hr;
}
if (ppidl) *ppidl = NULL;
if (pchEaten) *pchEaten = 0;
if (pdwAttributes) *pdwAttributes = 0;
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
} }
HRESULT STDMETHODCALLTYPE CMergedFolder::EnumObjects( HRESULT STDMETHODCALLTYPE CMergedFolder::EnumObjects(
@ -412,7 +480,7 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::BindToObject(
TRACE("BindToObject\n"); TRACE("BindToObject\n");
hr = m_EnumSource->FindPidlInList(pidl, &info); hr = m_EnumSource->FindPidlInList(NULL, pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -478,7 +546,7 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetAttributesOf(
{ {
LPCITEMIDLIST pidl = apidl[i]; LPCITEMIDLIST pidl = apidl[i];
hr = m_EnumSource->FindPidlInList(pidl, &info); hr = m_EnumSource->FindPidlInList(NULL, pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -514,7 +582,7 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetUIObjectOf(
TRACE("Processing GetUIObjectOf item %d of %u...\n", i, cidl); TRACE("Processing GetUIObjectOf item %d of %u...\n", i, cidl);
hr = m_EnumSource->FindPidlInList(pidl, &info); hr = m_EnumSource->FindPidlInList(hwndOwner, pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -544,7 +612,7 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetDisplayNameOf(
TRACE("GetDisplayNameOf\n"); TRACE("GetDisplayNameOf\n");
hr = m_EnumSource->FindPidlInList(pidl, &info); hr = m_EnumSource->FindPidlInList(NULL, pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -630,7 +698,7 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetDetailsEx(
TRACE("GetDetailsEx\n"); TRACE("GetDetailsEx\n");
hr = m_EnumSource->FindPidlInList(pidl, &info); hr = m_EnumSource->FindPidlInList(NULL, pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -655,7 +723,7 @@ HRESULT STDMETHODCALLTYPE CMergedFolder::GetDetailsOf(
TRACE("GetDetailsOf\n"); TRACE("GetDetailsOf\n");
hr = m_EnumSource->FindPidlInList(pidl, &info); hr = m_EnumSource->FindPidlInList(NULL, pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;

View file

@ -19,12 +19,37 @@
*/ */
#pragma once #pragma once
static IID IID_IAugmentedShellFolder = { 0x91EA3F8C, 0xC99B, 0x11D0, { 0x98, 0x15, 0x00, 0xC0, 0x4F, 0xD9, 0x19, 0x72 } };
static IID IID_IAugmentedShellFolder2 = { 0x8DB3B3F4, 0x6CFE, 0x11D1, { 0x8A, 0xE9, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xD0 } };
static CLSID CLSID_MergedFolder = { 0x26FDC864, 0xBE88, 0x46E7, { 0x92, 0x35, 0x03, 0x2D, 0x8E, 0xA5, 0x16, 0x2E } };
interface IAugmentedShellFolder : public IShellFolder
{
virtual HRESULT STDMETHODCALLTYPE AddNameSpace(LPGUID, IShellFolder *, LPCITEMIDLIST, ULONG) = 0;
virtual HRESULT STDMETHODCALLTYPE GetNameSpaceID(LPCITEMIDLIST, LPGUID) = 0;
virtual HRESULT STDMETHODCALLTYPE QueryNameSpace(ULONG, LPGUID, IShellFolder **) = 0;
virtual HRESULT STDMETHODCALLTYPE EnumNameSpace(ULONG, PULONG) = 0;
};
interface IAugmentedShellFolder2 : public IAugmentedShellFolder
{
virtual HRESULT STDMETHODCALLTYPE UnWrapIDList(LPCITEMIDLIST, LONG, IShellFolder **, LPITEMIDLIST *, LPITEMIDLIST *, LONG *) = 0;
};
/* No idea what QUERYNAMESPACEINFO struct contains -- the prototype comes from the PDB info
interface IAugmentedShellFolder3 : public IAugmentedShellFolder2
{
virtual HRESULT STDMETHODCALLTYPE QueryNameSpace2(ULONG, QUERYNAMESPACEINFO *) = 0;
};
*/
class CEnumMergedFolder; class CEnumMergedFolder;
class CMergedFolder : class CMergedFolder :
public CComObjectRootEx<CComMultiThreadModelNoCS>, public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2, public IShellFolder2,
//public IStorage, //public IStorage,
public IAugmentedShellFolder2, // -- undocumented
//public IAugmentedShellFolder3, // -- undocumented //public IAugmentedShellFolder3, // -- undocumented
//public IShellService, // -- undocumented //public IShellService, // -- undocumented
//public ITranslateShellChangeNotify,// -- undocumented //public ITranslateShellChangeNotify,// -- undocumented
@ -52,13 +77,15 @@ public:
DECLARE_PROTECT_FINAL_CONSTRUCT() DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CMergedFolder) BEGIN_COM_MAP(CMergedFolder)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder) COM_INTERFACE_ENTRY2_IID(IID_IShellFolder, IShellFolder, IShellFolder2)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2) COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist) COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder) COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2) COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
//COM_INTERFACE_ENTRY_IID(IID_IStorage, IStorage) COM_INTERFACE_ENTRY_IID(IID_IAugmentedShellFolder, IAugmentedShellFolder)
COM_INTERFACE_ENTRY_IID(IID_IAugmentedShellFolder2, IAugmentedShellFolder2)
//COM_INTERFACE_ENTRY_IID(IID_IAugmentedShellFolder3, IAugmentedShellFolder3) //COM_INTERFACE_ENTRY_IID(IID_IAugmentedShellFolder3, IAugmentedShellFolder3)
//COM_INTERFACE_ENTRY_IID(IID_IStorage, IStorage)
//COM_INTERFACE_ENTRY_IID(IID_IShellService, IShellService) //COM_INTERFACE_ENTRY_IID(IID_IShellService, IShellService)
//COM_INTERFACE_ENTRY_IID(IID_ITranslateShellChangeNotify,ITranslateShellChangeNotify) //COM_INTERFACE_ENTRY_IID(IID_ITranslateShellChangeNotify,ITranslateShellChangeNotify)
//COM_INTERFACE_ENTRY_IID(IID_IPersistPropertyBag,IPersistPropertyBag) //COM_INTERFACE_ENTRY_IID(IID_IPersistPropertyBag,IPersistPropertyBag)
@ -166,4 +193,11 @@ public:
// IPersistFolder2 // IPersistFolder2
virtual HRESULT STDMETHODCALLTYPE GetCurFolder(LPITEMIDLIST * pidl); virtual HRESULT STDMETHODCALLTYPE GetCurFolder(LPITEMIDLIST * pidl);
// IAugmentedShellFolder2
virtual HRESULT STDMETHODCALLTYPE AddNameSpace(LPGUID lpGuid, IShellFolder * psf, LPCITEMIDLIST pcidl, ULONG dwUnknown);
virtual HRESULT STDMETHODCALLTYPE GetNameSpaceID(LPCITEMIDLIST pcidl, LPGUID lpGuid);
virtual HRESULT STDMETHODCALLTYPE QueryNameSpace(ULONG dwUnknown, LPGUID lpGuid, IShellFolder ** ppsf);
virtual HRESULT STDMETHODCALLTYPE EnumNameSpace(ULONG dwUnknown, PULONG lpUnknown);
virtual HRESULT STDMETHODCALLTYPE UnWrapIDList(LPCITEMIDLIST pcidl, LONG lUnknown, IShellFolder ** ppsf, LPITEMIDLIST * ppidl1, LPITEMIDLIST *ppidl2, LONG * lpUnknown);
}; };

View file

@ -19,6 +19,8 @@
*/ */
#include "precomp.h" #include "precomp.h"
#include "CMergedFolder.h"
//#define TEST_TRACKPOPUPMENU_SUBMENUS //#define TEST_TRACKPOPUPMENU_SUBMENUS
@ -63,6 +65,7 @@ private:
CComPtr<IBandSite> m_pBandSite; CComPtr<IBandSite> m_pBandSite;
CComPtr<IDeskBar> m_pDeskBar; CComPtr<IDeskBar> m_pDeskBar;
CComPtr<ITrayPriv> m_pTrayPriv; CComPtr<ITrayPriv> m_pTrayPriv;
CComPtr<IShellFolder> m_programsFolder;
HRESULT OnInitMenu() HRESULT OnInitMenu()
{ {
@ -141,6 +144,12 @@ private:
int csidl = 0; int csidl = 0;
IShellMenu *pShellMenu; IShellMenu *pShellMenu;
hr = CMenuBand_Constructor(IID_PPV_ARG(IShellMenu, &pShellMenu));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = pShellMenu->Initialize(this, 0, ANCESTORDEFAULT, SMINIT_VERTICAL);
switch (psmd->uId) switch (psmd->uId)
{ {
case IDM_PROGRAMS: csidl = CSIDL_PROGRAMS; break; case IDM_PROGRAMS: csidl = CSIDL_PROGRAMS; break;
@ -148,20 +157,22 @@ private:
case IDM_DOCUMENTS: csidl = CSIDL_RECENT; break; case IDM_DOCUMENTS: csidl = CSIDL_RECENT; break;
} }
hr = CMenuBand_Constructor(IID_PPV_ARG(IShellMenu, &pShellMenu));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = pShellMenu->Initialize(this, 0, ANCESTORDEFAULT, SMINIT_VERTICAL);
if (csidl) if (csidl)
{ {
LPITEMIDLIST pidlStartMenu; IShellFolder *psfStartMenu;
IShellFolder *psfDestop, *psfStartMenu;
hr = SHGetFolderLocation(NULL, csidl, 0, 0, &pidlStartMenu); if (csidl == CSIDL_PROGRAMS && m_programsFolder)
hr = SHGetDesktopFolder(&psfDestop); {
hr = psfDestop->BindToObject(pidlStartMenu, NULL, IID_PPV_ARG(IShellFolder, &psfStartMenu)); psfStartMenu = m_programsFolder;
}
else
{
LPITEMIDLIST pidlStartMenu;
IShellFolder *psfDestop;
hr = SHGetFolderLocation(NULL, csidl, 0, 0, &pidlStartMenu);
hr = SHGetDesktopFolder(&psfDestop);
hr = psfDestop->BindToObject(pidlStartMenu, NULL, IID_PPV_ARG(IShellFolder, &psfStartMenu));
}
hr = pShellMenu->SetShellFolder(psfStartMenu, NULL, NULL, 0); hr = pShellMenu->SetShellFolder(psfStartMenu, NULL, NULL, 0);
} }
@ -240,6 +251,12 @@ public:
m_pDeskBar.Release(); m_pDeskBar.Release();
} }
HRESULT _SetProgramsFolder(IShellFolder * programs)
{
m_programsFolder = programs;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CallbackSM( HRESULT STDMETHODCALLTYPE CallbackSM(
LPSMDATA psmd, LPSMDATA psmd,
UINT uMsg, UINT uMsg,
@ -265,6 +282,85 @@ public:
} }
}; };
HRESULT BindToDesktop(LPCITEMIDLIST pidl, IShellFolder ** ppsfResult)
{
HRESULT hr;
CComPtr<IShellFolder> psfDesktop;
*ppsfResult = NULL;
hr = SHGetDesktopFolder(&psfDesktop);
if (FAILED(hr))
return hr;
hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, ppsfResult));
return hr;
}
HRESULT GetStartMenuFolder(IShellFolder ** ppsfStartMenu)
{
HRESULT hr;
LPITEMIDLIST pidlUserStartMenu;
LPITEMIDLIST pidlCommonStartMenu;
*ppsfStartMenu = NULL;
hr = SHGetSpecialFolderLocation(NULL, CSIDL_STARTMENU, &pidlUserStartMenu);
if (FAILED(hr))
return hr;
if (FAILED(SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_STARTMENU, &pidlCommonStartMenu)))
{
BindToDesktop(pidlUserStartMenu, ppsfStartMenu);
ILFree(pidlUserStartMenu);
return S_OK;
}
CComPtr<IShellFolder> psfUserStartMenu;
hr = BindToDesktop(pidlUserStartMenu, &psfUserStartMenu);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
CComPtr<IShellFolder> psfCommonStartMenu;
hr = BindToDesktop(pidlCommonStartMenu, &psfCommonStartMenu);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
#if CUSTOM_MERGE_FOLDERS
IShellFolder * psfMerged;
hr = CMergedFolder_Constructor(psfUserStartMenu, psfCommonStartMenu, IID_PPV_ARG(IShellFolder, &psfMerged));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
#else
CComPtr<IAugmentedShellFolder> pasf;
hr = CoCreateInstance(CLSID_MergedFolder, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IAugmentedShellFolder, &pasf));
if (FAILED_UNEXPECTEDLY(hr))
{
BindToDesktop(pidlUserStartMenu, ppsfStartMenu);
ILFree(pidlCommonStartMenu);
ILFree(pidlUserStartMenu);
return S_OK;
}
hr = pasf->AddNameSpace(NULL, psfUserStartMenu, pidlUserStartMenu, 0xFF00);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = pasf->AddNameSpace(NULL, psfCommonStartMenu, pidlCommonStartMenu, 0);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = pasf->QueryInterface(IID_PPV_ARG(IShellFolder, ppsfStartMenu));
pasf.Release();
#endif
ILFree(pidlCommonStartMenu);
ILFree(pidlUserStartMenu);
return hr;
}
extern "C" extern "C"
HRESULT WINAPI HRESULT WINAPI
CStartMenu_Constructor(REFIID riid, void **ppv) CStartMenu_Constructor(REFIID riid, void **ppv)
@ -274,15 +370,10 @@ CStartMenu_Constructor(REFIID riid, void **ppv)
IDeskBar* pDeskBar; IDeskBar* pDeskBar;
HRESULT hr; HRESULT hr;
IShellFolder *shellFolder; IShellFolder * psf;
LPITEMIDLIST pidlStartMenuUser; LPITEMIDLIST pidlPrograms;
IShellFolder *psfStartMenuUser; CComPtr<IShellFolder> psfPrograms;
#if MERGE_FOLDERS
LPITEMIDLIST pidlStartMenuAll;
IShellFolder *psfStartMenuAll;
#endif
hr = CMenuBand_Constructor(IID_PPV_ARG(IShellMenu, &pShellMenu)); hr = CMenuBand_Constructor(IID_PPV_ARG(IShellMenu, &pShellMenu));
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
@ -306,32 +397,26 @@ CStartMenu_Constructor(REFIID riid, void **ppv)
pShellMenu->Initialize(pCallback, (UINT) -1, 0, SMINIT_TOPLEVEL | SMINIT_VERTICAL); pShellMenu->Initialize(pCallback, (UINT) -1, 0, SMINIT_TOPLEVEL | SMINIT_VERTICAL);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
hr = SHGetDesktopFolder(&shellFolder); hr = GetStartMenuFolder(&psf);
/* FIXME: Use CLSID_MergedFolder class and IID_IAugmentedShellFolder2 interface here */
/* CLSID_MergedFolder 26fdc864-be88-46e7-9235-032d8ea5162e */
/* IID_IAugmentedShellFolder2 8db3b3f4-6cfe-11d1-8ae9-00c04fd918d0 */
hr = SHGetFolderLocation(NULL, CSIDL_STARTMENU, 0, 0, &pidlStartMenuUser);
hr = shellFolder->BindToObject(pidlStartMenuUser, NULL, IID_PPV_ARG(IShellFolder, &psfStartMenuUser));
#if MERGE_FOLDERS
hr = SHGetFolderLocation(NULL, CSIDL_COMMON_STARTMENU, 0, 0, &pidlStartMenuAll);
hr = shellFolder->BindToObject(pidlStartMenuAll, NULL, IID_PPV_ARG(IShellFolder, &psfStartMenuAll));
IShellFolder * psfMerged;
hr = CMergedFolder_Constructor(psfStartMenuUser, psfStartMenuAll, IID_PPV_ARG(IShellFolder, &psfMerged));
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
hr = pShellMenu->SetShellFolder(psfMerged, NULL, NULL, 0); hr = psf->ParseDisplayName(NULL, NULL, L"Programs", NULL, &pidlPrograms, NULL);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#else
hr = pShellMenu->SetShellFolder(psfStartMenuUser, NULL, NULL, 0); hr = psf->BindToObject(pidlPrograms, NULL, IID_PPV_ARG(IShellFolder, &psfPrograms));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = pCallback->_SetProgramsFolder(psfPrograms);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = pShellMenu->SetShellFolder(psf, NULL, NULL, 0);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#endif
hr = pDeskBar->SetClient(pBandSite); hr = pDeskBar->SetClient(pBandSite);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))