|
|
#include "priv.h"
#include "sccls.h"
#include "bands.h"
#include "util.h"
#include "resource.h"
#include "dhuihand.h"
#include "droptgt.h"
#include "iface.h"
#include "isfband.h"
#include "itbdrop.h"
#include "browband.h"
#include <varutil.h>
#include "legacy.h"
#include "mnbandid.h"
#include "mluisupp.h"
#include "inetsmgr.h"
#define DM_PERSIST 0 // trace IPS::Load, ::Save, etc.
#define DM_MENU 0 // menu code
#define DM_FOCUS 0 // focus
#define DM_FOCUS2 0 // like DM_FOCUS, but verbose
//*** CBrowserBand {
//
////////////////
/// BrowserOC band
CBrowserBand::CBrowserBand() : CToolBand() { _fBlockSIDProxy = TRUE; _dwModeFlags = DBIMF_FIXEDBMP | DBIMF_VARIABLEHEIGHT; _sizeMin.cx = _sizeMin.cy = 0; _sizeMax.cx = _sizeMax.cy = 32000; _fCustomTitle = FALSE; return; }
CBrowserBand::~CBrowserBand() { if (_pidl) ILFree(_pidl);
}
HRESULT CBrowserBand::QueryInterface(REFIID riid, void **ppvObj) { static const QITAB qit[] = { QITABENT(CBrowserBand, IContextMenu), // IID_IContextMenu
QITABENT(CBrowserBand, IWinEventHandler), // IID_IWinEventHandler
QITABENT(CBrowserBand, IDispatch), // IID_IDispatch
QITABENT(CBrowserBand, IPersistPropertyBag), // IID_IPersistPropertyBag
QITABENT(CBrowserBand, IBrowserBand), { 0 }, };
HRESULT hres = QISearch(this, qit, riid, ppvObj);
if (FAILED(hres)) hres = CToolBand::QueryInterface(riid, ppvObj);
return hres; }
HRESULT CBrowserBand_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi) { // aggregation checking is handled in class factory
CBrowserBand * p = new CBrowserBand(); if (p) { *ppunk = SAFECAST(p, IDeskBand *); return S_OK; }
return E_OUTOFMEMORY; }
HRESULT SHCreateBandForPidl(LPCITEMIDLIST pidl, IUnknown** ppunk, BOOL fAllowBrowserBand) { IDeskBand *ptb = NULL; BOOL fBrowserBand; DWORD dwAttrib = SFGAO_FOLDER | SFGAO_BROWSABLE; // if it's on the file system, we still might want to create a browser
// band if it's a docobj (including .htm file)
IEGetAttributesOf(pidl, &dwAttrib); switch (dwAttrib & (SFGAO_FOLDER | SFGAO_BROWSABLE)) { case (SFGAO_FOLDER | SFGAO_BROWSABLE): TraceMsg(TF_WARNING, "SHCreateBandForPidl() Find out what the caller wants. Last time we checked, nobody would set this - what does the caller want?"); case SFGAO_BROWSABLE: fBrowserBand = TRUE; break;
case SFGAO_FOLDER: fBrowserBand = FALSE; break; default: // if it's not a folder nor a browseable object, we can't host it.
// Happens when use drags a text file and we want to turn off the
// drop to create a band.
return E_FAIL;
} // this was a drag of a link or folder
if (fBrowserBand) { if (fAllowBrowserBand) { // create browser to show web sites
ptb = CBrowserBand_Create(pidl); } } else { // create an ISF band to show folders as hotlinks
CISFBand_CreateEx(NULL, pidl, IID_PPV_ARG(IDeskBand, &ptb)); }
*ppunk = ptb;
if (ptb) return S_OK;
return E_OUTOFMEMORY;
}
HRESULT CBrowserBand::CloseDW(DWORD dw) { _Connect(FALSE); return CToolBand::CloseDW(dw); }
void CBrowserBand::_Connect(BOOL fConnect) { ConnectToConnectionPoint(SAFECAST(this, IDeskBand*), DIID_DWebBrowserEvents2, fConnect, _pauto, &_dwcpCookie, NULL); }
/////////////////////////////////////////////////////////////////////////////
// IDispatch::Invoke
/////////////////////////////////////////////////////////////////////////////
HRESULT CBrowserBand::Invoke ( DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr ) { ASSERT(pdispparams); if(!pdispparams) return E_INVALIDARG;
//
// NOTES: If we have a custom title, we don't need to process this call.
// This code assumes DISPID_TITLECHANGE is the only id we support.
// If somebody add any other, move this check below.
//
if (_fCustomTitle) return (S_OK);
switch (dispidMember) { case DISPID_TITLECHANGE: { int iArg = pdispparams->cArgs -1; if (iArg == 0 && (pdispparams->rgvarg[iArg].vt == VT_BSTR)) {
BSTR pTitle = pdispparams->rgvarg[iArg].bstrVal; StringCchCopy(_wszTitle, ARRAYSIZE(_wszTitle), pTitle); _BandInfoChanged(); } break; } }
return S_OK; }
///// impl of IServiceProvider
HRESULT CBrowserBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObj) { *ppvObj = NULL; // assume error
if (_fBlockSIDProxy && IsEqualGUID(guidService, SID_SProxyBrowser)) { return E_FAIL; } else if (IsEqualGUID(guidService, SID_STopFrameBrowser)) { // block this so SearchBand doesn't end up in global history
return E_FAIL; } else if (_fBlockDrop && IsEqualGUID(guidService, SID_SDropBlocker)) { return QueryInterface(riid, ppvObj); }
return CToolBand::QueryService(guidService, riid, ppvObj); }
HRESULT CBrowserBand::SetSite(IUnknown* punkSite) { CToolBand::SetSite(punkSite);
if (punkSite != NULL) { if (!_hwnd) _CreateOCHost(); } else {
ATOMICRELEASE(_pauto); ATOMICRELEASE(_poipao); }
return S_OK; }
//*** CBrowserBand::IInputObject::* {
HRESULT CBrowserBand::TranslateAcceleratorIO(LPMSG lpMsg) { #ifdef DEBUG
if (lpMsg && lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F12) { // temp debug test code
_DebugTestCode(); } #endif
if (_poipao) return _poipao->TranslateAccelerator(lpMsg);
return S_FALSE; }
HRESULT CBrowserBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg) { int iVerb = fActivate ? OLEIVERB_UIACTIVATE : OLEIVERB_INPLACEACTIVATE;
HRESULT hr = OCHost_DoVerb(_hwnd, iVerb, lpMsg);
// OCHost UIActivate is different than IInputObject::UIActivateIO. It
// doesn't do anything with the lpMsg parameter. So, we need to pass
// it to them via TranslateAccelerator. Since the only case we care
// about is when they're getting tabbed into (we want them to highlight
// the first/last link), just do this in the case of a tab. However,
// don't give it to them if it's a ctl-tab. The rule is that you shouldn't
// handle ctl-tab when UI-active (ctl-tab switches between contexts), and
// since Trident is always UI-active (for perf?), they'll always reject
// ctl-tab.
if (IsVK_TABCycler(lpMsg) && !IsVK_CtlTABCycler(lpMsg) && _poipao) hr = _poipao->TranslateAccelerator(lpMsg);
return hr; }
// }
//*** CBrowserBand::IOleCommandTarget::* {
HRESULT CBrowserBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT *pcmdtext) { return MayQSForward(_pauto, OCTD_DOWN, pguidCmdGroup, cCmds, rgCmds, pcmdtext); }
HRESULT CBrowserBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut) { // These are broadcast messages to the TRIDENT doc for GUID CGID_MSTHML
if (pguidCmdGroup && IsEqualGUID(CGID_ExplorerBarDoc, *pguidCmdGroup)) { if (_pauto) { LPTARGETFRAME2 ptgf;
if (SUCCEEDED(_pauto->QueryInterface(IID_PPV_ARG(ITargetFrame2, &ptgf)))) { LPOLECONTAINER pocDoc; if (SUCCEEDED(ptgf->GetFramesContainer(&pocDoc)) && pocDoc) { IUnknown_Exec(pocDoc, &CGID_MSHTML, nCmdID, nCmdexecopt, pvarargIn, pvarargOut); pocDoc->Release(); } ptgf->Release(); } } return S_OK; } else { return MayExecForward(_pauto, OCTD_DOWN, pguidCmdGroup, nCmdID, nCmdexecopt, pvarargIn, pvarargOut); } }
// }
HRESULT CBrowserBand::GetBandInfo(DWORD dwBandID, DWORD fViewMode, DESKBANDINFO* pdbi) {
_dwBandID = dwBandID;
// nt5:192868 make sure can't size to smaller than title/scrollbars
// n.b. virt pdbi->pt.x,y is really phys y,x (i.e. phys long,short)
pdbi->ptMinSize.x = _sizeMin.cx; pdbi->ptMinSize.y = max(16, _sizeMin.cy); // FEATURE: 16 is bogus
#ifdef DEBUG
if (pdbi->ptMinSize.x != 0 || pdbi->ptMinSize.y != 0) TraceMsg(DM_TRACE, "cbb.gbi: ptMinSize.(x,y)=%x,%x", pdbi->ptMinSize.x, pdbi->ptMinSize.y); #endif
pdbi->ptMaxSize.x = _sizeMax.cx; pdbi->ptMaxSize.y = _sizeMax.cy; pdbi->dwModeFlags = _dwModeFlags;
pdbi->ptActual.y = -1; pdbi->ptActual.x = -1; pdbi->ptIntegral.y = 1; if (_wszTitle[0]) { StringCchCopy(pdbi->wszTitle, ARRAYSIZE(pdbi->wszTitle), _wszTitle); } else if ( _fCustomTitle) { pdbi->dwMask &= ~DBIM_TITLE; } else{ SHGetNameAndFlagsW(_pidl, SHGDN_NORMAL, pdbi->wszTitle, SIZECHARS(pdbi->wszTitle), NULL); } return S_OK; }
void CBrowserBand::_InitBrowser(void) { ASSERT(IsWindow(_hwnd));
OCHost_QueryInterface(_hwnd, IID_PPV_ARG(IWebBrowser2, &_pauto)); OCHost_SetOwner(_hwnd, SAFECAST(this, IContextMenu*));
if (EVAL(_pauto)) { LPTARGETFRAME2 ptgf;
if (SUCCEEDED(_pauto->QueryInterface(IID_PPV_ARG(ITargetFrame2, &ptgf)))) { DWORD dwOptions;
if (SUCCEEDED(ptgf->GetFrameOptions(&dwOptions))) { dwOptions |= FRAMEOPTIONS_BROWSERBAND | FRAMEOPTIONS_SCROLL_AUTO; ptgf->SetFrameOptions(dwOptions); } ptgf->Release(); }
_pauto->put_RegisterAsDropTarget(VARIANT_FALSE);
// BUG do OCHost_QI
// note only 1 active object (proxy)
_pauto->QueryInterface(IID_PPV_ARG(IOleInPlaceActiveObject, &_poipao)); ASSERT(_poipao != NULL); // set up the connection point
_Connect(TRUE); } }
HRESULT CBrowserBand::_NavigateOC() { HRESULT hres = E_FAIL; if (_hwnd) { ASSERT(IsWindow(_hwnd)); if (!_pidl) { if (_pauto) { hres = _pauto->GoHome(); } } else { IServiceProvider* psp = NULL;
OCHost_QueryInterface(_hwnd, IID_PPV_ARG(IServiceProvider, &psp)); if (psp) { IShellBrowser* psb; if (EVAL(SUCCEEDED(psp->QueryService(SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &psb))))) { hres = psb->BrowseObject(_pidl, SBSP_SAMEBROWSER); psb->Release(); } psp->Release(); }
} }
return hres; }
HRESULT CBrowserBand::_CreateOCHost() { HRESULT hres = E_FAIL; // assume error
// Register the OCHost window class
SHDRC shdrc = {sizeof(SHDRC), SHDRCF_OCHOST}; shdrc.cbSize = sizeof (SHDRC); shdrc.dwFlags |= SHDRCF_OCHOST; if (DllRegisterWindowClasses(&shdrc)) { // Create an OCHost window
_hwnd = CreateWindow(OCHOST_CLASS, NULL, WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_TABSTOP, 0, 0, 1, 1, _hwndParent, NULL, HINST_THISDLL, NULL);
if (_hwnd) { OCHINITSTRUCT ocs; ocs.cbSize = SIZEOF(OCHINITSTRUCT); ocs.clsidOC = CLSID_WebBrowser; ocs.punkOwner = SAFECAST(this, IDeskBand*);
hres = OCHost_InitOC(_hwnd, (LPARAM)&ocs);
_InitBrowser(); _NavigateOC(); OCHost_DoVerb(_hwnd, OLEIVERB_INPLACEACTIVATE, FALSE); } } return hres; }
//*** CBrowserBand::IWinEventHandler::* {
HRESULT CBrowserBand::OnWinEvent(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plres) { switch (uMsg) { case WM_NOTIFY: _OnNotify((LPNMHDR)lParam); return S_OK; default: break; }
return E_FAIL; }
HRESULT CBrowserBand::IsWindowOwner(HWND hwnd) { HRESULT hres;
hres = SHIsChildOrSelf(_hwnd, hwnd); ASSERT(hwnd != NULL || hres == S_FALSE); ASSERT(_hwnd != NULL || hres == S_FALSE); return hres; }
#if 0
static void HackFocus(HWND hwndFrom) { TraceMsg(DM_FOCUS, "HackFocus: GetFocus()=%x hwndOCHost=%x", GetFocus(), hwndFrom); hwndFrom = GetWindow(hwndFrom, GW_CHILD); // OCHost->shembed
TraceMsg(DM_FOCUS, "HackFocus: hwndShEmbed=%x", hwndFrom); hwndFrom = GetWindow(hwndFrom, GW_CHILD); // shembed->shdocvw
TraceMsg(DM_FOCUS, "HackFocus: hwndShDocVw=%x", hwndFrom); hwndFrom = GetWindow(hwndFrom, GW_CHILD); // shdocvw->iesvr
TraceMsg(DM_FOCUS, "HackFocus: hwndIESvr=%x", hwndFrom); if (hwndFrom != 0) { TraceMsg(DM_FOCUS, "HackFocus: SetFocus(%x)", hwndFrom); SetFocus(hwndFrom); } return; } #endif
LRESULT CBrowserBand::_OnNotify(LPNMHDR pnm) { switch (pnm->code) { case OCN_ONUIACTIVATE: // UIActivate
ASSERT(SHIsSameObject(((LPOCNONUIACTIVATEMSG)pnm)->punk, _poipao)); // n.b. we pass up 'this' not pnm->punk, since we always want to
// be the intermediary (e.g. for UIActivateIO calls to us)
IUnknown_OnFocusChangeIS(_punkSite, SAFECAST(this, IInputObject*), TRUE); return OCNONUIACTIVATE_HANDLED;
case OCN_ONSETSTATUSTEXT: { HRESULT hr = E_FAIL; IShellBrowser *psb;
hr = QueryService(SID_STopLevelBrowser, IID_PPV_ARG(IShellBrowser, &psb)); if (SUCCEEDED(hr)) { hr = psb->SetStatusTextSB(((LPOCNONSETSTATUSTEXTMSG)pnm)->pwszStatusText); psb->Release(); } } break;
case OCN_ONPOSRECTCHANGE: { LPCRECT lprcPosRect = ((LPOCNONPOSRECTCHANGEMSG)pnm)->prcPosRect; _sizeMin.cx = lprcPosRect->right - lprcPosRect->left; _sizeMin.cy = lprcPosRect->bottom - lprcPosRect->top;
_BandInfoChanged();
break; }
default: break; }
ASSERT(OCNONUIACTIVATE_HANDLED != 0); return 0; }
// }
//*** CBrowserBand::IPersistStream::* {
HRESULT CBrowserBand::GetClassID(CLSID *pClassID) { *pClassID = CLSID_BrowserBand;
return S_OK; }
// mask flags for BrowserBand persistence
//
#define BB_ILSTREAM 0x00000001
#define BB_PIDLASLINK 0x00000002
// FEATURE: REVIEW: it seems to me like we should let the WebBrowserOC
// persist it's location, not us...
//
HRESULT CBrowserBand::Load(IStream *pstm) { if (_pidl) { ILFree(_pidl); }
DWORD dw; HRESULT hr = pstm->Read(&dw, sizeof(dw), NULL); if (SUCCEEDED(hr)) { if (dw & BB_PIDLASLINK) { hr = LoadPidlAsLink(_punkSite, pstm, &_pidl); } else if (dw & BB_ILSTREAM) // for backwards compat
{ hr = ILLoadFromStream(pstm, &_pidl); } } if (SUCCEEDED(hr)) _NavigateOC(); return hr; }
HRESULT CBrowserBand::Save(IStream *pstm, BOOL fClearDirty) { HRESULT hres; DWORD dw = 0; BSTR bstrUrl = NULL;
if (_pauto && SUCCEEDED(_pauto->get_LocationURL(&bstrUrl)) && bstrUrl) { TraceMsg(DM_PERSIST, "cbb.s: current/new url=%s", bstrUrl); if (_pidl) { ILFree(_pidl); _pidl = NULL; // paranoia
} IECreateFromPath(bstrUrl, &_pidl); SysFreeString(bstrUrl); }
if (_pidl) dw |= BB_PIDLASLINK;
hres = pstm->Write(&dw, SIZEOF(DWORD), NULL);
if (SUCCEEDED(hres) && (dw & BB_PIDLASLINK)) hres = SavePidlAsLink(_punkSite, pstm, _pidl); return hres; }
// }
//*** CBrowserBand::IPersistPropertyBag::* {
HRESULT CBrowserBand::Load(IPropertyBag *pPBag, IErrorLog *pErrLog) { TraceMsg(DM_TRACE, "cbb.l(bag): enter");
if (_pidl) { ILFree(_pidl); }
TCHAR szUrl[MAX_URL_STRING]; HRESULT hr = SHPropertyBag_ReadStr(pPBag, L"Url", szUrl, ARRAYSIZE(szUrl)); if (SUCCEEDED(hr)) { PCTSTR pszFinalUrl = szUrl; TCHAR szPlug[MAX_PATH]; TCHAR szMuiPath[MAX_PATH];
hr = SHPropertyBag_ReadStr(pPBag, L"Pluggable", szPlug, ARRAYSIZE(szPlug));
if (SUCCEEDED(hr) && !StrCmpNI(TEXT("yes"), szPlug, ARRAYSIZE(szPlug))) { // if this is loading html out of the windows\web folder
// then we need to call SHGetWebFolderFilePath in order
// to support pluggable UI
hr = SHGetWebFolderFilePath(PathFindFileName(szUrl), szMuiPath, ARRAYSIZE(szMuiPath)); if (SUCCEEDED(hr)) { pszFinalUrl = szMuiPath; } }
hr = IECreateFromPath(pszFinalUrl, &_pidl); if (SUCCEEDED(hr)) { _NavigateOC(); } } return hr; }
// }
//*** CBrowserBand::IContextMenu::* {
HRESULT CBrowserBand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { int i = 0; HMENU hmenuMe = LoadMenuPopup_PrivateNoMungeW(MENU_BROWBAND);
i += Shell_MergeMenus(hmenu, hmenuMe, indexMenu, idCmdFirst + i, idCmdLast, MM_ADDSEPARATOR) - (idCmdFirst + i); DestroyMenu(hmenuMe);
// aka (S_OK|i)
return MAKE_HRESULT(ERROR_SUCCESS, FACILITY_NULL, i); }
HRESULT CBrowserBand::InvokeCommand(LPCMINVOKECOMMANDINFO pici) { TraceMsg(DM_MENU, "cbb.ic");
HRESULT hres; int idCmd = -1;
// FEATURE: todo: id -= _idCmdFirst ???
if (!HIWORD(pici->lpVerb)) idCmd = LOWORD(pici->lpVerb);
//
// Low memory paranoia safety check
//
if (!_pauto) { TraceMsg(DM_ERROR, "CBrowserBand::InvokeCommand: _pauto IS NULL"); return E_OUTOFMEMORY; }
switch (idCmd) { case IDM_BROWBAND_REFRESH: #ifdef DEBUG
if (GetKeyState(VK_SHIFT) < 0) hres = _pauto->GoHome(); else #endif
hres = _pauto->Refresh(); break; case IDM_BROWBAND_OPENNEW: // clone window into 'real' browser
{ BSTR bstrURL = NULL;
// n.b. this clones the *current page* into a 'real' browser,
// not the link.
// FEATURE: todo: we'd really rather get and navigate to
// a PIDL, but that isn't supported yet in ie4.
hres = _pauto->get_LocationURL(&bstrURL); if (SUCCEEDED(hres)) { VARIANT varFlags;
VariantInit(&varFlags); varFlags.vt = VT_I4; varFlags.lVal = (navOpenInNewWindow|navNoHistory);
// n.b. we drop the post data etc. on the floor, oh well...
hres = _pauto->Navigate(bstrURL, /*flags*/&varFlags, /*targ*/NULL, /*post*/NULL, /*hdrs*/NULL);
VariantClear(&varFlags); }
if (bstrURL) SysFreeString(bstrURL);
ASSERT(SUCCEEDED(hres));
break; } default: TraceMsg(DM_ERROR, "cbb::ic cmd=%d not handled", idCmd); break; }
return S_OK; }
// }
SIZE CBrowserBand::_GetCurrentSize() { SIZE size;
RECT rc; GetWindowRect(_hwnd, &rc);
size.cx = RECTWIDTH(rc); size.cy = RECTHEIGHT(rc);
return size; }
// *** IBrowserBand methods ***
HRESULT CBrowserBand::GetObjectBB(REFIID riid, LPVOID *ppv) { return _pauto ? _pauto->QueryInterface(riid, ppv) : E_UNEXPECTED; }
#ifdef DEBUG
void CBrowserBand::_DebugTestCode() { DWORD dwMask = 0x10000000; // non-NULL bogus mask
BROWSERBANDINFO bbi; bbi.cbSize = SIZEOF(BROWSERBANDINFO);
GetBrowserBandInfo(dwMask, &bbi); } #endif // DEBUG
void CBrowserBand::_MakeSizesConsistent(LPSIZE psizeCur) { // _sizeMin overrules _sizeMax
if (_dwModeFlags & DBIMF_FIXED) { // if they specified a current size, use that instead
// of min size
if (psizeCur) _sizeMin = *psizeCur; _sizeMax = _sizeMin; } else { _sizeMax.cx = max(_sizeMin.cx, _sizeMax.cx); _sizeMax.cy = max(_sizeMin.cy, _sizeMax.cy);
if (psizeCur) { psizeCur->cx = max(_sizeMin.cx, psizeCur->cx); psizeCur->cy = max(_sizeMin.cy, psizeCur->cy);
psizeCur->cx = min(_sizeMax.cx, psizeCur->cx); psizeCur->cy = min(_sizeMax.cy, psizeCur->cy); } } }
HRESULT CBrowserBand::SetBrowserBandInfo(DWORD dwMask, PBROWSERBANDINFO pbbi) { if (!pbbi || pbbi->cbSize != SIZEOF(BROWSERBANDINFO)) return E_INVALIDARG;
if (!dwMask || (dwMask & BBIM_MODEFLAGS)) _dwModeFlags = pbbi->dwModeFlags;
if (!dwMask || (dwMask & BBIM_TITLE)) { if (pbbi->bstrTitle) { _fCustomTitle = TRUE; // Change the internal _wszTitle used by Browser band
StringCchCopy(_wszTitle, ARRAYSIZE(_wszTitle), pbbi->bstrTitle); } else { _fCustomTitle = FALSE; } }
if (!dwMask || (dwMask & BBIM_SIZEMIN)) _sizeMin = pbbi->sizeMin;
if (!dwMask || (dwMask & BBIM_SIZEMAX)) _sizeMax = pbbi->sizeMax;
if (!dwMask || (dwMask & BBIM_SIZECUR)) { SIZE sizeCur = pbbi->sizeCur; _MakeSizesConsistent(&sizeCur);
// HACKHACK: the only way to tell bandsite to change the height of a horizontal
// band is to give it a new min/max height pair at the desired height. the same
// holds for setting the width of a vertical band. so we temporarily give bandsite
// new min/max size info, then restore old min/max.
SIZE sizeMinOld = _sizeMin; SIZE sizeMaxOld = _sizeMax; _sizeMin = _sizeMax = sizeCur;
_BandInfoChanged();
_sizeMin = sizeMinOld; _sizeMax = sizeMaxOld; } else { _MakeSizesConsistent(NULL); }
_BandInfoChanged();
return S_OK; }
// we don't have a client to test BBIM_TITLE, so leave it unimplemented for now.
#define BBIM_INVALIDFLAGS (~(BBIM_SIZEMIN | BBIM_SIZEMAX | BBIM_SIZECUR | BBIM_MODEFLAGS))
HRESULT CBrowserBand::GetBrowserBandInfo(DWORD dwMask, PBROWSERBANDINFO pbbi) { if (!pbbi || pbbi->cbSize != SIZEOF(BROWSERBANDINFO)) return E_INVALIDARG;
if (dwMask & BBIM_INVALIDFLAGS) return E_INVALIDARG;
pbbi->dwModeFlags = _dwModeFlags; pbbi->sizeMin = _sizeMin; pbbi->sizeMax = _sizeMax; pbbi->sizeCur =_GetCurrentSize();
return S_OK; }
IDeskBand* CBrowserBand_Create(LPCITEMIDLIST pidl) { CBrowserBand *p = new CBrowserBand(); if(p) { if (pidl) p->_pidl = ILClone(pidl); } return p; }
// }
class CSearchSecurityMgrImpl : public CInternetSecurityMgrImpl { // *** IID_IInternetSecurityManager ***
virtual STDMETHODIMP ProcessUrlAction(LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved) { HRESULT hres = INET_E_DEFAULT_ACTION;
switch (dwAction) { case URLACTION_ACTIVEX_RUN: case URLACTION_SCRIPT_RUN: case URLACTION_SCRIPT_SAFE_ACTIVEX: case URLACTION_HTML_SUBMIT_FORMS: if (_IsSafeUrl(pwszUrl)) { if (cbPolicy >= SIZEOF(DWORD)) { *(DWORD *)pPolicy = URLPOLICY_ALLOW; hres = S_OK; } else { hres = S_FALSE; } } break; } return hres; } };
class CCustomizeSearchHelper : public CInternetSecurityMgrImpl, public IServiceProvider { public:
CCustomizeSearchHelper() : _cRef(1) { } // *** IUnknown ***
virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj); virtual STDMETHODIMP_(ULONG) AddRef(void); virtual STDMETHODIMP_(ULONG) Release(void);
// *** IID_IInternetSecurityManager ***
virtual STDMETHODIMP ProcessUrlAction(LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved);
// *** IServiceProvider ***
virtual STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
virtual BOOL _IsSafeUrl(LPCWSTR pwszUrl) { return TRUE; }
private: ~CCustomizeSearchHelper() {}; ULONG _cRef; };
STDMETHODIMP_(ULONG) CCustomizeSearchHelper::AddRef() { return ++_cRef; }
STDMETHODIMP_(ULONG) CCustomizeSearchHelper::Release(void) { if( 0L != --_cRef ) return _cRef;
delete this; return 0L; }
HRESULT CCustomizeSearchHelper::QueryInterface(REFIID riid, void **ppvObj) { static const QITAB qit[] = { QITABENT(CCustomizeSearchHelper, IServiceProvider), QITABENT(CCustomizeSearchHelper, IInternetSecurityManager), { 0 }, };
return QISearch(this, qit, riid, ppvObj); }
HRESULT CCustomizeSearchHelper::ProcessUrlAction(LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved) { HRESULT hres = INET_E_DEFAULT_ACTION;
switch (dwAction) { case URLACTION_ACTIVEX_RUN: case URLACTION_SCRIPT_RUN: case URLACTION_SCRIPT_SAFE_ACTIVEX: case URLACTION_HTML_SUBMIT_FORMS: if (cbPolicy >= SIZEOF(DWORD)) { *(DWORD *)pPolicy = URLPOLICY_ALLOW; hres = S_OK; } else { hres = S_FALSE; } break; } return hres; }
STDMETHODIMP CCustomizeSearchHelper::QueryService(REFGUID guidService, REFIID riid, void **ppvObject) { if (IID_IInternetSecurityManager == guidService) { return QueryInterface(riid, ppvObject); } else { *ppvObject = NULL; return E_NOINTERFACE; } }
//*** CSearchBand {
//
////////////////
/// Search (BrowserOC) band
// If you change this, change shdocvw also.
const WCHAR c_wszThisBandIsYourBand[] = L"$$SearchBand$$";
#define SEARCH_MENUID_OFFSET 100
class CSearchBand : public CBrowserBand, public IBandNavigate, public ISearchBandTBHelper, public CSearchSecurityMgrImpl { public: // *** IUnknown ***
virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj); virtual STDMETHODIMP_(ULONG) AddRef(void); virtual STDMETHODIMP_(ULONG) Release(void);
// *** IDeskBand methods ***
virtual STDMETHODIMP GetBandInfo(DWORD dwBandID, DWORD fViewMode, DESKBANDINFO* pdbi);
// *** IPersistStream methods ***
// (others use base class implementation)
virtual STDMETHODIMP GetClassID(CLSID *pClassID); virtual STDMETHODIMP Load(IStream *pStm); virtual STDMETHODIMP Save(IStream *pStm, BOOL fClearDirty);
// *** IBandNavigate ***
virtual STDMETHODIMP Select(LPCITEMIDLIST pidl);
// *** IOleCommandTarget methods ***
virtual STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
// *** IDockingWindow methods ***
virtual STDMETHODIMP ShowDW(BOOL fShow);
// *** ISearchBandTBHelper methods ***
virtual STDMETHODIMP AddNextMenuItem(LPCWSTR pwszText, int idItem); virtual STDMETHODIMP ResetNextMenu(); virtual STDMETHODIMP SetOCCallback(IOleCommandTarget *pOleCmdTarget); virtual STDMETHODIMP NavigateToPidl(LPCITEMIDLIST pidl);
// *** IServiceProvider methods ***
virtual STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, LPVOID* ppvObj);
// *** IWinEventHandler ***
virtual STDMETHODIMP OnWinEvent(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plres);
protected: CSearchBand(); virtual ~CSearchBand();
virtual void _Connect(BOOL fConnect); virtual void _InitBrowser(void); virtual HRESULT _NavigateOC(); void _AddButtons(BOOL fAdd); void _OnNextButtonSelect(int x, int y); void _OnNew(); void _DoNext(int newPos); void _OnNextButtonClick(); void _OnCustomize(); void _OnHelp(); void _NavigateToUrl(LPCTSTR pszUrl); void _EnsureImageListsLoaded(); void _EnableNext(BOOL bEnable); void _NavigateToSearchUrl();
virtual BOOL _IsSafeUrl(LPCWSTR pwszUrl); BOOL _fStrsAdded; LONG_PTR _lStrOffset;
IOleCommandTarget *_pOCCmdTarget;
HIMAGELIST _himlNormal; HIMAGELIST _himlHot;
friend HRESULT CSearchBand_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi); // for ctor
friend IDeskBand* CSearchBand_Create();
HMENU _hmenuNext; HWND _hwndParent; int _nextPos;
BOOL _bNewUrl; // set to true when we are QS'd for IInternetSecurityMgr, i.e. when pane is renavigated
BOOL _bUseDefault; // true if we should not use our security mgr
WCHAR _wszCache[MAX_URL_STRING]; DWORD _nCmpLength; BOOL _bIsCacheSafe; };
CSearchBand::CSearchBand() : CBrowserBand() { _fBlockSIDProxy = FALSE; _fBlockDrop = TRUE; _bNewUrl = TRUE; ASSERT(_wszCache[0] == TEXT('\0')); ASSERT(_nCmpLength == 0); ASSERT(_bIsCacheSafe == FALSE); }
CSearchBand::~CSearchBand() { ResetNextMenu();
if (NULL != _himlNormal) { ImageList_Destroy(_himlNormal); } if (NULL != _himlHot) { ImageList_Destroy(_himlHot); }
ATOMICRELEASE(_pOCCmdTarget); }
void CSearchBand::_NavigateToUrl(LPCTSTR pszUrl) { if (NULL != _pidl) { ILFree(_pidl); }
IECreateFromPath(pszUrl, &_pidl); _NavigateOC(); }
void CSearchBand::_NavigateToSearchUrl() { TCHAR szUrl[INTERNET_MAX_URL_LENGTH]; BOOL bFound; BOOL bWebSearch = FALSE; IBrowserService2 *pbs; if (SUCCEEDED(IUnknown_QueryService(_punkSite, SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService2, &pbs)))) { ITEMIDLIST *pidl;
if (SUCCEEDED(pbs->GetPidl(&pidl))) { // FEATURE: This code should be using IShellFolder2::GetDefaultSearchGUID() and
// keying off SRCID_SWebSearch (vs. SRCID_SFileSearch/SRCID_SFindComputer/SRCID_SFindPrinter)
bWebSearch = ILIsWeb(pidl); ILFree(pidl); } pbs->Release(); }
ResetNextMenu();
if (bWebSearch) { bFound = GetDefaultInternetSearchUrl(szUrl, ARRAYSIZE(szUrl), TRUE); } else { bFound = GetSearchAssistantUrl(szUrl, ARRAYSIZE(szUrl), TRUE, FALSE); }
if (bFound) { _NavigateToUrl(szUrl); } }
void CSearchBand::_OnNew() { VARIANT var; var.vt = VT_BOOL; var.boolVal = VARIANT_FALSE;
if (NULL != _pOCCmdTarget) { HRESULT hr = _pOCCmdTarget->Exec(NULL, SBID_SEARCH_NEW, 0, NULL, &var); if (FAILED(hr)) { var.boolVal = VARIANT_FALSE; } }
if ((var.vt != VT_BOOL) || (!var.boolVal)) { _NavigateToSearchUrl(); } }
void CSearchBand::_OnNextButtonSelect(int x, int y) { HWND hwnd;
if (SUCCEEDED(IUnknown_GetWindow(_punkSite, &hwnd))) { int idItem = TrackPopupMenu(_hmenuNext, TPM_RETURNCMD, x, y, 0, hwnd, NULL);
if (0 != idItem) { _DoNext(GetMenuPosFromID(_hmenuNext, idItem)); } } }
void CSearchBand::_DoNext(int newPos) { if (NULL != _pOCCmdTarget) { CheckMenuItem(_hmenuNext, _nextPos, MF_BYPOSITION | MF_UNCHECKED);
_nextPos = newPos;
CheckMenuItem(_hmenuNext, _nextPos, MF_BYPOSITION | MF_CHECKED);
VARIANT var; var.vt = VT_I4; var.lVal = GetMenuItemID(_hmenuNext, _nextPos) - SEARCH_MENUID_OFFSET; HRESULT hr = _pOCCmdTarget->Exec(NULL, SBID_SEARCH_NEXT, 0, &var, NULL); ASSERT(SUCCEEDED(hr)); } }
void CSearchBand::_OnNextButtonClick() { int newPos = _nextPos + 1; if (newPos >= GetMenuItemCount(_hmenuNext)) { newPos = 0; }
_DoNext(newPos); }
void CSearchBand::_OnCustomize() { TCHAR szUrl[INTERNET_MAX_URL_LENGTH]; HWND hwnd;
IUnknown_GetWindow(_punkSite, &hwnd);
if (GetSearchAssistantUrl(szUrl, ARRAYSIZE(szUrl), TRUE, TRUE)) { if (InternetGoOnline(szUrl, hwnd, 0)) { IMoniker *pmk;
if (SUCCEEDED(CreateURLMoniker(NULL, szUrl, &pmk))) { IHostDialogHelper *pTridentAPI; if (SUCCEEDED(CoCreateInstance(CLSID_HostDialogHelper, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IHostDialogHelper, &pTridentAPI)))) { IUnknown *punkCustHelper = NULL;
if (_IsSafeUrl(szUrl)) { punkCustHelper = (IUnknown *)(IServiceProvider *)new CCustomizeSearchHelper; }
pTridentAPI->ShowHTMLDialog(hwnd, pmk, NULL, L"help:no;resizable:1", NULL, punkCustHelper);
if (NULL != punkCustHelper) { punkCustHelper->Release(); }
pTridentAPI->Release(); }
pmk->Release(); } } } }
void CSearchBand::_OnHelp() { HWND hwnd;
IUnknown_GetWindow(_punkSite, &hwnd);
SHHtmlHelpOnDemandWrap(hwnd, TEXT("iexplore.chm > iedefault"), 0, (DWORD_PTR) TEXT("srchasst.htm"), ML_CROSSCODEPAGE);
}
HRESULT CSearchBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut) { if (pguidCmdGroup && IsEqualGUID(CGID_SearchBand, *pguidCmdGroup)) { switch (nCmdID) { case SBID_SEARCH_NEW: _OnNew(); return S_OK;
case SBID_SEARCH_NEXT: if (nCmdexecopt == OLECMDEXECOPT_PROMPTUSER) { if ((NULL != pvarargIn) && (pvarargIn->vt == VT_I4)) { ASSERT(NULL != _hmenuNext); _OnNextButtonSelect(GET_X_LPARAM(pvarargIn->lVal), GET_Y_LPARAM(pvarargIn->lVal)); } } else { _OnNextButtonClick(); } return S_OK;
case SBID_SEARCH_CUSTOMIZE: _OnCustomize(); return S_OK;
case SBID_SEARCH_HELP: _OnHelp(); return S_OK;
case SBID_HASPIDL: // Simply return whether or not the band has a pidl
if (_pidl) return S_OK; else return S_FALSE; case SBID_GETPIDL: { HRESULT hres = E_INVALIDARG; if (pvarargOut) { hres = E_OUTOFMEMORY; VariantInit(pvarargOut); // zero init it
if (!_pidl || SUCCEEDED(InitVariantFromIDList(pvarargOut, _pidl))) hres = S_OK; } return hres; } } } return CBrowserBand::Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvarargIn, pvarargOut); }
#define INDEX_NEXT 1
#define INDEX_CUSTOMIZE 3
static const TBBUTTON c_tbSearch[] = { { 0, SBID_SEARCH_NEW, TBSTATE_ENABLED, BTNS_AUTOSIZE | BTNS_SHOWTEXT, {0, 0}, 0, 0}, { 1, SBID_SEARCH_NEXT, 0, BTNS_AUTOSIZE | BTNS_DROPDOWN | BTNS_SHOWTEXT, {0, 0}, 0, 1}, { 0, 0, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0}, { I_IMAGENONE, SBID_SEARCH_CUSTOMIZE, TBSTATE_ENABLED, BTNS_AUTOSIZE | BTNS_SHOWTEXT, {0, 0}, 0, 2} };
void CSearchBand::_EnableNext(BOOL bEnable) { IExplorerToolbar* piet;
if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IExplorerToolbar, &piet)))) { UINT state;
if (SUCCEEDED(piet->GetState(&CGID_SearchBand, SBID_SEARCH_NEXT, &state))) { if (bEnable) { state |= TBSTATE_ENABLED; } else { state &= ~TBSTATE_ENABLED; } piet->SetState(&CGID_SearchBand, SBID_SEARCH_NEXT, state); }
piet->Release(); } }
void CSearchBand::_AddButtons(BOOL fAdd) { IExplorerToolbar* piet;
if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IExplorerToolbar, &piet)))) { if (fAdd) { piet->SetCommandTarget((IUnknown*)SAFECAST(this, IOleCommandTarget*), &CGID_SearchBand, 0);
if (!_fStrsAdded) { LONG_PTR cbOffset; piet->AddString(&CGID_SearchBand, MLGetHinst(), IDS_SEARCH_BAR_LABELS, &cbOffset); _lStrOffset = cbOffset; _fStrsAdded = TRUE; }
_EnsureImageListsLoaded(); piet->SetImageList(&CGID_SearchBand, _himlNormal, _himlHot, NULL);
TBBUTTON tbSearch[ARRAYSIZE(c_tbSearch)]; UpdateButtonArray(tbSearch, c_tbSearch, ARRAYSIZE(c_tbSearch), _lStrOffset);
if (SHRestricted2(REST_NoSearchCustomization, NULL, 0)) { tbSearch[INDEX_CUSTOMIZE].fsState &= ~TBSTATE_ENABLED; }
if (NULL != _hmenuNext) { tbSearch[INDEX_NEXT].fsState |= TBSTATE_ENABLED; }
piet->AddButtons(&CGID_SearchBand, ARRAYSIZE(tbSearch), tbSearch); } else piet->SetCommandTarget(NULL, NULL, 0);
piet->Release(); } }
void CSearchBand::_EnsureImageListsLoaded() { if (_himlNormal == NULL) { _himlNormal = ImageList_LoadImage(HINST_THISDLL, MAKEINTRESOURCE(IDB_SEARCHBANDDEF), 18, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION); }
if (_himlHot == NULL) { _himlHot = ImageList_LoadImage(HINST_THISDLL, MAKEINTRESOURCE(IDB_SEARCHBANDHOT), 18, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION); } }
HRESULT CSearchBand::AddNextMenuItem(LPCWSTR pwszText, int idItem) { if (NULL == _hmenuNext) { _hmenuNext = CreatePopupMenu(); }
ASSERT(NULL != _hmenuNext);
if (NULL != _hmenuNext) {
#ifdef DEBUG
// Check to see if an item with this ID has already been added
MENUITEMINFO dbgMii = { sizeof(dbgMii) }; dbgMii.fMask = MIIM_STATE; if (GetMenuItemInfo(_hmenuNext, idItem + SEARCH_MENUID_OFFSET, FALSE, &dbgMii)) { TraceMsg(DM_ERROR, "Adding duplicate menu item in CSearchBand::AddNextMenuItem"); } #endif
int nItems = GetMenuItemCount(_hmenuNext); MENUITEMINFOW mii = { sizeof(mii) };
mii.fMask = MIIM_ID | MIIM_TYPE; mii.wID = (WORD)idItem + SEARCH_MENUID_OFFSET; mii.fType = MFT_RADIOCHECK | MFT_STRING; mii.dwTypeData = (LPWSTR)pwszText; mii.cch = lstrlenW(pwszText);
BOOL result = InsertMenuItemW(_hmenuNext, nItems, TRUE, &mii);
if (result) { if (0 == nItems) { CheckMenuItem(_hmenuNext, 0, MF_BYPOSITION | MF_CHECKED); _EnableNext(TRUE); } } } return S_OK; }
HRESULT CSearchBand::ResetNextMenu() { if (NULL != _hmenuNext) { _nextPos = 0; _EnableNext(FALSE); DestroyMenu(_hmenuNext); _hmenuNext = NULL; } return S_OK; }
HRESULT CSearchBand::SetOCCallback(IOleCommandTarget *pOleCmdTarget) { ResetNextMenu();
ATOMICRELEASE(_pOCCmdTarget);
_pOCCmdTarget = pOleCmdTarget;
if (NULL != _pOCCmdTarget) { _pOCCmdTarget->AddRef(); } return S_OK; }
//
// CSearchBand::NavigateToPidl
//
// Implements ISearchBandTBHelper::NavigateToPidl
//
// This is *almost* the same as CSearchBand::Select, except that it always navigates, whereas
// CSearchBand::Select will skip navigation if the search band is already displaying that pidl.
// We need that function to retain that behavior so that the search pane retains its results when
// opened.
//
HRESULT CSearchBand::NavigateToPidl(LPCITEMIDLIST pidl) { ILFree(_pidl); _pidl = ILClone(pidl); return _NavigateOC(); }
HRESULT CSearchBand::ShowDW(BOOL fShow) {
HRESULT hres = CBrowserBand::ShowDW(fShow); _AddButtons(fShow); return hres; }
HRESULT CSearchBand_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi) { *ppunk = NULL;
// aggregation checking is handled in class factory
HRESULT hr = CreateFromRegKey(REGSTR_PATH_EXPLORER, TEXT("WebFindBandHook"), IID_PPV_ARG(IUnknown, ppunk)); if (FAILED(hr)) { CSearchBand *p = new CSearchBand(); if (p) { *ppunk = SAFECAST(p, IDeskBand*); hr = S_OK; } else { hr = E_OUTOFMEMORY; } } return hr; }
IDeskBand* CSearchBand_Create() { IDeskBand* pistb = NULL;
IUnknown *punk; HRESULT hr = CSearchBand_CreateInstance(NULL, &punk, NULL); if (SUCCEEDED(hr)) { punk->QueryInterface(IID_PPV_ARG(IDeskBand, &pistb)); ASSERT(pistb); punk->Release(); } return pistb; }
HRESULT CSearchBand::QueryInterface(REFIID riid, void **ppvObj) { static const QITAB qit[] = { QITABENT(CSearchBand, IContextMenu), QITABENT(CSearchBand, IBandNavigate), QITABENT(CSearchBand, ISearchBandTBHelper), QITABENT(CSearchBand, IServiceProvider), QITABENT(CSearchBand, IInternetSecurityManager), { 0 }, };
HRESULT hres = QISearch(this, qit, riid, ppvObj);
if (FAILED(hres)) hres = CBrowserBand::QueryInterface(riid, ppvObj);
return hres; }
ULONG CSearchBand::AddRef() { return CBrowserBand::AddRef(); }
ULONG CSearchBand::Release() { return CBrowserBand::Release(); }
void CSearchBand::_Connect(BOOL fConnect) { CBrowserBand::_Connect(fConnect);
// Now we need to expose ourselves so the control in the search assistant
// can talk to us.
if (_pauto) { IWebBrowserApp *pWebBrowserApp; HRESULT hr = _pauto->QueryInterface(IID_PPV_ARG(IWebBrowserApp, &pWebBrowserApp));
if (SUCCEEDED(hr)) { ASSERT(NULL != pWebBrowserApp); BSTR bstrProp = SysAllocString(c_wszThisBandIsYourBand); if (NULL != bstrProp) { VARIANT varThis; if (fConnect) { varThis.vt = VT_UNKNOWN; varThis.punkVal = (IBandNavigate *)this; } else { varThis.vt = VT_EMPTY; } pWebBrowserApp->PutProperty(bstrProp, varThis); SysFreeString(bstrProp); } pWebBrowserApp->Release(); } } }
void CSearchBand::_InitBrowser(void) { CBrowserBand::_InitBrowser(); }
HRESULT CSearchBand::_NavigateOC() { HRESULT hres = E_FAIL;
if (_pidl) // don't want search pane to be navigated to home.
return CBrowserBand::_NavigateOC();
return hres; }
HRESULT CSearchBand::GetBandInfo(DWORD dwBandID, DWORD fViewMode, DESKBANDINFO* pdbi) { _dwBandID = dwBandID; pdbi->dwModeFlags = DBIMF_FIXEDBMP | DBIMF_VARIABLEHEIGHT; pdbi->ptMinSize.x = 16; pdbi->ptMinSize.y = 0; pdbi->ptMaxSize.x = 32000; // random
pdbi->ptMaxSize.y = 32000; // random
pdbi->ptActual.y = -1; pdbi->ptActual.x = -1; pdbi->ptIntegral.y = 1;
MLLoadStringW(IDS_BAND_SEARCH, pdbi->wszTitle, ARRAYSIZE(pdbi->wszTitle)); return S_OK; }
//*** CSearchBand::IPersistStream::* {
HRESULT CSearchBand::GetClassID(CLSID *pClassID) { *pClassID = CLSID_SearchBand;
return S_OK; }
HRESULT CSearchBand::Load(IStream *pstm) { _NavigateOC(); return S_OK; }
HRESULT CSearchBand::Save(IStream *pstm, BOOL fClearDirty) { return S_OK; }
HRESULT CSearchBand::Select(LPCITEMIDLIST pidl) { HRESULT hres = S_OK; IServiceProvider *psp = NULL; LPITEMIDLIST pidlTemp = NULL;
OCHost_QueryInterface(_hwnd, IID_PPV_ARG(IServiceProvider, &psp)); if (psp) { IBrowserService * pbs; if (EVAL(SUCCEEDED(psp->QueryService(SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &pbs))))) { pbs->GetPidl(&pidlTemp); pbs->Release(); } psp->Release(); }
if ((!pidlTemp) || (!ILIsEqual(pidlTemp, pidl))) { ILFree(_pidl); _pidl = ILClone(pidl); hres = _NavigateOC(); } ILFree(pidlTemp); return hres; }
STDMETHODIMP CSearchBand::QueryService(REFGUID guidService, REFIID riid, LPVOID* ppvObj) { HRESULT hres; if (IsEqualGUID(guidService, SID_SInternetSecurityManager)) { _bNewUrl = TRUE; hres = QueryInterface(riid, ppvObj); } else hres = CBrowserBand::QueryService(guidService, riid, ppvObj);
return hres; }
HRESULT CSearchBand::OnWinEvent(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plres) { if ((WM_WININICHANGE == uMsg) && lParam && ((0 == StrCmpW((LPCWSTR)lParam, SEARCH_SETTINGS_CHANGEDW)) || (0 == StrCmpA((LPCSTR) lParam, SEARCH_SETTINGS_CHANGEDA)))) { _NavigateToSearchUrl(); }
return CBrowserBand::OnWinEvent(hwnd, uMsg, wParam, lParam, plres); }
BOOL CSearchBand::_IsSafeUrl(LPCWSTR pwszUrl) { BOOL bRet = FALSE; HKEY hkey;
if (_bNewUrl || !_bUseDefault) { WCHAR wsz[MAX_URL_STRING]; DWORD cch = ARRAYSIZE(wsz);
if (SUCCEEDED(UrlCanonicalizeW(pwszUrl, wsz, &cch, 0)) && cch > 0) { // the first time this f-n is called, url passed in is the url of
// the top most frame -- if that's not one of our 'safe' urls we
// don't want to use this security mgr because it is possible
// that the outer frame hosts iframe w/ 'safe' site and scripts
// shell dispatch from the outside thus being able to do anything
// it wants.
if (_wszCache[0] != L'\0') { if ((_nCmpLength && StrCmpNIW(wsz, _wszCache, _nCmpLength) == 0) || (!_nCmpLength && StrCmpIW(wsz, _wszCache) == 0)) return _bIsCacheSafe; } if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\SafeSites", 0, KEY_READ, &hkey) == ERROR_SUCCESS) { WCHAR wszValue[MAX_PATH]; WCHAR wszData[MAX_URL_STRING]; DWORD cbData = SIZEOF(wszData); DWORD cchValue = ARRAYSIZE(wszValue);
for (int i=0; RegEnumValueW(hkey, i, wszValue, &cchValue, NULL, NULL, (LPBYTE)wszData, &cbData) == ERROR_SUCCESS; i++) { if (SHExpandEnvironmentStringsW(wszData, _wszCache, ARRAYSIZE(_wszCache)) > 0) { cchValue = ARRAYSIZE(_wszCache); if (SUCCEEDED(UrlCanonicalizeW(_wszCache, _wszCache, &cchValue, 0)) && (cchValue > 0)) { if (_wszCache[cchValue - 1] == L'*') { _nCmpLength = cchValue - 1; bRet = StrCmpNIW(wsz, _wszCache, _nCmpLength) == 0; } else { _nCmpLength = 0; bRet = StrCmpIW(wsz, _wszCache) == 0; }
_bIsCacheSafe = bRet; if (bRet) break; } cbData = SIZEOF(_wszCache); cchValue = ARRAYSIZE(wszValue); } } RegCloseKey(hkey); }
// we did not find the url in the list of 'safe' sites
// _wszCache now point to the last url read from the registry
// ajdust it to point pwszUrl, _bIsCacheSafe is correct already
if (!bRet) StringCchCopy(_wszCache, ARRAYSIZE(_wszCache), wsz);
if (_bNewUrl) { _bNewUrl = FALSE; _bUseDefault = !bRet; } } } return bRet; }
//*** CCommBand {
//
////////////////
/// Comm (BrowserOC) band
class CCommBand : public CBrowserBand {
public: // *** IPersistStream methods ***
// (others use base class implementation)
virtual STDMETHODIMP GetClassID(CLSID *pClassID); virtual STDMETHODIMP Load(IStream *pStm); virtual STDMETHODIMP Save(IStream *pStm, BOOL fClearDirty);
// *** IDockingWindow methods ***
virtual STDMETHODIMP ShowDW(BOOL fShow);
protected: CCommBand(); virtual ~CCommBand();
friend HRESULT CCommBand_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi); // for ctor
};
CCommBand::CCommBand() : CBrowserBand() { _fBlockSIDProxy = FALSE; _fBlockDrop = TRUE; _fCustomTitle = TRUE; _wszTitle[0] = L'\0';
_dwModeFlags = DBIMF_VARIABLEHEIGHT;
return; }
CCommBand::~CCommBand() { }
HRESULT CCommBand_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi) { // aggregation checking is handled in class factory
*ppunk = NULL; LPITEMIDLIST pidlNew; HRESULT hr = IECreateFromPath(L"about:blank", &pidlNew); if (SUCCEEDED(hr)) { CCommBand *p = new CCommBand(); if (p) { p->_pidl = pidlNew; *ppunk = SAFECAST(p, IDeskBand*); hr = S_OK; } else { ILFree(pidlNew); hr = E_OUTOFMEMORY; } } return hr; }
//*** CCommBand::IPersistStream::* {
HRESULT CCommBand::GetClassID(CLSID *pClassID) { *pClassID = CLSID_CommBand;
return S_OK; }
HRESULT CCommBand::Load(IStream *pstm) { // _NavigateOC();
return S_OK; }
HRESULT CCommBand::Save(IStream *pstm, BOOL fClearDirty) { return S_OK; }
HRESULT CCommBand::ShowDW(BOOL fShow) { // so that the contained Browser OC event gets fired
if (_pauto) { _pauto->put_Visible(fShow); }
return CBrowserBand::ShowDW(fShow); }
// }
|