|
|
#include "priv.h"
#include "sccls.h"
#include "bands.h"
#include "bsmenu.h"
#include "isfband.h"
#include "legacy.h"
#include "resource.h"
#include "uemapp.h"
#include "enumband.h"
#include "mluisupp.h"
static const CLSID g_clsidNull = {0};
#define DPA_SafeGetPtrCount(hdpa) (hdpa ? DPA_GetPtrCount(hdpa) : 0)
HRESULT CBandSiteMenu_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi) { // aggregation checking is handled in class factory
CBandSiteMenu *p = new CBandSiteMenu(); if (p) { *ppunk = SAFECAST(p, IShellService*); return S_OK; }
return E_OUTOFMEMORY; }
CBandSiteMenu::CBandSiteMenu() : _cRef(1) { DllAddRef(); }
CBandSiteMenu::~CBandSiteMenu() { DPA_DestroyCallback(_hdpaBandClasses, _DPA_FreeBandClassInfo, 0); _hdpaBandClasses = NULL; SetOwner(NULL); DllRelease(); }
int CBandSiteMenu::_DPA_FreeBandClassInfo(LPVOID p, LPVOID d) { BANDCLASSINFO *pbci = (BANDCLASSINFO*)p;
// req'd
ASSERT(pbci->pszName || (*(int *)&pbci->clsid == 0)); if (pbci->pszName) LocalFree(pbci->pszName);
// optional
if (pbci->pszIcon != NULL) LocalFree(pbci->pszIcon); if (pbci->pszMenu != NULL) LocalFree(pbci->pszMenu); if (pbci->pszHelp != NULL) LocalFree(pbci->pszHelp); if (pbci->pszMenuPUI != NULL) LocalFree(pbci->pszMenuPUI); if (pbci->pszHelpPUI != NULL) LocalFree(pbci->pszHelpPUI);
LocalFree(pbci);
return 1; }
ULONG CBandSiteMenu::AddRef() { _cRef++; return _cRef; }
ULONG CBandSiteMenu::Release() { ASSERT(_cRef > 0); _cRef--;
if (_cRef > 0) return _cRef;
delete this; return 0; }
HRESULT CBandSiteMenu::SetOwner(IUnknown* punk) { ATOMICRELEASE(_pbs); if (punk) { punk->QueryInterface(IID_IBandSite, (LPVOID*)&_pbs); } return S_OK; }
HRESULT CBandSiteMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { return HandleMenuMsg2(uMsg, wParam, lParam, NULL); }
UINT CBandSiteMenu::_IDToInternal(UINT uID) { if (uID != -1) { uID -= _idCmdFirst; }
return uID; }
UINT CBandSiteMenu::_IDToExternal(UINT uID) { if (uID != -1) { uID += _idCmdFirst; }
return uID; }
LRESULT CBandSiteMenu::_OnInitMenuPopup(HMENU hmenu, UINT uPos) { //
// Is this is the "Toolbars >" submenu (which we populate
// lazily), and has it not yet been populated?
//
UINT uID = GetMenuItemID(hmenu, 0); uID = _IDToInternal(uID); if (uID == DBIDM_DESKTOPBAND) { // Yes
_PopulateSubmenu(hmenu); }
return 0; }
HRESULT CBandSiteMenu::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plres) { LRESULT lres = 0;
switch (uMsg) { case WM_INITMENUPOPUP: lres = _OnInitMenuPopup((HMENU)wParam, LOWORD(lParam)); break; }
if (plres) *plres = lres;
return S_OK; }
HRESULT CBandSiteMenu::QueryInterface(REFIID riid, LPVOID * ppvObj) { static const QITAB qit[] = { QITABENT(CBandSiteMenu, IContextMenu3), QITABENTMULTI(CBandSiteMenu, IContextMenu2, IContextMenu3), QITABENTMULTI(CBandSiteMenu, IContextMenu, IContextMenu3), QITABENT(CBandSiteMenu, IShellService), { 0 }, };
HRESULT hres = QISearch(this, qit, riid, ppvObj);
if (FAILED(hres)) { if (IsEqualIID(riid, CLSID_BandSiteMenu)) { *ppvObj = (void *) this; AddRef(); return S_OK; } }
return hres; }
#define MAX_BANDS 50
void CBandSiteMenu::_PopulateSubmenu(HMENU hmenuSub) { // the start id is the last of the fixed bands.
// when we do the Shell_MergeMenus below, it will be incremented by idCmdFirst
ASSERT(hmenuSub);
CATID catid = CATID_DeskBand;
if (_hdpaBandClasses) { DPA_DestroyCallback(_hdpaBandClasses, _DPA_FreeBandClassInfo, 0); _hdpaBandClasses = NULL; }
LoadFromComCat(&catid);
// Kick off an asynchronous update of the comcat cache
SHWriteClassesOfCategories(1, &catid, 0, NULL, TRUE, FALSE, NULL);
_idCmdEnumFirst = CreateMergeMenu(hmenuSub, MAX_BANDS, 0, _IDToExternal(DBIDM_NEWBANDFIXEDLAST), 0, FALSE);
_AddEnumMenu(hmenuSub, GetMenuItemCount(hmenuSub) - 2); // -2 to go before "New Toolbar" and separator
int iIndex = GetMenuItemCount(hmenuSub); if (SHRestricted(REST_NOCLOSE_DRAGDROPBAND) || SHRestricted(REST_CLASSICSHELL)) { // We also need to disable turning On or Off the Bands.
// In classic mode, don't allow them either.
int nIter; for (nIter = 0; nIter < iIndex; nIter++) EnableMenuItem(hmenuSub, nIter, MF_BYPOSITION | MF_GRAYED); }
if (SHRestricted(REST_CLASSICSHELL)) { // Disable New Toolbar menu also.
EnableMenuItem(hmenuSub, DBIDM_NEWFOLDERBAND, MF_BYCOMMAND | MF_GRAYED); } }
HRESULT CBandSiteMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { if (!_pbs) return E_FAIL;
if (SHRestricted(REST_NOTOOLBARSONTASKBAR)) { return E_FAIL; }
HMENU hmenuSrc = LoadMenuPopup_PrivateNoMungeW(MENU_DESKBARAPP); if (hmenuSrc) { _idCmdFirst = idCmdFirst;
Shell_MergeMenus(hmenu, hmenuSrc, indexMenu, idCmdFirst, idCmdLast, MM_ADDSEPARATOR); DestroyMenu(hmenuSrc);
if (_SHIsMenuSeparator(hmenu, indexMenu)) { //
// Adjust indexMenu to point to the spot where the Toolbars
// submenu was actually inserted.
//
indexMenu++; }
if (!(uFlags & CMF_ICM3)) { //
// Caller doesn't speak ICM3, so won't give us a chance to
// populate submenu on WM_INITMENUPOPUP. Thus we need to
// populate it now.
//
HMENU hmenuSub = GetSubMenu(hmenu, indexMenu);
if (hmenuSub) _PopulateSubmenu(hmenuSub); } #ifdef DEBUG
else { //
// _OnInitMenuPopup assumes DBIDM_DESKTOPBAND is the first item
// in the "Toolbars >" submenu. If that assumption breaks (and
// you see this ASSERT rip), be sure to fix up the code there.
//
HMENU hmenuSub = GetSubMenu(hmenu, indexMenu); ASSERT(GetMenuItemID(hmenuSub, 0) == _IDToExternal(DBIDM_DESKTOPBAND)); } #endif
//
// Assert that our caller gave us enough room to accomodate
// the worst-case count.
//
ASSERT((idCmdFirst + DBIDM_NEWBANDFIXEDLAST + MAX_BANDS) < idCmdLast);
return idCmdFirst + DBIDM_NEWBANDFIXEDLAST + MAX_BANDS; }
return E_FAIL; }
BOOL CBandSiteMenu::_CheckUnique(IDeskBand* pdb, HMENU hmenu) { // check to see if this band is unique. (not already added by comcat list or
// hard coded list
// if it is unique, return TRUE.
// if it's not, check the other menu item
CLSID clsid; DWORD dwPrivID; BOOL fRet = TRUE; UINT idCmd = (UINT)-1; if (SUCCEEDED(_GetBandIdentifiers(pdb, &clsid, &dwPrivID))) { // check the comcat list
if (dwPrivID == (DWORD)-1) { for (int i = 0; i < DPA_SafeGetPtrCount(_hdpaBandClasses) ; i++) { BANDCLASSINFO *pbci = (BANDCLASSINFO*)DPA_GetPtr(_hdpaBandClasses, i); if (IsEqualGUID(clsid, pbci->clsid)) { idCmd = i + DBIDM_NEWBANDFIXEDLAST; goto FoundIt; } } } else if (IsEqualGUID(clsid, CLSID_ISFBand)) { // check our hardcoded list
switch (dwPrivID) { case CSIDL_DESKTOP: idCmd = DBIDM_DESKTOPBAND; break; case CSIDL_APPDATA: idCmd = DBIDM_LAUNCHBAND; break; } } }
FoundIt: if (idCmd != (UINT)-1) { // we found a menu for this already.... if it wasn't already checked,
// check it now and it will represent us
if (!(GetMenuState(hmenu, _IDToExternal(idCmd), MF_BYCOMMAND) & MF_CHECKED)) { CheckMenuItem(hmenu, _IDToExternal(idCmd), MF_BYCOMMAND | MF_CHECKED); fRet = FALSE; } } return fRet; }
void CBandSiteMenu::_AddEnumMenu(HMENU hmenu, int iInsert) { DWORD dwID;
int iMax = MAX_BANDS - (_IDToInternal(_idCmdEnumFirst) - DBIDM_NEWBANDFIXEDLAST);
for (int i = 0; i < iMax && SUCCEEDED(_pbs->EnumBands(i, &dwID)); i++) { HRESULT hr; WCHAR szName[80]; DWORD dwFlags = MF_BYPOSITION; DWORD dwState; IDeskBand *pdb;
hr = _pbs->QueryBand(dwID, &pdb, &dwState, szName, ARRAYSIZE(szName)); if (EVAL(SUCCEEDED(hr))) { if (_CheckUnique(pdb, hmenu)) { if (dwState & BSSF_VISIBLE) dwFlags |= MF_CHECKED;
if (!(dwState & BSSF_UNDELETEABLE)) { InsertMenu(hmenu, iInsert, dwFlags, _idCmdEnumFirst + i, szName); iInsert++; } } } if (pdb) pdb->Release(); } }
HRESULT CBandSiteMenu::_GetBandIdentifiers(IUnknown *punk, CLSID* pclsid, DWORD* pdwPrivID) { HRESULT hr = E_FAIL; IPersist* pp;
if (SUCCEEDED(punk->QueryInterface(IID_IPersist, (LPVOID*)&pp))) { pp->GetClassID(pclsid);
VARIANTARG v = {0}; *pdwPrivID = (DWORD) -1; if (SUCCEEDED(IUnknown_Exec(punk, &CGID_ISFBand, ISFBID_PRIVATEID, 0, NULL, &v))) { if (v.vt == VT_I4) { *pdwPrivID = (DWORD)v.lVal; } } hr = S_OK; pp->Release(); } return hr; }
// we use IPersist to find the class id of bands.
// we have a few special case bands (such as Quick Launch and Desktop) that are
// the same band, but pointing to different objects.
HRESULT CBandSiteMenu::_FindBand(const CLSID* pclsid, DWORD dwPrivID, DWORD* pdwBandID) { int i = 0; BOOL fFound = FALSE; HRESULT hr = E_FAIL; DWORD dwBandID = -1;
while (hr == E_FAIL && SUCCEEDED(_pbs->EnumBands(i, &dwBandID))) { IDeskBand* pdb;
if (SUCCEEDED(_pbs->QueryBand(dwBandID, &pdb, NULL, NULL, 0))) { CLSID clsid; DWORD dwPrivData; if (SUCCEEDED(_GetBandIdentifiers(pdb, &clsid, &dwPrivData))) { // special case for differentiating between all of the isfbands
// find out if the private id this holds is the same as what we're asking for
if (IsEqualIID(clsid, *pclsid) && (dwPrivData == dwPrivID)) { hr = S_OK; } } pdb->Release(); } i++; } if (pdwBandID) *pdwBandID = dwBandID; return hr; }
HRESULT CBandSiteMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici) { int idCmd; if (!_pbs) return E_FAIL; if (!HIWORD(pici->lpVerb)) idCmd = LOWORD(pici->lpVerb); else return E_FAIL;
//
// N.B.: Caller has mapped idCmd to internal for us
//
int idCmdEnumFirstInt = _IDToInternal(_idCmdEnumFirst);
if (idCmd >= idCmdEnumFirstInt) { // these are the bands that they're turning on and off
DWORD dwID; if (SUCCEEDED(_pbs->EnumBands(idCmd - idCmdEnumFirstInt, &dwID))) { _pbs->RemoveBand(dwID); } } else { // these are our merged menus from MENU_DESKBARAPP
switch (idCmd) { case DBIDM_NEWFOLDERBAND: _BrowseForNewFolderBand(); break; case DBIDM_DESKTOPBAND: _ToggleSpecialFolderBand(CSIDL_DESKTOP, NULL, FALSE); break; case DBIDM_LAUNCHBAND: { TCHAR szSubDir[MAX_PATH]; MLLoadString(IDS_QLAUNCHAPPDATAPATH, szSubDir, ARRAYSIZE(szSubDir)); // Microsoft\\Internet Explorer\\Quick Launch
_ToggleSpecialFolderBand(CSIDL_APPDATA, szSubDir, TRUE); break; } default: ASSERT(idCmd >= DBIDM_NEWBANDFIXEDLAST); _ToggleComcatBand(idCmd - DBIDM_NEWBANDFIXEDLAST); break; } } return S_OK; }
HRESULT CBandSiteMenu::_BandClassEnum(REFCATID rcatid, REFCLSID rclsid, LPARAM lParam) { TCHAR szName[128], szRegName[128], szClass[GUIDSTR_MAX]; DWORD cbName;
HDPA hdpa = (HDPA)lParam; ASSERT(NULL != hdpa);
// IE4 introduced this band, suppress it since we cut support for it in IE6
if (IsEqualCLSID(CLSID_ChannelBand, rclsid)) { return S_OK; }
BANDCLASSINFO *pbci = (BANDCLASSINFO*)LocalAlloc(LPTR, sizeof(*pbci)); if (NULL == pbci) { return E_OUTOFMEMORY; }
pbci->clsid = rclsid; pbci->catid = rcatid; // now that we have the clsid,
// look in the registry for the display name
SHStringFromGUID(pbci->clsid, szClass, ARRAYSIZE(szClass)); StringCchPrintf(szRegName, ARRAYSIZE(szRegName), TEXT("CLSID\\%s"), szClass);
cbName = ARRAYSIZE(szName); if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT, szRegName, NULL, NULL, szName, &cbName)) { HKEY hkey;
pbci->pszName = StrDup(szName); if (NULL == pbci->pszName) { return E_OUTOFMEMORY; }
if (ERROR_SUCCESS == RegOpenKey(HKEY_CLASSES_ROOT, szRegName, &hkey)) { const struct regstrs rstab[] = { { TEXT("DefaultIcon"), FIELD_OFFSET(BANDCLASSINFO, pszIcon) }, { TEXT("MenuText") , FIELD_OFFSET(BANDCLASSINFO, pszMenu) }, { TEXT("HelpText") , FIELD_OFFSET(BANDCLASSINFO, pszHelp) }, { TEXT("MenuTextPUI"), FIELD_OFFSET(BANDCLASSINFO, pszMenuPUI) }, { TEXT("HelpTextPUI"), FIELD_OFFSET(BANDCLASSINFO, pszHelpPUI) }, { 0, 0 }, };
// szBuf big enough for "path,-32767" or for status text
TCHAR szBuf[MAX_PATH+7];
Reg_GetStrs(hkey, rstab, szBuf, (int)ARRAYSIZE(szBuf), (LPVOID)pbci); RegCloseKey(hkey); }
DPA_AppendPtr(hdpa, pbci); }
return S_OK; }
//***
// Collect band class info from registry...
int CBandSiteMenu::LoadFromComCat(const CATID *pcatid ) { if (NULL == _hdpaBandClasses) { _hdpaBandClasses = DPA_Create(4); }
if (NULL != _hdpaBandClasses && NULL != pcatid) { SHEnumClassesImplementingCATID(*pcatid, CBandSiteMenu::_BandClassEnum, (LPARAM)_hdpaBandClasses); }
return DPA_SafeGetPtrCount(_hdpaBandClasses); }
int CBandSiteMenu::CreateMergeMenu(HMENU hmenu, UINT cMax, UINT iPosition, UINT idCmdFirst, UINT iStart, BOOL fMungeAllowed) { int j = 0; int iMax = DPA_SafeGetPtrCount(_hdpaBandClasses);
for (int i = iStart; i < iMax; i++) { if ((UINT)j >= cMax) { TraceMsg(DM_WARNING, "cbsm.cmm: cMax=%u menu overflow, truncated", cMax); break; }
BANDCLASSINFO *pbci = (BANDCLASSINFO*)DPA_GetPtr(_hdpaBandClasses, i); DWORD dwFlags = IsEqualCLSID(g_clsidNull,pbci->clsid) ? MF_BYPOSITION|MF_SEPARATOR : MF_BYPOSITION; LPTSTR pszMenuText = pbci->pszMenuPUI ? pbci->pszMenuPUI : (pbci->pszMenu ? pbci->pszMenu : pbci->pszName) ;
if (pszMenuText && *pszMenuText) { BOOL fInsert;
if (fMungeAllowed) { fInsert = InsertMenu(hmenu, iPosition + j, dwFlags, idCmdFirst + j, pszMenuText); } else { fInsert = InsertMenu_PrivateNoMungeW(hmenu, iPosition + j, dwFlags, idCmdFirst + j, pszMenuText); }
if (fInsert) { // update menuitem cmd ID:
pbci->idCmd = idCmdFirst + j; j++; } } }
return j + idCmdFirst; }
BANDCLASSINFO * CBandSiteMenu::GetBandClassDataStruct(UINT uBand) { BANDCLASSINFO * pbci = (BANDCLASSINFO *)DPA_GetPtr(_hdpaBandClasses, uBand); return pbci; }
BOOL CBandSiteMenu::DeleteBandClass( REFCLSID rclsid ) { if( _hdpaBandClasses ) { for( int i = 0, cnt = GetBandClassCount( NULL, FALSE ); i< cnt; i++ ) { BANDCLASSINFO * pbci = (BANDCLASSINFO *)DPA_GetPtr( _hdpaBandClasses, i ); ASSERT( pbci ); if( IsEqualCLSID( rclsid, pbci->clsid ) ) { EVAL( DPA_DeletePtr( _hdpaBandClasses, i ) == (LPVOID)pbci );
if( pbci->pszName ) LocalFree(pbci->pszName); LocalFree( pbci ); return TRUE; }
} } return FALSE; }
int CBandSiteMenu::GetBandClassCount(const CATID* pcatid /*NULL*/, BOOL bMergedOnly /*FALSE*/) { int cRet = 0;
if( _hdpaBandClasses != NULL ) { int cBands = DPA_GetPtrCount(_hdpaBandClasses); if( pcatid || bMergedOnly ) // filter request
{ for( int i = 0; i < cBands; i++ ) { BANDCLASSINFO * pbci = (BANDCLASSINFO *)DPA_FastGetPtr( _hdpaBandClasses, i );
if( pbci->idCmd || !bMergedOnly ) { if( pcatid ) { if( IsEqualGUID( pbci->catid, *pcatid ) ) cRet++; } else cRet++; } } } else cRet = cBands; } return cRet; }
void CBandSiteMenu::_AddNewFSBand(LPCITEMIDLIST pidl, BOOL fNoTitleText, DWORD dwPrivID) { IDeskBand *ptb = NULL; BOOL fISF = FALSE;
// this was a drag of a link or folder
// FEATURE: We should use a different test:
// DWORD dwAttrib = (SFGAO_FOLDER | SFGAO_BROWSABLE);
// IEGetAttributesOf(pidl, &dwAttrib);
// if (SFGAO_BROWSABLE != dwAttrib)
// or we could reuse SHCreateBandForPidl().
if (IsURLChild(pidl, TRUE)) { // create browser to show web sites
ptb = CBrowserBand_Create(pidl); } else { IFolderBandPriv *pfbp; // create an ISF band to show folders as hotlinks
fISF = TRUE; ASSERT(pidl); // o.w. CISFBand_CreateEx will fail
if (FAILED(CISFBand_CreateEx(NULL, pidl, IID_PPV_ARG(IFolderBandPriv, &pfbp)))) { // we need to give a pretty
// generic message: "can't create toolbar for %1".
TCHAR szName[MAX_URL_STRING]; szName[0] = 0; SHGetNameAndFlags(pidl, SHGDN_NORMAL, szName, SIZECHARS(szName), NULL); MLShellMessageBox(NULL, MAKEINTRESOURCE(IDS_CANTISFBAND), MAKEINTRESOURCE(IDS_WEBBARTITLE), MB_OK|MB_ICONERROR, szName); } else { pfbp->SetNoText(fNoTitleText); if (SUCCEEDED(pfbp->QueryInterface(IID_PPV_ARG(IDeskBand, &ptb)))) { if (dwPrivID != -1) { VARIANTARG v; v.vt = VT_I4; v.lVal = dwPrivID; // find out if the private id this holds is the same as what we're asking for
IUnknown_Exec(ptb, &CGID_ISFBand, ISFBID_PRIVATEID, 0, &v, NULL); // qlaunch and qlinks get logged
// (should we key off of host or CSIDL or both?)
// FEATURE: UASSIST todo: qlinks NYI
if (dwPrivID == CSIDL_APPDATA) { ASSERT(v.vt == VT_I4); v.lVal = UEMIND_SHELL; // UEMIND_SHELL/BROWSER
IUnknown_Exec(ptb, &CGID_ShellDocView, SHDVID_UEMLOG, 0, &v, NULL); } } } pfbp->Release(); } }
if (ptb) { HRESULT hr = _pbs->AddBand(ptb); if (SUCCEEDED(hr) && fISF) _pbs->SetBandState(ShortFromResult(hr), BSSF_NOTITLE, fNoTitleText ? BSSF_NOTITLE : 0); ptb->Release(); } }
void CBandSiteMenu::_ToggleSpecialFolderBand(int iFolder, LPTSTR pszSubPath, BOOL fNoTitleText) {
DWORD dwBandID; if (SUCCEEDED(_FindBand(&CLSID_ISFBand, iFolder, &dwBandID))) { _pbs->RemoveBand(dwBandID); } else { LPITEMIDLIST pidl; if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, iFolder, &pidl))) { if (pszSubPath) { TCHAR szPath[MAX_PATH]; SHGetPathFromIDList(pidl, szPath); PathCombine(szPath, szPath, pszSubPath); ILFree(pidl); pidl = ILCreateFromPath(szPath); ASSERT(pidl); // o.w. AddNewFSBand will fail
} _AddNewFSBand(pidl, fNoTitleText, iFolder); ILFree(pidl); } } }
int CALLBACK SetCaptionCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { switch (uMsg) { case BFFM_INITIALIZED: TCHAR szTitle[80]; MLLoadShellLangString(IDS_NEWFSBANDCAPTION, szTitle, ARRAYSIZE(szTitle)); SetWindowText(hwnd, szTitle); break; case BFFM_VALIDATEFAILEDA: case BFFM_VALIDATEFAILEDW: MLShellMessageBox(hwnd, uMsg == BFFM_VALIDATEFAILEDA ? MAKEINTRESOURCE(IDS_ERROR_GOTOA) : MAKEINTRESOURCE(IDS_ERROR_GOTOW), MAKEINTRESOURCE(IDS_WEBBARTITLE), MB_OK|MB_ICONERROR, (LPVOID)lParam); return 1; // 1:leave dialog up for another try...
/*NOTREACHED*/
}
return 0; }
void CBandSiteMenu::_BrowseForNewFolderBand() { BROWSEINFO bi = {0}; LPITEMIDLIST pidl; TCHAR szTitle[256]; TCHAR szPath[MAX_URL_STRING];
if (_pbs) IUnknown_GetWindow(_pbs, &bi.hwndOwner);
ASSERT(bi.pidlRoot == NULL);
MLLoadShellLangString(IDS_NEWFSBANDTITLE, szTitle, ARRAYSIZE(szTitle)); bi.lpszTitle = szTitle;
bi.pszDisplayName = szPath; bi.ulFlags = (BIF_EDITBOX | BIF_VALIDATE | BIF_USENEWUI | BIF_BROWSEINCLUDEURLS); bi.lpfn = SetCaptionCallback;
pidl = SHBrowseForFolder(&bi); if (pidl) { _AddNewFSBand(pidl, FALSE, -1); ILFree(pidl); } }
void CBandSiteMenu::_ToggleComcatBand(UINT idCmd) { BANDCLASSINFO* pbci = (BANDCLASSINFO*)DPA_GetPtr(_hdpaBandClasses, idCmd); IUnknown* punk; DWORD dwBandID; if (SUCCEEDED(_FindBand(&pbci->clsid, -1, &dwBandID))) { _pbs->RemoveBand(dwBandID); } else if (S_OK == CoCreateInstance(pbci->clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID*)&punk)) { // Language returns S_FALSE and doesn't initialize punk leave us to fault
IPersistStreamInit * ppsi;
// Some Bands don't work if IPersistStreamInit::InitNew() isn't called.
// This includes the QuickLinks Band.
if (SUCCEEDED(punk->QueryInterface(IID_IPersistStreamInit, (LPVOID*)&ppsi))) { ppsi->InitNew(); ppsi->Release(); }
_pbs->AddBand(punk); punk->Release(); } }
|