#include "priv.h" #include #include "hlframe.h" #include "winlist.h" #include "resource.h" //CLSID_SearchBand #include "interned.h" // IHTMLPrivateWindow // Locally defined FINDFRAME flag used to guarantee ITargetFrame vs ITargetFrame2 compatibility #define FINDFRAME_OLDINTERFACE FINDFRAME_INTERNAL STDAPI SafeGetItemObject(LPSHELLVIEW psv, UINT uItem, REFIID riid, LPVOID *ppv); HRESULT TargetQueryService(LPUNKNOWN punk, REFIID riid, void **ppvObj); HRESULT CoCreateNewIEWindow( DWORD dwClsContext, REFIID riid, void **ppvunk ); /****************************************************************** NAME: SetOleStrMember SYNOPSIS: sets a new value for OleStr member ******************************************************************/ HRESULT SetOleStrMember(WCHAR **ppszMember, LPCOLESTR pszNewValue) { HRESULT hr; if (*ppszMember) { LocalFree(*ppszMember); *ppszMember = NULL; } if (pszNewValue) { *ppszMember = StrDupW(pszNewValue); hr = *ppszMember ? S_OK : E_OUTOFMEMORY; } else { *ppszMember = NULL; hr = S_OK; } return hr; } /****************************************************************** NAME: GetOleStrMember SYNOPSIS: gets a value for OleStr member as new CoTaskMemAlloc LPOLESTR ******************************************************************/ HRESULT GetOleStrMember(LPCOLESTR pszMember, WCHAR **ppszReturnValue) { HRESULT hr; if (pszMember) hr = SHStrDupW(pszMember, ppszReturnValue); else { hr = S_OK; *ppszReturnValue = NULL; } return hr; } /******************************************************************* NAME: CIEFrameAuto::SetFrameName SYNOPSIS: Sets the Frame Name. Frees current one if exists. ********************************************************************/ STDMETHODIMP CIEFrameAuto::SetFrameName(LPCOLESTR pszFrameName) { // AOL and other 3rd Party 3.0 compatibility. The ITargetNotify // object that sets off a window open operation via AOL container // registers itself in ShellCallbacks list and wnsprintf's the // coresponding cookie in the front of the frame name ("" if there // is no frame name as in _blank). we extract the cookie, notify // all registered callbacks, then set the name MINUS the _[NNNNN..] // that was prepending to the frame name. if (pszFrameName && lstrlen(pszFrameName) >= 2 && pszFrameName[0] == '_' && pszFrameName[1] == '[') { #define MAX_COOKIE 24 WCHAR wszCookie[MAX_COOKIE + 1]; // big enough for "cbCookie" int i; long cbCookie; BOOL fNonDigit = FALSE; IShellWindows* psw = NULL; for (i = 2; i < MAX_COOKIE && pszFrameName[i] && pszFrameName[i] != ']'; i++) { wszCookie[i-2] = pszFrameName[i]; if (i != 2 || pszFrameName[2] != '-') fNonDigit = fNonDigit || pszFrameName[i] < '0' || pszFrameName[i] > '9'; } wszCookie[i-2] = 0; if (i >= 3 && pszFrameName[i] == ']' && !fNonDigit) { cbCookie = StrToIntW(wszCookie); psw = WinList_GetShellWindows(TRUE); if (psw) { IUnknown *punkThis; if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IUnknown, &punkThis)))) { psw->OnCreated(cbCookie, punkThis); punkThis->Release(); } psw->Release(); } pszFrameName = pszFrameName + i + 1; if (pszFrameName[0] == 0) pszFrameName = NULL; } } return SetOleStrMember(&m_pszFrameName, pszFrameName); } /******************************************************************* NAME: CIEFrameAuto::GetFrameName SYNOPSIS: Gets the Frame Name. Allocates a copy (this is an [OUT] parameter ********************************************************************/ STDMETHODIMP CIEFrameAuto::GetFrameName(WCHAR **ppszFrameName) { return GetOleStrMember(m_pszFrameName, ppszFrameName); } /******************************************************************* NAME: CIEFrameAuto::_GetParentFramePrivate SYNOPSIS: Gets an the IUnknown pointer of the parent frame, or NULL if this is a top level frame. This pointer must be Released by Caller after use. IMPLEMENTATION: A Frame Container is required to implement ITargetFrame::GetParentFrame and implement GetParentFrame by returning the IUnknown pointer of the Browser that hosts it. A Browser implements GetParentFrame by returning NULL if it's top level or calling GetParentFrame on its Container if it is embedded. NOTE: THIS PRIVATE VERSION doesn't check for parent being desktopframe. ********************************************************************/ HRESULT CIEFrameAuto::_GetParentFramePrivate(LPUNKNOWN *ppunkParentFrame) { LPOLEOBJECT pOleObject = NULL; LPOLECLIENTSITE pOleClientSite = NULL; HRESULT hr = S_OK; LPUNKNOWN punkParent = NULL; // Start off with OleObject for this OCX embedding, it will // be null if we're top level (a CIEFrameAuto, not a CVOCBrowser) _GetOleObject(&pOleObject); if (pOleObject != NULL) { // Assumes GetClientSite succeeds and returns NULL if we // are not embedded hr = pOleObject->GetClientSite(&pOleClientSite); if (FAILED(hr)) goto errExit; pOleObject->Release(); pOleObject = NULL; // If pOleClientSite is NULL, then we are at the top level if (pOleClientSite == NULL) { hr = S_OK; goto errExit; } else { hr = TargetQueryService(pOleClientSite, IID_PPV_ARG(IUnknown, &punkParent)); if (FAILED(hr)) { // if parent container does not support ITargetFrame, then // the parent container must be some other app, like VB. In this // case, we've already found the outermost frame (us). Return // S_OK and a NULL ptgfTargetFrame which indicates that we are the // outermost HTML frame. hr = S_OK; } SAFERELEASE(pOleClientSite); } } errExit: SAFERELEASE(pOleObject); SAFERELEASE(pOleClientSite); *ppunkParentFrame = punkParent; return hr; } /******************************************************************* NAME: CIEFrameAuto::GetParentFrame SYNOPSIS: Gets an the IUnknown pointer of the parent frame, or NULL if this is a top level frame. This pointer must be Released by Caller after use. IMPLEMENTATION: A Frame Container is required to implement ITargetFrame::GetParentFrame and implement GetParentFrame by returning the IUnknown pointer of the Browser that hosts it. A Browser implements GetParentFrame by returning NULL if it's top level or calling GetParentFrame on its Container if it is embedded. ********************************************************************/ STDMETHODIMP CIEFrameAuto::GetParentFrame(LPUNKNOWN *ppunkParentFrame) { HRESULT hr = _GetParentFramePrivate(ppunkParentFrame); // Check if the parent is the desktop, if so, the frame chain stops // at us if (SUCCEEDED(hr) && *ppunkParentFrame) { LPTARGETFRAME2 ptgfParent; DWORD dwOptions; if (SUCCEEDED((*ppunkParentFrame)->QueryInterface(IID_PPV_ARG(ITargetFrame2, &ptgfParent)))) { ptgfParent->GetFrameOptions(&dwOptions); if (dwOptions & FRAMEOPTIONS_DESKTOP) { (*ppunkParentFrame)->Release(); *ppunkParentFrame = NULL; } ptgfParent->Release(); } } return hr; } // PLEASE PROPOGATE ANY CHANGES TO THESE ENUMS TO \mshtml\iextag\httpwfh.h typedef enum _TARGET_TYPE { TARGET_FRAMENAME, TARGET_SELF, TARGET_PARENT, TARGET_BLANK, TARGET_TOP, TARGET_MAIN, TARGET_SEARCH, TARGET_MEDIA } TARGET_TYPE; typedef struct _TARGETENTRY { TARGET_TYPE targetType; const WCHAR *pTargetValue; } TARGETENTRY; static const TARGETENTRY targetTable[] = { {TARGET_SELF, L"_self"}, {TARGET_PARENT, L"_parent"}, {TARGET_BLANK, L"_blank"}, {TARGET_TOP, L"_top"}, {TARGET_MAIN, L"_main"}, {TARGET_SEARCH, L"_search"}, {TARGET_MEDIA, L"_media"}, {TARGET_SELF, NULL} }; /******************************************************************* NAME: ParseTargetType SYNOPSIS: Maps pszTarget into a target class. IMPLEMENTATION: Treats unknown MAGIC targets as _self ********************************************************************/ // PLEASE PROPOGATE ANY CHANGES TO THIS FUNCTION TO \mshtml\iextag\httpwf.cxx TARGET_TYPE ParseTargetType(LPCOLESTR pszTarget) { const TARGETENTRY *pEntry = targetTable; if (pszTarget[0] != '_') return TARGET_FRAMENAME; while (pEntry->pTargetValue) { if (!StrCmpW(pszTarget, pEntry->pTargetValue)) return pEntry->targetType; pEntry++; } // Treat unknown MAGIC targets as regular frame name! <> return TARGET_FRAMENAME; } /******************************************************************* NAME: TargetQueryService SYNOPSIS: Returns a pointer to containing Browser's ITargetFrame interface (or NULL if container does not support it) NOTES: If we don't yet have this interface pointer yet, this function will QueryInterface to get it. ********************************************************************/ HRESULT TargetQueryService(LPUNKNOWN punk, REFIID riid, void **ppvObj) { // Get the ITargetFrame for the embedding. return IUnknown_QueryService(punk, IID_ITargetFrame2, riid, ppvObj); } /******************************************************************* NAME: _TargetTopLevelWindows SYNOPSIS: see FindFrame, does the named targets across windows ********************************************************************/ HRESULT _TargetTopLevelWindows(LPTARGETFRAMEPRIV ptgfpThis, LPCOLESTR pszTargetName, DWORD dwFlags, LPUNKNOWN *ppunkTargetFrame) { IShellWindows* psw = NULL; HRESULT hr = E_FAIL; *ppunkTargetFrame = NULL; psw = WinList_GetShellWindows(TRUE); if (psw != NULL) { IUnknown *punkEnum; IEnumVARIANT *penumVariant; VARIANT VarResult; BOOL fDone = FALSE; LPTARGETFRAMEPRIV ptgfpWindowFrame; hr = psw->_NewEnum(&punkEnum); if (SUCCEEDED(hr)) { hr = punkEnum->QueryInterface(IID_PPV_ARG(IEnumVARIANT, &penumVariant)); if (SUCCEEDED(hr)) { while (!fDone) { VariantInit(&VarResult); hr = penumVariant->Next(1, &VarResult, NULL); if (hr == NOERROR) { if (VarResult.vt == VT_DISPATCH && VarResult.pdispVal) { hr = VarResult.pdispVal->QueryInterface(IID_PPV_ARG(ITargetFramePriv, &ptgfpWindowFrame)); if (SUCCEEDED(hr)) { if (ptgfpWindowFrame != ptgfpThis) { hr = ptgfpWindowFrame->FindFrameDownwards(pszTargetName, dwFlags, ppunkTargetFrame); if (SUCCEEDED(hr) && *ppunkTargetFrame != NULL) { fDone = TRUE; } } ptgfpWindowFrame->Release(); } } VariantClear(&VarResult); } else { fDone = TRUE; } } penumVariant->Release(); } punkEnum->Release(); } psw->Release(); } return hr; } /******************************************************************* NAME: CreateTargetFrame SYNOPSIS: Creates a new window, if pszTargetName is not special target, names it pszTargetName. returns IUnknown for the object that implements ITargetFrame,IHlinkFrame and IWebBrowserApp. ********************************************************************/ // PLEASE PROPOGATE ANY CHANGES TO THIS FUNCTION TO \mshtml\iextag\httpwf.cxx HRESULT CreateTargetFrame(LPCOLESTR pszTargetName, LPUNKNOWN /*IN,OUT*/ *ppunk) { LPTARGETFRAME2 ptgfWindowFrame; HRESULT hr = S_OK; // Launch a new window, set it's frame name to pszTargetName // return it's IUnknown. If the new window is passed to us, // just set the target name. if (NULL == *ppunk) { hr = CoCreateNewIEWindow(CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_PPV_ARG(IUnknown, ppunk)); } if (SUCCEEDED(hr)) { // Don't set frame name if target is special or missing if (pszTargetName && ParseTargetType(pszTargetName) == TARGET_FRAMENAME) { HRESULT hrLocal; hrLocal = (*ppunk)->QueryInterface(IID_PPV_ARG(ITargetFrame2, &ptgfWindowFrame)); if (SUCCEEDED(hrLocal)) { ptgfWindowFrame->SetFrameName(pszTargetName); ptgfWindowFrame->Release(); } } // Even if we don't set the frame name, we still want to return // success, otherwise we'd have a blank window hanging around. } return hr; } /******************************************************************* NAME: CIEFrameAuto::_DoNamedTarget SYNOPSIS: see FindFrame, does the named targets. checks itself then if that fails, all children except for punkContextFrame (if punkContextFrame != NULL). if all of the above fail, will recurse upwards if necessary, if punkContextFrame != NULL. if punkContextFrame is NULL, then this works out to checking ourself and all children then giving up. ********************************************************************/ HRESULT CIEFrameAuto::_DoNamedTarget(LPCOLESTR pszTargetName, LPUNKNOWN punkContextFrame, DWORD dwFlags, LPUNKNOWN * ppunkTargetFrame) { // asserts HRESULT hr = S_OK; HRESULT hrLocal; LPUNKNOWN punkParent = NULL; LPUNKNOWN punkThisFrame = NULL; LPTARGETFRAMEPRIV ptgfpParent = NULL; LPUNKNOWN punkThis = NULL; LPUNKNOWN punkChildObj = NULL; LPUNKNOWN punkChildFrame = NULL; LPTARGETFRAMEPRIV ptgfpChild = NULL; LPOLECONTAINER pOleContainer = NULL; LPENUMUNKNOWN penumUnknown = NULL; LPUNKNOWN punkProxyContextFrame = NULL; LPTARGETFRAMEPRIV ptgfpTarget = NULL; ASSERT(ppunkTargetFrame); *ppunkTargetFrame = NULL; hr = QueryInterface(IID_PPV_ARG(IUnknown, &punkThis)); ASSERT(punkThis != NULL); if (FAILED(hr)) goto exitPoint; // First check for match on US! if (m_pszFrameName && !StrCmpW(pszTargetName, m_pszFrameName)) { *ppunkTargetFrame = punkThis; // Set punkThis to NULL to prevent Release at exit punkThis = NULL; goto exitPoint; } // we ask our ShellView's embedded DocObject if it supports ITargetFrame. If it does, // we first let it look for the target. hrLocal = GetFramesContainer(&pOleContainer); if (SUCCEEDED(hrLocal) && pOleContainer != NULL) { hr = pOleContainer->EnumObjects(OLECONTF_EMBEDDINGS, &penumUnknown); if (hr != S_OK || penumUnknown == NULL) goto exitPoint; while (TRUE) { hr = penumUnknown->Next(1, &punkChildObj, NULL); if (punkChildObj == NULL) { hr = S_OK; break; } hrLocal = punkChildObj->QueryInterface(IID_PPV_ARG(ITargetFramePriv, &ptgfpChild)); if (SUCCEEDED(hrLocal)) { hr = ptgfpChild->QueryInterface(IID_PPV_ARG(IUnknown, &punkChildFrame)); if (FAILED(hr)) goto exitPoint; // IF this isn't the punkContextFrame, see if embedding supports ITargetFrame if (punkChildFrame != punkContextFrame) { hr = ptgfpChild->FindFrameDownwards(pszTargetName, dwFlags, ppunkTargetFrame); if (hr != S_OK || *ppunkTargetFrame != NULL) goto exitPoint; } } punkChildObj->Release(); punkChildObj = NULL; SAFERELEASE(punkChildFrame); SAFERELEASE(ptgfpChild); } } if (!(*ppunkTargetFrame) && pOleContainer) { hr = _FindWindowByName(pOleContainer, pszTargetName, ppunkTargetFrame); if (S_OK == hr) goto exitPoint; } // We don't recurse to parent in punkContextFrame is NULL if (punkContextFrame == NULL) goto exitPoint; hr = GetParentFrame(&punkParent); if (hr != S_OK) goto exitPoint; if (punkParent != NULL) { // We have a parent, recurse upwards, with ourself as context frame hr = punkParent->QueryInterface(IID_PPV_ARG(ITargetFramePriv, &ptgfpParent)); if (hr != S_OK) goto exitPoint; hr = ptgfpParent->FindFrameInContext(pszTargetName, punkThis, dwFlags, ppunkTargetFrame); goto exitPoint; } // At this point we've come to the top level frame. // Enumerate top level windows, unless we're a toolbar *ppunkTargetFrame = NULL; if (_psb != _psbProxy) { // Webbar : Find in context of top frame of proxy hr = TargetQueryService(_psbProxy, IID_PPV_ARG(ITargetFramePriv, &ptgfpTarget)); if (SUCCEEDED(hr) && ptgfpTarget) { hr = ptgfpTarget->QueryInterface(IID_PPV_ARG(IUnknown, &punkProxyContextFrame)); if (SUCCEEDED(hr)) { hr = ptgfpTarget->FindFrameInContext(pszTargetName, punkProxyContextFrame, dwFlags, ppunkTargetFrame); if (*ppunkTargetFrame) goto exitPoint; } } } else if (!(FINDFRAME_OLDINTERFACE & dwFlags)) { hr = _TargetTopLevelWindows((LPTARGETFRAMEPRIV)this, pszTargetName, dwFlags, ppunkTargetFrame); if (*ppunkTargetFrame) goto exitPoint; } // Now we have exhausted all frames. Unless FINDFRAME_JUSTTESTEXISTENCE // is set in dwFlags, create a new window, set it's frame name and return it if (dwFlags & FINDFRAME_JUSTTESTEXISTENCE) { hr = S_OK; } else { // CreateTargetFrame will not work with AOL 3.01 clients // so we must return E_FAIL hr = E_FAIL; } exitPoint: SAFERELEASE(punkProxyContextFrame); SAFERELEASE(ptgfpTarget); SAFERELEASE(punkThis); SAFERELEASE(punkThisFrame); SAFERELEASE(ptgfpParent); SAFERELEASE(punkParent); SAFERELEASE(punkChildFrame); SAFERELEASE(ptgfpChild); SAFERELEASE(penumUnknown); SAFERELEASE(pOleContainer); SAFERELEASE(punkChildObj); return hr; } //+------------------------------------------------------------------------- // // Method : CIEFrameAuto::_FindWindowByName // // Synopsis : Searches the give container for the given frame name. // This method is called when _DoNamedTarget fails to find // the target frame in one of the container's embeddings. // //+------------------------------------------------------------------------- HRESULT CIEFrameAuto::_FindWindowByName(IOleContainer * pOleContainer, LPCOLESTR pszTargetName, LPUNKNOWN * ppunkTargetFrame) { HRESULT hr; IHTMLDocument2 * pDocument; IHTMLPrivateWindow * pPrivWindow; IHTMLWindow2 * pHTMLWindow; IServiceProvider * pServiceProvider; IWebBrowserApp * pWebBrowserApp; ASSERT(pOleContainer); ASSERT(ppunkTargetFrame); hr = pOleContainer->QueryInterface(IID_PPV_ARG(IHTMLDocument2, &pDocument)); if (SUCCEEDED(hr)) { hr = pDocument->get_parentWindow(&pHTMLWindow); if (SUCCEEDED(hr)) { hr = pHTMLWindow->QueryInterface(IID_PPV_ARG(IHTMLPrivateWindow, &pPrivWindow)); pHTMLWindow->Release(); // being reused below if (SUCCEEDED(hr)) { hr = pPrivWindow->FindWindowByName(pszTargetName, &pHTMLWindow); if (S_OK == hr) { hr = pHTMLWindow->QueryInterface(IID_PPV_ARG(IServiceProvider, &pServiceProvider)); if (S_OK == hr) { hr = pServiceProvider->QueryService(SID_SWebBrowserApp, IID_PPV_ARG(IWebBrowserApp, &pWebBrowserApp)); if (S_OK == hr) { *ppunkTargetFrame = SAFECAST(pWebBrowserApp, IUnknown*); (*ppunkTargetFrame)->AddRef(); pWebBrowserApp->Release(); } pServiceProvider->Release(); } pHTMLWindow->Release(); } pPrivWindow->Release(); } } pDocument->Release(); } return hr; } /******************************************************************* NAME: CIEFrameAuto::SetFrameSrc SYNOPSIS: Sets the Frame original SRC url. Frees current one if exists. ********************************************************************/ HRESULT CIEFrameAuto::SetFrameSrc(LPCOLESTR pszFrameSrc) { return SetOleStrMember(&m_pszFrameSrc, pszFrameSrc); } IShellView* CIEFrameAuto::_GetShellView(void) { IShellView* psv = NULL; if (_psb) { _psb->QueryActiveShellView(&psv); } return psv; } /******************************************************************* NAME: CIEFrameAuto::GetFrameSrc SYNOPSIS: Gets the Frame original URL. Allocates a copy (this is an [OUT] parameter NOTES: If we are at top level, SRC is dynamic, so ask our contained DocObject to do it for us. ********************************************************************/ HRESULT CIEFrameAuto::GetFrameSrc(WCHAR **ppszFrameSrc) { LPUNKNOWN punkParent = NULL; LPTARGETFRAME ptgfTargetFrame = NULL; LPTARGETCONTAINER ptgcTargetContainer = NULL; *ppszFrameSrc = NULL; HRESULT hr = GetParentFrame(&punkParent); if (hr != S_OK) goto exitPoint; // If we're an embedding we have original src. If we're top level and // src has been set, return that, else defer to document if (punkParent != NULL || m_pszFrameSrc) { hr = GetOleStrMember(m_pszFrameSrc, ppszFrameSrc); } else // We're top level without an explicit SRC { *ppszFrameSrc = NULL; hr = S_OK; // review: since we are w/o SRC, we should succeed even though we don't fill out ppszFrameSrc in failure case? IShellView* psv = _GetShellView(); if (psv) { HRESULT hrLocal = SafeGetItemObject(psv, SVGIO_BACKGROUND, IID_PPV_ARG(ITargetContainer, &ptgcTargetContainer)); if (SUCCEEDED(hrLocal)) { hr = ptgcTargetContainer->GetFrameUrl(ppszFrameSrc); } else { // Backwards compatibility hrLocal = SafeGetItemObject(psv, SVGIO_BACKGROUND, IID_PPV_ARG(ITargetFrame, &ptgfTargetFrame)); if (SUCCEEDED(hrLocal)) { hr = ptgfTargetFrame->GetFrameSrc(ppszFrameSrc); } } psv->Release(); } } exitPoint: SAFERELEASE(punkParent); SAFERELEASE(ptgfTargetFrame); SAFERELEASE(ptgcTargetContainer); return hr; } /******************************************************************* NAME: CIEFrameAuto::GetFramesContainer SYNOPSIS: Returns an addref'ed pointer to the LPOLECONTAINER for our nested frames. Can be NULL. ********************************************************************/ HRESULT CIEFrameAuto::GetFramesContainer(LPOLECONTAINER *ppContainer) { LPTARGETFRAME ptgfTargetFrame = NULL; LPTARGETCONTAINER ptgcTargetContainer = NULL; HRESULT hr = E_FAIL; *ppContainer = NULL; IShellView* psv = _GetShellView(); if (psv) { HRESULT hrLocal = SafeGetItemObject(psv, SVGIO_BACKGROUND, IID_PPV_ARG(ITargetContainer, &ptgcTargetContainer)); if (SUCCEEDED(hrLocal)) { hr = ptgcTargetContainer->GetFramesContainer(ppContainer); } else { // Backwards compatibility hrLocal = SafeGetItemObject(psv, SVGIO_BACKGROUND, IID_PPV_ARG(ITargetFrame, &ptgfTargetFrame)); if (SUCCEEDED(hrLocal)) { hr = ptgfTargetFrame->GetFramesContainer(ppContainer); } } psv->Release(); } SAFERELEASE(ptgcTargetContainer); SAFERELEASE(ptgfTargetFrame); return hr; } /******************************************************************* NAME: CIEFrameAuto::SetFrameOptions SYNOPSIS: Sets the Frame Options. ********************************************************************/ HRESULT CIEFrameAuto::SetFrameOptions(DWORD dwFlags) { m_dwFrameOptions = dwFlags; return S_OK; } /******************************************************************* NAME: CIEFrameAuto::GetFrameOptions SYNOPSIS: Returns the frame options ********************************************************************/ HRESULT CIEFrameAuto::GetFrameOptions(LPDWORD pdwFlags) { *pdwFlags = m_dwFrameOptions; // If we are full screen turn on a few extras... VARIANT_BOOL fFullScreen; if ((SUCCEEDED(get_FullScreen(&fFullScreen)) && fFullScreen == VARIANT_TRUE) || (SUCCEEDED(get_TheaterMode(&fFullScreen)) && fFullScreen == VARIANT_TRUE)) { *pdwFlags |= FRAMEOPTIONS_SCROLL_AUTO | FRAMEOPTIONS_NO3DBORDER; } else if (_psbProxy != _psb) { // If we are in the WebBar, turn off the 3D border. *pdwFlags |= FRAMEOPTIONS_NO3DBORDER; } // if we are desktop, turn on FRAMEOPTIONS_DESKTOP if (_fDesktopFrame) { *pdwFlags |= FRAMEOPTIONS_DESKTOP; } return S_OK; } /******************************************************************* NAME: CIEFrameAuto::SetFrameMargins SYNOPSIS: Sets the Frame margins. ********************************************************************/ HRESULT CIEFrameAuto::SetFrameMargins(DWORD dwWidth, DWORD dwHeight) { m_dwFrameMarginWidth = dwWidth; m_dwFrameMarginHeight = dwHeight; return S_OK; } /******************************************************************* NAME: CIEFrameAuto::GetFrameMargins SYNOPSIS: Returns the frame margins ********************************************************************/ HRESULT CIEFrameAuto::GetFrameMargins(LPDWORD pdwWidth, LPDWORD pdwHeight) { *pdwWidth = m_dwFrameMarginWidth; *pdwHeight = m_dwFrameMarginHeight; return S_OK; } /******************************************************************* NAME: CIEFrameAuto::_fDesktopComponent SYNOPSIS: Returns TRUE if this frame is a desktop component top level frame or a the top frame of a browser band other than the search pane. These panes need special treatment of FindFrame and navigate. *******************************************************************/ BOOL CIEFrameAuto::_fDesktopComponent() { BOOL fInDesktop = FALSE; LPUNKNOWN punkParent; // Special interpretation for desktop components and non-search browser bands // NULL pszTargetName at top level frames is defined as being targeted // to the window whose frame is "_desktop". this will create a new top level // browser as necessary and return it's frame. if (SUCCEEDED(_GetParentFramePrivate(&punkParent)) && punkParent) { DWORD dwOptions; LPTARGETFRAME2 ptgfTop; // not a top level frame unless our parent is desktop frame if (SUCCEEDED(punkParent->QueryInterface(IID_PPV_ARG(ITargetFrame2, &ptgfTop)))) { if (SUCCEEDED(ptgfTop->GetFrameOptions(&dwOptions))) { fInDesktop = (dwOptions & FRAMEOPTIONS_DESKTOP) ? TRUE:FALSE; } ptgfTop->Release(); } punkParent->Release(); } else if (m_dwFrameOptions & FRAMEOPTIONS_BROWSERBAND) { // a browser band - check for search band (proxied hlinkframe) fInDesktop = _psb == _psbProxy; } return fInDesktop; } // ITargetFrame2 members /******************************************************************* NAME: CIEFrameAuto::GetTargetAlias SYNOPSIS: Gets the Frame Name. Allocates a copy (this is an [OUT] parameter ********************************************************************/ STDMETHODIMP CIEFrameAuto::GetTargetAlias(LPCOLESTR pszTargetName, WCHAR **ppszTargetAlias) { // Special interpretation for desktop components and non-search browser bands // NULL pszTargetName and "_top" at top level frames are defined as being targeted // to the window whose frame is "_desktop". this will create a new top level // browser as necessary and return it's frame. if (pszTargetName == NULL && _fDesktopComponent()) return GetOleStrMember(L"_desktop", ppszTargetAlias); *ppszTargetAlias = NULL; return E_FAIL; } /******************************************************************* NAME: CIEFrameAuto::FindFrame SYNOPSIS: Gets an the IUnknown pointer of the frame referenced by pszTarget. This pointer must be Released by Caller after use. punkContextFrame, if not NULL, is the IUnknown pointer for the immediate descendent frame in whose subtree the Target reference (eg anchor with a Target tag) resides. dwFlags are flags which modify FindFrame's behaviour and can be any combination of FINDFRAME_FLAGS. In particular, SETTING FINDFRAME_JUSTTESTEXISTENCE allows the caller to defeat the default FindFrame behavior of creating a new top level frame named pszTarget, if pszTarget does not exist. IMPLEMENTATION: NOTE: In HTML all anchors and other TARGET tags can occur ONLY in leaf FRAMES!! punkContextFrame is significant only if pszTarget is not a MAGIC target name (_self, _top, _blank, _parent). Non-MAGIC target names: first off, this frame should check if it matches pszTarget and return it's own IUnknown pointer forthwith. if punkContextFrame is not NULL, all child Frames except punkContextFrame should be searched (depth first) for pszTarget with punkContextFrame == NULL. on failure, the parent of this frame should be recursively called with this frame replacing punkContextFrame. if this is a top level Frame (so there is no parent), all top level frames should be called with punkContextFrame == NULL. if this fails, then a new top level frame should be created (unless FINDFRAME_JUSTTESTEXISTENCE is set in dwFlags), named pszTarget and its IUnknown returned. if punkContextFrame is NULL, all child Frames should be searched depth first for pszTarget. on failure, NULL should be returned. MAGIC target names: _self should return the IUnknown of this ITargetFrame _top should be recursively passed up to the top level ITargetFrame. if there is no FrameParent, this defaults to _self. _parent should return the IUnknown of the FrameParent ITargetFrame. if there is no FrameParent, this defaults to _self. _blank should be recursively passed up to the top level ITargetFrame, which should create a unnamed top level frame ********************************************************************/ STDMETHODIMP CIEFrameAuto::FindFrame(LPCOLESTR pszTargetName, DWORD dwFlags, LPUNKNOWN *ppunkTargetFrame) { LPTARGETFRAMEPRIV ptgfpTarget = NULL; LPUNKNOWN punkContextFrame = NULL; HRESULT hr = E_FAIL; BOOL fInContext = TRUE; BOOL fWasMain = FALSE; TARGET_TYPE targetType; if (pszTargetName == NULL || *pszTargetName == 0) pszTargetName = L"_self"; targetType = ParseTargetType(pszTargetName); if (targetType == TARGET_MAIN) { fWasMain = TRUE; pszTargetName = L"_self"; } *ppunkTargetFrame = NULL; // Default behavior: // If this is a webbar and targeting _main, find frame in _psbProxy and return it // If this is in browser, find frame relative to ourselves if (_psb != _psbProxy && fWasMain) { // Webbar : Find in context of top frame of proxy hr = TargetQueryService(_psbProxy, IID_PPV_ARG(ITargetFramePriv, &ptgfpTarget)); } else { // Browser : A normal find in context in ourself hr = QueryInterface(IID_PPV_ARG(ITargetFramePriv, &ptgfpTarget)); } if (SUCCEEDED(hr) && ptgfpTarget) { if (fInContext) { hr = ptgfpTarget->QueryInterface(IID_PPV_ARG(IUnknown, &punkContextFrame)); if (SUCCEEDED(hr)) { hr = ptgfpTarget->FindFrameInContext(pszTargetName, punkContextFrame, dwFlags, ppunkTargetFrame); } } else { hr = ptgfpTarget->FindFrameDownwards(pszTargetName, dwFlags, ppunkTargetFrame); } } SAFERELEASE(punkContextFrame); SAFERELEASE(ptgfpTarget); if (SUCCEEDED(hr) && *ppunkTargetFrame == NULL && !(FINDFRAME_OLDINTERFACE&dwFlags)) hr = S_FALSE; return hr; } // ITargetFramePriv members /******************************************************************* NAME: CIEFrameAuto::FindFrameDownwards SYNOPSIS: IMPLEMENTATION: ********************************************************************/ STDMETHODIMP CIEFrameAuto::FindFrameDownwards(LPCOLESTR pszTargetName, DWORD dwFlags, LPUNKNOWN *ppunkTargetFrame) { return FindFrameInContext(pszTargetName, NULL, dwFlags | FINDFRAME_JUSTTESTEXISTENCE, ppunkTargetFrame); } /******************************************************************* NAME: CIEFrameAuto::FindFrameInContext SYNOPSIS: IMPLEMENTATION: ********************************************************************/ // can this function be any bigger? STDMETHODIMP CIEFrameAuto::FindFrameInContext(LPCOLESTR pszTargetName, LPUNKNOWN punkContextFrame, DWORD dwFlags, LPUNKNOWN *ppunkTargetFrame) { //asserts TARGET_TYPE targetType; HRESULT hr = S_OK; LPUNKNOWN punkParent = NULL; LPUNKNOWN punkThisFrame = NULL; LPTARGETFRAMEPRIV ptgfpTargetFrame = NULL; LPUNKNOWN punkThis = NULL; targetType = ParseTargetType(pszTargetName); if (targetType == TARGET_FRAMENAME) { hr = _DoNamedTarget(pszTargetName, punkContextFrame, dwFlags, ppunkTargetFrame); goto exitPoint; } // Must be a Magic Target //for search, first show the search bar and then reach across to get it's TargetFrame if (targetType == TARGET_SEARCH) { SA_BSTRGUID strGuid; VARIANT vaGuid; InitFakeBSTR(&strGuid, CLSID_SearchBand); vaGuid.vt = VT_BSTR; vaGuid.bstrVal = strGuid.wsz; //if we're in an explorer bar, use the proxy's pbs IBrowserService *pbs = _pbs; if (_psb != _psbProxy) { EVAL(SUCCEEDED(_psbProxy->QueryInterface(IID_PPV_ARG(IBrowserService, &pbs)))); } IUnknown_Exec(pbs, &CGID_ShellDocView, SHDVID_SHOWBROWSERBAR, 1, &vaGuid, NULL); VARIANT vaPunkBand = {0}; hr = IUnknown_Exec(pbs, &CGID_ShellDocView, SHDVID_GETBROWSERBAR, NULL, NULL, &vaPunkBand); if (_psb != _psbProxy) { ATOMICRELEASE(pbs); } if (hr == S_OK) { IDeskBand* pband = (IDeskBand*)vaPunkBand.punkVal; ASSERT(pband); if (pband) { IBrowserBand* pbb; hr = pband->QueryInterface(IID_PPV_ARG(IBrowserBand, &pbb)); if (SUCCEEDED(hr)) { // now, get the pidl search pane is navigated to. // if it's null we have to navigate it to something -- default search url (web search) // this used to be in CSearchBand::_NavigateOC but caused problems // if user had dial up networking set up and tried to get to the file search we would // first set pidl to web search url (_NavigateOC is called by _CreateOCHost) which would // cause AutoDial dialog to come up and then we would navigate the pane to the file search // (nt5 bug#186970) reljai -- 6/22/98 VARIANT varPidl = {0}; if (SUCCEEDED(IUnknown_Exec(pbb, &CGID_SearchBand, SBID_GETPIDL, 0, NULL, &varPidl))) { ISearchItems* psi; LPITEMIDLIST pidl = VariantToIDList(&varPidl); VariantClear(&varPidl); if (!pidl && SUCCEEDED(IUnknown_QueryService(pbb, SID_SExplorerToolbar, IID_PPV_ARG(ISearchItems, &psi)))) { // get the default search url WCHAR wszSearchUrl[INTERNET_MAX_URL_LENGTH]; if (SUCCEEDED(psi->GetDefaultSearchUrl(wszSearchUrl, ARRAYSIZE(wszSearchUrl)))) { IBandNavigate* pbn; if (SUCCEEDED(pbb->QueryInterface(IID_PPV_ARG(IBandNavigate, &pbn)))) { // reuse pidl IECreateFromPathW(wszSearchUrl, &pidl); pbn->Select(pidl); pbn->Release(); } } psi->Release(); } ILFree(pidl); } IWebBrowser2* pwb; hr = pbb->GetObjectBB(IID_PPV_ARG(IWebBrowser2, &pwb)); //set the search pane's opener property if (SUCCEEDED(hr)) { IDispatch* pdisp; if (SUCCEEDED(pwb->get_Document(&pdisp)) && pdisp) { IHTMLDocument2* pDoc; if (SUCCEEDED(pdisp->QueryInterface(IID_PPV_ARG(IHTMLDocument2, &pDoc))) && pDoc) { IHTMLWindow2* pWindow; if (SUCCEEDED(pDoc->get_parentWindow(&pWindow)) && pWindow) { VARIANT var; VariantInit(&var); var.vt = VT_DISPATCH; // unknown or dispatch QI? _omwin.QueryInterface(IID_IUnknown, (void **)&var.pdispVal); pWindow->put_opener(var); VariantClear(&var); pWindow->Release(); } pDoc->Release(); } pdisp->Release(); } } if (SUCCEEDED(hr)) { hr = pwb->QueryInterface(IID_ITargetFramePriv, (void **)ppunkTargetFrame); pwb->Release(); } pbb->Release(); } pband->Release(); } } else { //maybe we're the search bar //hack to let search pane know to remember the next navigation IUnknown *punkThis; if (SUCCEEDED(_psb->QueryInterface(IID_PPV_ARG(IUnknown, &punkThis)))) { hr = QueryInterface(IID_PPV_ARG(ITargetFramePriv, &ptgfpTargetFrame)); if (SUCCEEDED(hr)) *ppunkTargetFrame = ptgfpTargetFrame; ptgfpTargetFrame = NULL; punkThis->Release(); } } goto exitPoint; } // content pane of MediaBar: if (targetType == TARGET_MEDIA) { SA_BSTRGUID strGuid; VARIANT vaGuid; InitFakeBSTR(&strGuid, CLSID_MediaBand); vaGuid.vt = VT_BSTR; vaGuid.bstrVal = strGuid.wsz; //if we're in an explorer bar, use the proxy's pbs IBrowserService *pbs = _pbs; if (_psb != _psbProxy) { EVAL(SUCCEEDED(_psbProxy->QueryInterface(IID_PPV_ARG(IBrowserService, &pbs)))); } IUnknown_Exec(pbs, &CGID_ShellDocView, SHDVID_SHOWBROWSERBAR, 1, &vaGuid, NULL); VARIANT vaPunkBand = {0}; hr = IUnknown_Exec(pbs, &CGID_ShellDocView, SHDVID_GETBROWSERBAR, NULL, NULL, &vaPunkBand); if (_psb != _psbProxy) { ATOMICRELEASE(pbs); } if (hr == S_OK) { IDeskBand* pband = (IDeskBand*)vaPunkBand.punkVal; ASSERT(pband); if (pband) { IBrowserBand* pbb; hr = pband->QueryInterface(IID_PPV_ARG(IBrowserBand, &pbb)); if (SUCCEEDED(hr)) { IWebBrowser2* pwb; hr = pbb->GetObjectBB(IID_PPV_ARG(IWebBrowser2, &pwb)); //set the media pane's opener property if (SUCCEEDED(hr)) { IDispatch* pdisp; if (SUCCEEDED(pwb->get_Document(&pdisp)) && pdisp) { IHTMLDocument2* pDoc; if (SUCCEEDED(pdisp->QueryInterface(IID_PPV_ARG(IHTMLDocument2, &pDoc))) && pDoc) { IHTMLWindow2* pWindow; if (SUCCEEDED(pDoc->get_parentWindow(&pWindow)) && pWindow) { VARIANT var; VariantInit(&var); var.vt = VT_DISPATCH; // are we supposed to QI for dispatch or unknown here? _omwin.QueryInterface(IID_IUnknown, (void**)&var.pdispVal); pWindow->put_opener(var); VariantClear(&var); pWindow->Release(); } pDoc->Release(); } pdisp->Release(); } } if (SUCCEEDED(hr)) { hr = pwb->QueryInterface(IID_ITargetFramePriv, (void **)ppunkTargetFrame); pwb->Release(); } pbb->Release(); } pband->Release(); } } else { ASSERT(0); // means we have no explorer bands at all........ // but the SHDVID_SHOWBROWSERBAR just before does launch the media bar } goto exitPoint; } hr = QueryInterface(IID_PPV_ARG(IUnknown, &punkThis)); ASSERT(punkThis != NULL); if (targetType == TARGET_SELF) { *ppunkTargetFrame = punkThis; // Set punkThis to NULL to prevent Release at exit punkThis = NULL; } else // _blank, _parent, _top { hr = GetParentFrame(&punkParent); if (hr != S_OK) goto exitPoint; if (punkParent == NULL) { if (targetType == TARGET_PARENT || targetType == TARGET_TOP) { *ppunkTargetFrame = punkThis; // Set punkThis to NULL to prevent Release at exit punkThis = NULL; } else // TARGET_BLANK { if (dwFlags & FINDFRAME_JUSTTESTEXISTENCE) { // It is the client's responsibility to handle "_blank" hr = S_OK; } else { // CreateTargetFrame will not work with AOL 3.01 clients // so we must return E_FAIL hr = E_FAIL; } *ppunkTargetFrame = NULL; } } else // punkParent != NULL { // Handle parent ourself, defer _top and _blank to top level frame if (targetType == TARGET_PARENT) { *ppunkTargetFrame = punkParent; // Set punkThisFrame to NULL to prevent Release at exit punkParent = NULL; } else { hr = punkParent->QueryInterface(IID_PPV_ARG(ITargetFramePriv, &ptgfpTargetFrame)); if (hr != S_OK) goto exitPoint; hr = ptgfpTargetFrame->FindFrameInContext(pszTargetName, punkThis, dwFlags, ppunkTargetFrame); } } } exitPoint: SAFERELEASE(punkThis); SAFERELEASE(punkThisFrame); SAFERELEASE(ptgfpTargetFrame); SAFERELEASE(punkParent); return hr; } HRESULT CIEFrameAuto::_GetOleObject(IOleObject** ppobj) { HRESULT hres = E_UNEXPECTED; if (_pbs) { hres = _pbs->GetOleObject(ppobj); } return hres; } // ITargetFrame implementation for backwards compatibility HRESULT CIEFrameAuto::CTargetFrame::QueryInterface(REFIID riid, LPVOID * ppvObj) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->QueryInterface(riid, ppvObj); } ULONG CIEFrameAuto::CTargetFrame::AddRef(void) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->AddRef(); } ULONG CIEFrameAuto::CTargetFrame::Release(void) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->Release(); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::SetFrameName SYNOPSIS: Sets the Frame Name. Frees current one if exists. ********************************************************************/ STDMETHODIMP CIEFrameAuto::CTargetFrame::SetFrameName(LPCOLESTR pszFrameName) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->SetFrameName(pszFrameName); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::GetFrameName SYNOPSIS: Gets the Frame Name. Allocates a copy (this is an [OUT] parameter ********************************************************************/ STDMETHODIMP CIEFrameAuto::CTargetFrame::GetFrameName(WCHAR **ppszFrameName) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->GetFrameName(ppszFrameName); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::GetParentFrame SYNOPSIS: Gets an the IUnknown pointer of the parent frame, or NULL if this is a top level frame. This pointer must be Released by Caller after use. IMPLEMENTATION: A Frame Container is required to implement ITargetFrame::GetParentFrame and implement GetParentFrame by returning the IUnknown pointer of the Browser that hosts it. A Browser implements GetParentFrame by returning NULL if it's top level or calling GetParentFrame on its Container if it is embedded. ********************************************************************/ STDMETHODIMP CIEFrameAuto::CTargetFrame::GetParentFrame(LPUNKNOWN *ppunkParentFrame) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->GetParentFrame(ppunkParentFrame); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::FindFrame SYNOPSIS: Gets an the IUnknown pointer of the frame referenced by pszTarget. This pointer must be Released by Caller after use. punkContextFrame, if not NULL, is the IUnknown pointer for the immediate descendent frame in whose subtree the Target reference (eg anchor with a Target tag) resides. dwFlags are flags which modify FindFrame's behaviour and can be any combination of FINDFRAME_FLAGS. In particular, SETTING FINDFRAME_JUSTTESTEXISTENCE allows the caller to defeat the default FindFrame behavior of creating a new top level frame named pszTarget, if pszTarget does not exist. IMPLEMENTATION: NOTE: In HTML all anchors and other TARGET tags can occur ONLY in leaf FRAMES!! punkContextFrame is significant only if pszTarget is not a MAGIC target name (_self, _top, _blank, _parent). Non-MAGIC target names: first off, this frame should check if it matches pszTarget and return it's own IUnknown pointer forthwith. if punkContextFrame is not NULL, all child Frames except punkContextFrame should be searched (depth first) for pszTarget with punkContextFrame == NULL. on failure, the parent of this frame should be recursively called with this frame replacing punkContextFrame. if this is a top level Frame (so there is no parent), all top level frames should be called with punkContextFrame == NULL. if this fails, then a new top level frame should be created (unless FINDFRAME_JUSTTESTEXISTENCE is set in dwFlags), named pszTarget and its IUnknown returned. if punkContextFrame is NULL, all child Frames should be searched depth first for pszTarget. on failure, NULL should be returned. MAGIC target names: _self should return the IUnknown of this ITargetFrame _top should be recursively passed up to the top level ITargetFrame. if there is no FrameParent, this defaults to _self. _parent should return the IUnknown of the FrameParent ITargetFrame. if there is no FrameParent, this defaults to _self. _blank should be recursively passed up to the top level ITargetFrame, which should create a unnamed top level frame ********************************************************************/ STDMETHODIMP CIEFrameAuto::CTargetFrame::FindFrame(LPCOLESTR pszTargetName, LPUNKNOWN punkContextFrame, DWORD dwFlags, LPUNKNOWN *ppunkTargetFrame) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->FindFrame(pszTargetName, dwFlags|FINDFRAME_OLDINTERFACE, ppunkTargetFrame); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::RemoteNavigate SYNOPSIS: Used in response to WM_COPYDATA message with dwData equal to TF_NAVIGATE. Does a FindFrame (named target only) and if frame is not found returns S_FALSE. If found, returns S_OK and fires off the navigate. cLength is number of ULONGs in pulData TODO: Relies on RemoteNavigate member of top level MSHTML docobject host. Need to write the equivalent code to work if top level frame contains some other DocObject. Post,etc require help from bindstatuscallback. ********************************************************************/ HRESULT CIEFrameAuto::CTargetFrame::RemoteNavigate(ULONG cLength,ULONG *pulData) { // FEATURE chrisfra 10/22/96 - this is now here purely for backwards compatibility and // should be removed for ie4.0 return E_FAIL; } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::SetFrameSrc SYNOPSIS: Sets the Frame original SRC url. Frees current one if exists. ********************************************************************/ HRESULT CIEFrameAuto::CTargetFrame::SetFrameSrc(LPCOLESTR pszFrameSrc) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->SetFrameSrc(pszFrameSrc); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::GetFrameSrc SYNOPSIS: Gets the Frame original URL. Allocates a copy (this is an [OUT] parameter NOTES: If we are at top level, SRC is dynamic, so ask our contained DocObject to do it for us. ********************************************************************/ HRESULT CIEFrameAuto::CTargetFrame::GetFrameSrc(WCHAR **ppszFrameSrc) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->GetFrameSrc(ppszFrameSrc); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::GetFramesContainer SYNOPSIS: Returns an addref'ed pointer to the LPOLECONTAINER for our nested frames. Can be NULL. ********************************************************************/ HRESULT CIEFrameAuto::CTargetFrame::GetFramesContainer(LPOLECONTAINER *ppContainer) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->GetFramesContainer(ppContainer); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::SetFrameOptions SYNOPSIS: Sets the Frame Options. ********************************************************************/ HRESULT CIEFrameAuto::CTargetFrame::SetFrameOptions(DWORD dwFlags) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->SetFrameOptions(dwFlags); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::GetFrameOptions SYNOPSIS: Returns the frame options ********************************************************************/ HRESULT CIEFrameAuto::CTargetFrame::GetFrameOptions(LPDWORD pdwFlags) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->GetFrameOptions(pdwFlags); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::SetFrameMargins SYNOPSIS: Sets the Frame margins. ********************************************************************/ HRESULT CIEFrameAuto::CTargetFrame::SetFrameMargins(DWORD dwWidth, DWORD dwHeight) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->SetFrameMargins(dwWidth, dwHeight); } /******************************************************************* NAME: CIEFrameAuto::CTargetFrame::GetFrameMargins SYNOPSIS: Returns the frame margins ********************************************************************/ HRESULT CIEFrameAuto::CTargetFrame::GetFrameMargins(LPDWORD pdwWidth, LPDWORD pdwHeight) { CIEFrameAuto* pie = IToClass(CIEFrameAuto, _TargetFrame, this); return pie->GetFrameMargins(pdwWidth, pdwHeight); } /******************************************************************* NAME: CIEFrameAuto::FindBrowserByIndex SYNOPSIS: Returns an IUnknown that points to a Browser that has the requested index ********************************************************************/ HRESULT CIEFrameAuto::FindBrowserByIndex(DWORD dwID,IUnknown **ppunkBrowser) { HRESULT hr = S_OK; IOleContainer * poc = NULL; IBrowserService *pbs; ASSERT(ppunkBrowser); *ppunkBrowser = NULL; if (!_psb) return E_FAIL; // first check self if(SUCCEEDED(_psb->QueryInterface(IID_PPV_ARG(IBrowserService, &pbs)))) { ASSERT(pbs); if(dwID == pbs->GetBrowserIndex()) { // this is the one... *ppunkBrowser = (IUnknown *)pbs; goto exitPoint; } SAFERELEASE(pbs); } hr = GetFramesContainer(&poc); if (SUCCEEDED(hr) && poc) { IEnumUnknown *penum = NULL; hr = E_FAIL; if (S_OK != poc->EnumObjects(OLECONTF_EMBEDDINGS, &penum) || penum == NULL) goto exitPoint; IUnknown *punk; while (S_OK == penum->Next(1, &punk, NULL)) { if (punk == NULL) break; ITargetFramePriv *ptf; if (SUCCEEDED(punk->QueryInterface(IID_PPV_ARG(ITargetFramePriv, &ptf)))) { ASSERT(ptf); hr = ptf->FindBrowserByIndex(dwID, ppunkBrowser); ptf->Release(); } punk->Release(); if (SUCCEEDED(hr)) //foundit! break; } // Native frames - no WebBrowser OC in frame. Note that // if a WebOC is included on a web page with an // tag, navigations in the WebOC will be placed in the travel // log. However, since the WebOC does not currently support // ITravelLogClient, back and forward will not work correctly. // The WebOC will need to be updated to support ITravelLogClient. // if (FAILED(hr)) { IHTMLDocument2 *pDoc; if (SUCCEEDED(poc->QueryInterface(IID_PPV_ARG(IHTMLDocument2, &pDoc)))) { IHTMLWindow2 *pWnd; if (SUCCEEDED(pDoc->get_parentWindow(&pWnd))) { IHTMLWindow2 *pTop; if (SUCCEEDED(pWnd->get_top(&pTop))) { ITravelLogClient *ptlc; if (SUCCEEDED(pTop->QueryInterface(IID_PPV_ARG(ITravelLogClient, &ptlc)))) { hr = ptlc->FindWindowByIndex(dwID, ppunkBrowser); ptlc->Release(); } pTop->Release(); } pWnd->Release(); } pDoc->Release(); } } SAFERELEASE(penum); poc->Release(); } else { hr = E_FAIL; } exitPoint: return hr; } // External helper function for TRIDENT when it stands alone w/o the steely thews of // shdocvw CIEFrameAuto to shield it's pityfull body. STDAPI HlinkFindFrame(LPCWSTR pszFrameName, LPUNKNOWN *ppunk) { HRESULT hres = E_FAIL; *ppunk = NULL; if (pszFrameName) { switch (ParseTargetType(pszFrameName)) { case TARGET_FRAMENAME: hres = _TargetTopLevelWindows(NULL, pszFrameName, FINDFRAME_JUSTTESTEXISTENCE, ppunk); break; case TARGET_BLANK: hres = S_FALSE; break; } } return hres; }