windows-nt/Source/XPSP1/NT/shell/shdocvw/favband.cpp
2020-09-26 16:20:57 +08:00

217 lines
6.4 KiB
C++

//
// favband.cpp
//
// favorites band implementation
//
#include "priv.h"
#include "sccls.h"
#include "nscband.h"
#include "resource.h"
#include "favorite.h"
#include "uemapp.h" // KMTF: Included for instrumentation
#include <mluisupp.h>
#define SUPERCLASS CNSCBand
#define TF_FAVBAND 0
class CFavBand : public CNSCBand
{
public:
// *** IOleCommandTarget methods ***
virtual STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
// *** IDockingWindow methods ***
virtual STDMETHODIMP ShowDW(BOOL fShow);
protected:
virtual void _AddButtons(BOOL fAdd);
HRESULT _BrowserExec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
void _OrganizeFavorites();
virtual BOOL _ShouldNavigateToPidl(LPCITEMIDLIST pidl, ULONG ulAttrib);
virtual HRESULT _NavigateRightPane(IShellBrowser *psb, LPCITEMIDLIST pidl);
virtual HRESULT _TranslatePidl(LPCITEMIDLIST pidl, LPITEMIDLIST *ppidlTarget, ULONG *pulAttrib);
friend HRESULT CFavBand_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi);
BOOL _fStrsAdded;
LONG_PTR _lStrOffset;
};
HRESULT CFavBand::_BrowserExec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)
{
return IUnknown_QueryServiceExec(_punkSite, SID_STopLevelBrowser, pguidCmdGroup, nCmdID, nCmdexecopt, pvarargIn, pvarargOut);
}
void CFavBand::_OrganizeFavorites()
{
DoOrganizeFavDlgW(_hwnd, NULL);
}
// *** IOleCommandTarget methods ***
HRESULT CFavBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)
{
if (pguidCmdGroup && IsEqualGUID(CLSID_FavBand, *pguidCmdGroup))
{
TraceMsg(TF_FAVBAND, "CFavBand::Exec CLSID_FavBand -- nCmdID == %x", nCmdID);
switch(nCmdID)
{
case FCIDM_ADDTOFAVORITES:
{
_BrowserExec(&CGID_Explorer, SBCMDID_ADDTOFAVORITES, OLECMDEXECOPT_PROMPTUSER, NULL, NULL);
// Instrument addition to favorites by pane
UEMFireEvent(&UEMIID_BROWSER, UEME_INSTRBROWSER, UEMF_INSTRUMENT, UIBW_ADDTOFAV, UIBL_PANE);
return S_OK;
}
case FCIDM_ORGANIZEFAVORITES:
{
_OrganizeFavorites();
return S_OK;
}
}
}
return SUPERCLASS::Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvarargIn, pvarargOut);
}
static const TBBUTTON c_tbFavorites[] =
{
{ 0, FCIDM_ADDTOFAVORITES, TBSTATE_ENABLED, BTNS_AUTOSIZE | BTNS_SHOWTEXT, {0,0}, 0, 0 },
{ 1, FCIDM_ORGANIZEFAVORITES, TBSTATE_ENABLED, BTNS_AUTOSIZE | BTNS_SHOWTEXT, {0,0}, 0, 1 },
};
void CFavBand::_AddButtons(BOOL fAdd)
{
IExplorerToolbar* piet;
if (SUCCEEDED(_punkSite->QueryInterface(IID_IExplorerToolbar, (void**)&piet)))
{
if (fAdd)
{
piet->SetCommandTarget((IUnknown*)SAFECAST(this, IOleCommandTarget*), &CLSID_FavBand, 0);
if (!_fStrsAdded)
{
piet->AddString(&CLSID_FavBand, MLGetHinst(), IDS_FAVS_BAR_LABELS, &_lStrOffset);
_fStrsAdded = TRUE;
}
_EnsureImageListsLoaded();
piet->SetImageList(&CLSID_FavBand, _himlNormal, _himlHot, NULL);
TBBUTTON tbFavorites[ARRAYSIZE(c_tbFavorites)];
memcpy(tbFavorites, c_tbFavorites, SIZEOF(TBBUTTON) * ARRAYSIZE(c_tbFavorites));
for (int i = 0; i < ARRAYSIZE(c_tbFavorites); i++)
tbFavorites[i].iString += (long) _lStrOffset;
piet->AddButtons(&CLSID_FavBand, ARRAYSIZE(tbFavorites), tbFavorites);
}
else
piet->SetCommandTarget(NULL, NULL, 0);
piet->Release();
}
}
// *** IDockingWindow methods ***
HRESULT CFavBand::ShowDW(BOOL fShow)
{
HRESULT hres = SUPERCLASS::ShowDW(fShow);
_AddButtons(fShow);
return hres;
}
HRESULT CFavBand_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi)
{
// aggregation checking is handled in class factory
CFavBand * pfb = new CFavBand();
if (!pfb)
return E_OUTOFMEMORY;
if (SUCCEEDED(pfb->_Init((LPCITEMIDLIST)CSIDL_FAVORITES)))
{
pfb->_pns = CNscTree_CreateInstance();
if (pfb->_pns)
{
ASSERT(poi);
pfb->_poi = poi;
// if you change this cast, fix up CChannelBand_CreateInstance
*ppunk = SAFECAST(pfb, IDeskBand *);
IUnknown_SetSite(pfb->_pns, *ppunk);
pfb->_SetNscMode(MODE_FAVORITES);
return S_OK;
}
}
pfb->Release();
return E_FAIL;
}
HRESULT CFavBand::_TranslatePidl(LPCITEMIDLIST pidl, LPITEMIDLIST *ppidlTarget, ULONG *pulAttrib)
{
HRESULT hr = E_INVALIDARG;
if (pidl && ppidlTarget && pulAttrib)
{
hr = IEGetAttributesOf(pidl, pulAttrib);
if (SUCCEEDED(hr))
{
hr = SHILClone(pidl, ppidlTarget);
}
}
return hr;
}
BOOL CFavBand::_ShouldNavigateToPidl(LPCITEMIDLIST pidl, ULONG ulAttrib)
{
return !(ulAttrib & SFGAO_FOLDER);
}
HRESULT CFavBand::_NavigateRightPane(IShellBrowser *psb, LPCITEMIDLIST pidl)
{
HRESULT hr = E_INVALIDARG;
if (psb && pidl)
{
TCHAR szPath[MAX_PATH];
hr = SHGetNameAndFlags(pidl, SHGDN_FORPARSING, szPath, ARRAYSIZE(szPath), NULL);
if (SUCCEEDED(hr))
{
hr = NavFrameWithFile(szPath, psb);
if (FAILED(hr))
{
IShellFolder *psf;
LPCITEMIDLIST pidlLast;
if (SUCCEEDED(SHBindToIDListParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlLast)))
{
LPITEMIDLIST pidlTarget;
if (SUCCEEDED(SHGetNavigateTarget(psf, pidlLast, &pidlTarget, NULL)))
{
hr = psb->BrowseObject(pidlTarget, SBSP_SAMEBROWSER);
ILFree(pidlTarget);
}
psf->Release();
}
}
if (SUCCEEDED(hr))
{
UEMFireEvent(&UEMIID_BROWSER, UEME_INSTRBROWSER, UEMF_INSTRUMENT, UIBW_NAVIGATE, UIBL_NAVFAVS);
UEMFireEvent(&UEMIID_BROWSER, UEME_RUNPIDL, UEMF_XEVENT, (WPARAM)NULL, (LPARAM)pidl);
SHSendChangeMenuNotify(NULL, SHCNEE_PROMOTEDITEM, 0, pidl);
}
}
}
return hr;
}