2033 lines
53 KiB
C++
2033 lines
53 KiB
C++
#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"
|
|
#ifdef UNIX
|
|
#include "unixstuff.h"
|
|
#endif
|
|
|
|
#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;
|
|
StrCpyNW(_wszTitle, pTitle, ARRAYSIZE(_wszTitle));
|
|
_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]) {
|
|
StrCpyNW(pdbi->wszTitle, _wszTitle, ARRAYSIZE(pdbi->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)
|
|
{
|
|
HRESULT hres;
|
|
DWORD dw;
|
|
|
|
if (_pidl) {
|
|
ILFree(_pidl);
|
|
}
|
|
|
|
hres = pstm->Read(&dw, SIZEOF(DWORD), NULL);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
if (dw & BB_PIDLASLINK)
|
|
{
|
|
hres = LoadPidlAsLink(_punkSite, pstm, &_pidl);
|
|
}
|
|
else if (dw & BB_ILSTREAM) // for backwards compat
|
|
{
|
|
hres = ILLoadFromStream(pstm, &_pidl);
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hres))
|
|
_NavigateOC();
|
|
|
|
return hres;
|
|
}
|
|
|
|
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)
|
|
{
|
|
HRESULT hres;
|
|
TCHAR szUrl[MAX_URL_STRING];
|
|
|
|
TraceMsg(DM_TRACE, "cbb.l(bag): enter");
|
|
|
|
if (_pidl) {
|
|
ILFree(_pidl);
|
|
}
|
|
|
|
hres = SHPropertyBag_ReadStr(pPBag, L"Url", szUrl, ARRAYSIZE(szUrl));
|
|
if (SUCCEEDED(hres)) {
|
|
TCHAR * pszFinalUrl;
|
|
TCHAR szPlug[MAX_PATH];
|
|
TCHAR szMuiPath[MAX_PATH];
|
|
|
|
pszFinalUrl = szUrl;
|
|
|
|
hres = SHPropertyBag_ReadStr(pPBag, L"Pluggable", szPlug, ARRAYSIZE(szPlug));
|
|
|
|
if (SUCCEEDED(hres) && !StrCmpNI(TEXT("yes"), szPlug, ARRAYSIZE(szPlug)))
|
|
{
|
|
TCHAR * pszFile;
|
|
|
|
// if this is loading html out of the windows\web folder
|
|
// then we need to call SHGetWebFolderFilePath in order
|
|
// to support pluggable UI
|
|
|
|
pszFile = PathFindFileName(szUrl);
|
|
hres = SHGetWebFolderFilePath(pszFile, szMuiPath, ARRAYSIZE(szMuiPath));
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
pszFinalUrl = szMuiPath;
|
|
}
|
|
}
|
|
|
|
hres = IECreateFromPath(pszFinalUrl, &_pidl);
|
|
if (SUCCEEDED(hres)) {
|
|
_NavigateOC();
|
|
}
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
// }
|
|
|
|
//*** 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
|
|
StrCpyNW(_wszTitle, pbbi->bstrTitle, ARRAYSIZE(_wszTitle));
|
|
} 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);
|
|
|
|
#ifndef UNIX
|
|
SHHtmlHelpOnDemandWrap(hwnd, TEXT("iexplore.chm > iedefault"), 0, (DWORD_PTR) TEXT("srchasst.htm"), ML_CROSSCODEPAGE);
|
|
#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)))))
|
|
{
|
|
UnixHelp(L"Search Help", psb);
|
|
psb->Release();
|
|
}
|
|
psp->Release();
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
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)
|
|
{
|
|
#ifdef UNIX
|
|
// We overide this method in order to provide renavigation if our earlier navigation
|
|
// was cancelled for some reason.
|
|
|
|
if (fShow)
|
|
{
|
|
// Should be there.
|
|
// Just being sure we are able to navigate.
|
|
|
|
ASSERT(IsWindow(_hwnd));
|
|
ASSERT( _pidl );
|
|
|
|
if (_pauto)
|
|
{
|
|
BSTR bstrURL = NULL;
|
|
TCHAR szLocation[MAX_URL_STRING];
|
|
|
|
// SHUnicodeToTChar does this - no memset
|
|
// memset(szLocation, 0, SIZEOF(szLocation));
|
|
|
|
if( SUCCEEDED(_pauto->get_LocationURL(&bstrURL)) && bstrURL )
|
|
{
|
|
// Fire navigation again if the navigation was canceled earlier for
|
|
// some reason (Maybe the proxy was not set).
|
|
|
|
SHUnicodeToTChar(bstrURL, szLocation, ARRAYSIZE(szLocation));
|
|
if( !StrCmpI( szLocation, NAVCANCELLED_URL ) ||
|
|
!StrCmpI( szLocation, OFFLINEINFO_URL ) )
|
|
_NavigateOC();
|
|
|
|
SysFreeString(bstrURL);
|
|
}
|
|
|
|
}
|
|
}
|
|
#endif
|
|
|
|
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)
|
|
lstrcpynW(_wszCache, wsz, ARRAYSIZE(_wszCache));
|
|
|
|
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);
|
|
}
|
|
|
|
// }
|
|
|