1083 lines
30 KiB
C++
1083 lines
30 KiB
C++
|
//*********************************************************************
|
||
|
//* Microsoft Windows **
|
||
|
//* Copyright(c) Microsoft Corp., 1999 **
|
||
|
//*********************************************************************
|
||
|
//
|
||
|
// MSOBWEB.CPP - Implementation of CObWebBrowser
|
||
|
//
|
||
|
// HISTORY:
|
||
|
//
|
||
|
// 1/27/99 a-jaswed Created.
|
||
|
//
|
||
|
// Class which will call up an IOleSite and the WebOC
|
||
|
// and provide external interfaces.
|
||
|
|
||
|
#include <exdispid.h>
|
||
|
#include <mshtml.h> // IHTMLElement, IHTMLDocument2, IHTMLWindow2
|
||
|
#include <mshtmhst.h>
|
||
|
#include <tchar.h>
|
||
|
|
||
|
#include "msobweb.h"
|
||
|
#include "appdefs.h"
|
||
|
#include "zmouse.h"
|
||
|
#include "util.h"
|
||
|
|
||
|
const VARIANT c_vaEmpty = {0};
|
||
|
|
||
|
#define PVAREMPTY ((VARIANT*)&c_vaEmpty)
|
||
|
#define VK_N L'N'
|
||
|
#define VK_P L'P'
|
||
|
#define VK_Z L'Z'
|
||
|
#define VK_ENTER 0x0D
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Creation function used by CFactory.
|
||
|
//
|
||
|
HRESULT CObWebBrowser::CreateInstance(IUnknown* pOuterUnknown,
|
||
|
CUnknown** ppNewComponent)
|
||
|
{
|
||
|
if (pOuterUnknown != NULL)
|
||
|
{
|
||
|
// Don't allow aggregation. Just for the heck of it.
|
||
|
return CLASS_E_NOAGGREGATION;
|
||
|
}
|
||
|
|
||
|
*ppNewComponent = new CObWebBrowser(pOuterUnknown);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// NondelegatingQueryInterface
|
||
|
//
|
||
|
HRESULT __stdcall
|
||
|
CObWebBrowser::NondelegatingQueryInterface(const IID& iid, void** ppv)
|
||
|
{
|
||
|
if (iid == IID_IObWebBrowser)
|
||
|
{
|
||
|
return FinishQI(static_cast<IObWebBrowser*>(this), ppv);
|
||
|
}
|
||
|
else if (iid == IID_IDispatch)
|
||
|
{
|
||
|
return FinishQI(static_cast<IDispatch*>(this), ppv);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return CUnknown::NondelegatingQueryInterface(iid, ppv);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Constructor
|
||
|
//
|
||
|
CObWebBrowser::CObWebBrowser(IUnknown* pOuterUnknown)
|
||
|
: CUnknown(pOuterUnknown),
|
||
|
m_hMainWnd (NULL),
|
||
|
m_pOleSite (NULL),
|
||
|
m_lpOleObject (NULL),
|
||
|
m_lpWebBrowser (NULL),
|
||
|
m_dwDrawAspect (0),
|
||
|
m_dwcpCookie (0),
|
||
|
m_fInPlaceActive (FALSE),
|
||
|
m_fOnErrorWasHooked(FALSE),
|
||
|
m_pOleSiteWMP (NULL),
|
||
|
m_lpOleObjectWMP (NULL),
|
||
|
m_pWMPPlayer (NULL)
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
IUnknown* pOleSiteIUnkwn = NULL;
|
||
|
|
||
|
FORMATETC fromAtetc;
|
||
|
|
||
|
// Create a new OLE site w/ WebOC
|
||
|
m_pOleSite = new COleSite();
|
||
|
if (m_pOleSite == NULL)
|
||
|
{
|
||
|
// We're hosed if this happens.
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SETDefFormatEtc(fromAtetc, 0, TYMED_NULL);
|
||
|
|
||
|
if(SUCCEEDED(OleCreate(CLSID_WebBrowser,
|
||
|
IID_IWebBrowser2,
|
||
|
OLERENDER_DRAW,
|
||
|
&fromAtetc,
|
||
|
m_pOleSite->m_pOleClientSite,
|
||
|
m_pOleSite->m_lpStorage,
|
||
|
(LPVOID*)&m_lpWebBrowser)) && m_lpWebBrowser)
|
||
|
{
|
||
|
|
||
|
InitBrowserObject();
|
||
|
}
|
||
|
|
||
|
// Create an extra control for the Windows Media Player
|
||
|
m_pOleSiteWMP = new COleSite();
|
||
|
if (m_pOleSiteWMP == NULL)
|
||
|
{
|
||
|
goto LFail;
|
||
|
}
|
||
|
|
||
|
if (FAILED(OleCreate(__uuidof(WMPOCX),
|
||
|
__uuidof(IWMPPlayer),
|
||
|
OLERENDER_NONE,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
m_pOleSiteWMP->m_lpStorage,
|
||
|
(LPVOID*)&m_pWMPPlayer)))
|
||
|
{
|
||
|
goto LFail;
|
||
|
}
|
||
|
|
||
|
// Get An OleObject from the WebBrowser Interface
|
||
|
if (FAILED(m_pWMPPlayer->QueryInterface(IID_IOleObject, (LPVOID*)&m_lpOleObjectWMP)))
|
||
|
{
|
||
|
goto LFail;
|
||
|
}
|
||
|
|
||
|
m_pOleSiteWMP->m_lpOleObject = m_lpOleObjectWMP;
|
||
|
// inform object handler/DLL object that it is used in the embedding container's context
|
||
|
OleSetContainedObject(m_lpOleObjectWMP, TRUE);
|
||
|
|
||
|
return;
|
||
|
|
||
|
LFail:
|
||
|
if (m_pWMPPlayer != NULL)
|
||
|
{
|
||
|
m_pWMPPlayer->Release();
|
||
|
m_pWMPPlayer = NULL;
|
||
|
}
|
||
|
if (m_pOleSiteWMP != NULL)
|
||
|
{
|
||
|
m_pOleSiteWMP->Release();
|
||
|
m_pOleSiteWMP = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Destructor
|
||
|
//
|
||
|
CObWebBrowser::~CObWebBrowser()
|
||
|
{
|
||
|
if (m_lpOleObjectWMP)
|
||
|
{
|
||
|
m_lpOleObjectWMP->Close(OLECLOSE_NOSAVE);
|
||
|
m_pOleSiteWMP->m_hWnd = NULL;;
|
||
|
m_lpOleObjectWMP->Release();
|
||
|
m_lpOleObjectWMP = NULL;
|
||
|
m_pOleSiteWMP->m_lpOleObject = NULL;
|
||
|
}
|
||
|
if (m_pWMPPlayer != NULL)
|
||
|
{
|
||
|
m_pWMPPlayer->Release();
|
||
|
m_pWMPPlayer = NULL;
|
||
|
}
|
||
|
if (m_pOleSiteWMP != NULL)
|
||
|
{
|
||
|
m_pOleSiteWMP->Release();
|
||
|
m_pOleSiteWMP = NULL;
|
||
|
}
|
||
|
|
||
|
if (m_lpOleObject)
|
||
|
{
|
||
|
LPVIEWOBJECT lpViewObject = NULL;
|
||
|
// ensure object is closed;
|
||
|
CloseOleObject();
|
||
|
|
||
|
m_lpOleObject->QueryInterface(IID_IViewObject, (LPVOID*)&lpViewObject);
|
||
|
|
||
|
if (lpViewObject)
|
||
|
{
|
||
|
// Remove the view advise
|
||
|
lpViewObject->SetAdvise(m_dwDrawAspect, 0, NULL);
|
||
|
lpViewObject->Release();
|
||
|
}
|
||
|
m_lpOleObject->Release();
|
||
|
m_lpOleObject = NULL;
|
||
|
m_pOleSite->m_lpOleObject = NULL;
|
||
|
}
|
||
|
|
||
|
if (m_lpWebBrowser)
|
||
|
{
|
||
|
m_lpWebBrowser->Release();
|
||
|
m_lpWebBrowser = NULL;
|
||
|
}
|
||
|
|
||
|
if (m_lpOleObject)
|
||
|
{
|
||
|
m_lpOleObject->Release();
|
||
|
m_lpOleObject = NULL;
|
||
|
}
|
||
|
|
||
|
if(m_pOleSite)
|
||
|
{
|
||
|
m_pOleSite->Release();
|
||
|
m_pOleSite = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// FinalRelease -- Clean up the aggreated objects.
|
||
|
//
|
||
|
void CObWebBrowser::FinalRelease()
|
||
|
{
|
||
|
CUnknown::FinalRelease();
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// IObWebBrowser Implementation
|
||
|
///////////////////////////////////////////////////////////
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// AttachToWindow
|
||
|
//
|
||
|
HRESULT CObWebBrowser::AttachToWindow(HWND hWnd)
|
||
|
{
|
||
|
if(m_hMainWnd)
|
||
|
{
|
||
|
CloseOleObject();
|
||
|
}
|
||
|
|
||
|
//Set the new hwnd
|
||
|
m_hMainWnd = hWnd;
|
||
|
m_pOleSite->m_hWnd = m_hMainWnd;
|
||
|
|
||
|
InPlaceActivate();
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// PreTranslateMessage -- Do not use with size parameters because addin the org...
|
||
|
//
|
||
|
HRESULT CObWebBrowser::PreTranslateMessage(LPMSG lpMsg)
|
||
|
{
|
||
|
HRESULT hr = S_FALSE;
|
||
|
|
||
|
switch(lpMsg->message)
|
||
|
{
|
||
|
case WM_LBUTTONDOWN:
|
||
|
{
|
||
|
WPARAM dwKeys = lpMsg->wParam; // key flags
|
||
|
|
||
|
if (MK_SHIFT & dwKeys)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case WM_MOUSEWHEEL:
|
||
|
case WM_MBUTTONDOWN:
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
case WM_RBUTTONDOWN :
|
||
|
{
|
||
|
VARIANT varg1;
|
||
|
VARIANT varg2;
|
||
|
IDispatch *pdisp = NULL;
|
||
|
IDispatch* pDisp = NULL;
|
||
|
IHTMLWindow2* pFrWin = NULL;
|
||
|
IHTMLDocument2* pDoc = NULL;
|
||
|
IHTMLElementCollection *pColl = NULL;
|
||
|
|
||
|
IHTMLElement* pElement = NULL;
|
||
|
IHTMLStyle* pStyle = NULL;
|
||
|
BOOL bFilter = FALSE;
|
||
|
HRESULT hrDoc = S_OK;
|
||
|
|
||
|
VariantInit(&varg1);
|
||
|
V_VT(&varg1) = VT_BSTR;
|
||
|
varg1.bstrVal= SysAllocString(L"MovieFrame");
|
||
|
|
||
|
VariantInit(&varg2);
|
||
|
varg2.vt = VT_UINT;
|
||
|
varg2.lVal= 0;
|
||
|
|
||
|
if(SUCCEEDED(m_lpWebBrowser->get_Document(&pDisp))&& pDisp)
|
||
|
{
|
||
|
if(SUCCEEDED(pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc)) && pDoc)
|
||
|
{
|
||
|
if(SUCCEEDED(pDoc->get_all( &pColl )) && pColl)
|
||
|
{
|
||
|
if(SUCCEEDED(pColl->item(varg1, varg2, &pdisp)) && pdisp)
|
||
|
{
|
||
|
|
||
|
if(SUCCEEDED(pdisp->QueryInterface(IID_IHTMLElement, (void**)&pElement)) && pElement)
|
||
|
{
|
||
|
if(SUCCEEDED(pElement->get_style(&pStyle)) && pStyle)
|
||
|
{
|
||
|
BSTR bstrVisibility = NULL;
|
||
|
BSTR bstrDisplay = NULL;
|
||
|
|
||
|
pStyle->get_visibility(&bstrVisibility);
|
||
|
|
||
|
pStyle->get_display(&bstrDisplay);
|
||
|
|
||
|
if (bstrDisplay)
|
||
|
{
|
||
|
if (lstrcmpi(bstrDisplay, L"none") != 0)
|
||
|
bFilter = TRUE;
|
||
|
}
|
||
|
if (bstrVisibility)
|
||
|
{
|
||
|
if (lstrcmpi(bstrVisibility, L"hidden") != 0)
|
||
|
bFilter = TRUE;
|
||
|
}
|
||
|
|
||
|
pStyle->Release();
|
||
|
pStyle = NULL;
|
||
|
}
|
||
|
pElement->Release();
|
||
|
pElement = NULL;
|
||
|
}
|
||
|
pdisp->Release();
|
||
|
pdisp = NULL;
|
||
|
}
|
||
|
|
||
|
pColl->Release();
|
||
|
pColl = NULL;
|
||
|
}
|
||
|
pDoc->Release();
|
||
|
pDoc = NULL;
|
||
|
}
|
||
|
pDisp->Release();
|
||
|
pDisp = NULL;
|
||
|
}
|
||
|
if (bFilter)
|
||
|
return S_OK;
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
case WM_KEYDOWN:
|
||
|
{
|
||
|
if ( lpMsg->wParam == VK_F3 )
|
||
|
{
|
||
|
/* Convert keyboard messages came into WM_COMMANDs to
|
||
|
* the found dialog. Return TRUE because we procecessed.
|
||
|
*/
|
||
|
if ( (GetKeyState ( VK_SHIFT) & 0x8000) && (GetKeyState( VK_CONTROL) & 0x8000))
|
||
|
{
|
||
|
HWND hWnd = FindWindow(OOBE_MAIN_CLASSNAME, NULL);
|
||
|
PostMessage(hWnd, WM_COMMAND, WM_SKIP, 0L); //MAKELPARAM(lpMsg->hwnd, BY_KEYBOARD));
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(lpMsg->wParam == VK_F1)
|
||
|
{
|
||
|
HWND hWnd = FindWindow(OOBE_MAIN_CLASSNAME, DEFAULT_WINDOW_TEXT);
|
||
|
if (hWnd)
|
||
|
{
|
||
|
PostMessage(hWnd, WM_COMMAND, WM_AGENT_HELP, 0L);
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(
|
||
|
#ifndef DBG
|
||
|
(lpMsg->wParam == VK_F5) ||
|
||
|
#endif
|
||
|
(lpMsg->wParam == VK_F6) || // F6 key deletes the insertation point cursor when filling out the Registration info.
|
||
|
(((lpMsg->wParam == VK_N) || (lpMsg->wParam == VK_Z) ||
|
||
|
(lpMsg->wParam == VK_P)) && ((GetKeyState(VK_CONTROL) & 0x1000))))
|
||
|
return S_OK;
|
||
|
}
|
||
|
//Fall through!!!
|
||
|
|
||
|
case WM_SYSKEYDOWN:
|
||
|
{
|
||
|
|
||
|
if((((lpMsg->wParam == VK_LEFT) ||
|
||
|
(lpMsg->wParam == VK_RIGHT) ||
|
||
|
(lpMsg->wParam == VK_HOME)) && (GetKeyState(VK_MENU) & 0x1000)) ||
|
||
|
((lpMsg->wParam == VK_ENTER ) && (GetKeyState( VK_SHIFT) & 0x8000)) ||
|
||
|
// Space +Shift +Ctrl is a Narrator key combination, don't diable this.
|
||
|
((lpMsg->wParam == VK_SPACE) && (GetKeyState( VK_SHIFT) & 0x8000) &&
|
||
|
(GetKeyState( VK_CONTROL ) & 0x8000))
|
||
|
)
|
||
|
return S_OK;
|
||
|
else if((lpMsg->wParam == VK_BACK) || (lpMsg->wParam == VK_SPACE))
|
||
|
{
|
||
|
VARIANT varRet;
|
||
|
VARIANTARG varg;
|
||
|
|
||
|
IDispatch* pDisp = NULL;
|
||
|
IHTMLWindow2* pFrWin = NULL;
|
||
|
IHTMLDocument2* pDoc = NULL;
|
||
|
IHTMLDocument2* pFrDoc = NULL;
|
||
|
IHTMLElement* pActElem = NULL;
|
||
|
IHTMLFramesCollection2* pColl = NULL;
|
||
|
BOOL bDontTA = TRUE;
|
||
|
HRESULT hrDoc = S_OK;
|
||
|
|
||
|
VariantInit(&varg);
|
||
|
V_VT(&varg) = VT_BSTR;
|
||
|
varg.bstrVal= SysAllocString(DEFAULT_FRAME_NAME);
|
||
|
|
||
|
if(SUCCEEDED(m_lpWebBrowser->get_Document(&pDisp))&& pDisp)
|
||
|
{
|
||
|
if(SUCCEEDED(pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc)) && pDoc)
|
||
|
{
|
||
|
if(SUCCEEDED(pDoc->get_frames(&pColl)) && pColl)
|
||
|
{
|
||
|
if(SUCCEEDED(pColl->item(&varg, &varRet)) && varRet.pdispVal)
|
||
|
{
|
||
|
if(SUCCEEDED(varRet.pdispVal->QueryInterface(IID_IHTMLWindow2, (void**)&pFrWin)) && pFrWin)
|
||
|
{
|
||
|
if(SUCCEEDED( hrDoc = pFrWin->get_document(&pFrDoc)) && pFrDoc)
|
||
|
{
|
||
|
if(SUCCEEDED(pFrDoc->get_activeElement(&pActElem)) && pActElem)
|
||
|
{
|
||
|
BSTR bstr = NULL;
|
||
|
|
||
|
if (SUCCEEDED(pActElem->get_tagName(&bstr)))
|
||
|
{
|
||
|
LPWSTR lpszType = bstr;
|
||
|
|
||
|
if ( (lstrcmpi(lpszType, L"TEXTAREA") == 0) ||
|
||
|
(lstrcmpi(lpszType, L"INPUT") == 0) ||
|
||
|
(lstrcmpi(lpszType, L"BUTTON") == 0) )
|
||
|
bDontTA = FALSE;
|
||
|
}
|
||
|
|
||
|
pActElem->Release();
|
||
|
pActElem = NULL;
|
||
|
}
|
||
|
pFrDoc->Release();
|
||
|
pFrDoc = NULL;
|
||
|
}
|
||
|
}
|
||
|
varRet.pdispVal->Release();
|
||
|
varRet.pdispVal = NULL;
|
||
|
}
|
||
|
pColl->Release();
|
||
|
pColl = NULL;
|
||
|
}
|
||
|
pDoc->Release();
|
||
|
pDoc = NULL;
|
||
|
}
|
||
|
pDisp->Release();
|
||
|
pDisp = NULL;
|
||
|
}
|
||
|
|
||
|
if(bDontTA)
|
||
|
{
|
||
|
if ( !SUCCEEDED(hrDoc) ) // cross frame access denied for server page.
|
||
|
{
|
||
|
return S_FALSE; // Send VK_BACK to the page.
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(m_lpWebBrowser)
|
||
|
{
|
||
|
IOleInPlaceActiveObject* lpIPA;
|
||
|
|
||
|
if(SUCCEEDED(m_lpWebBrowser->QueryInterface(IID_IOleInPlaceActiveObject,(void**)&lpIPA)))
|
||
|
{
|
||
|
hr = lpIPA->TranslateAccelerator(lpMsg);
|
||
|
|
||
|
lpIPA->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// Navigate
|
||
|
HRESULT CObWebBrowser::Navigate(WCHAR* pszUrl, WCHAR* pszTarget)
|
||
|
{
|
||
|
VARIANT varURL;
|
||
|
VARIANT varTarget;
|
||
|
VARIANT v;
|
||
|
IDispatch *pdisp = NULL;
|
||
|
IHTMLWindow2 *pwin = NULL;
|
||
|
IHTMLDocument2 *pdoc = NULL;
|
||
|
|
||
|
TRACE2(L"Attempting to navigate: \n\tUrl: %s\n\tTarget: %s\n",
|
||
|
(NULL != pszUrl) ? pszUrl : L"NONE",
|
||
|
(NULL != pszTarget) ? pszTarget : L"NONE"
|
||
|
);
|
||
|
|
||
|
VariantInit(&varURL);
|
||
|
VariantInit(&varTarget);
|
||
|
VariantInit(&v);
|
||
|
|
||
|
V_VT(&varURL) = VT_BSTR;
|
||
|
V_VT(&varTarget) = VT_BSTR;
|
||
|
|
||
|
varURL.bstrVal = SysAllocString(pszUrl);
|
||
|
varTarget.bstrVal = SysAllocString(pszTarget);
|
||
|
|
||
|
m_lpWebBrowser->Navigate2(&varURL, PVAREMPTY, &varTarget, PVAREMPTY, PVAREMPTY);
|
||
|
|
||
|
if (FAILED(m_lpWebBrowser->get_Document(&pdisp)) || pdisp == NULL)
|
||
|
{
|
||
|
TRACE(L"Couldn't find the web browser's document object!");
|
||
|
goto LCleanup;
|
||
|
}
|
||
|
|
||
|
if (FAILED(pdisp->QueryInterface(IID_IHTMLDocument2, (void**)&pdoc)))
|
||
|
{
|
||
|
TRACE(L"The web browser's document doesn't support IHTMLDocument2!");
|
||
|
goto LCleanup;
|
||
|
}
|
||
|
|
||
|
if (FAILED(pdoc->get_parentWindow(&pwin)) || pwin == NULL)
|
||
|
{
|
||
|
TRACE(L"There's no window for the web browser's document object!");
|
||
|
goto LCleanup;
|
||
|
}
|
||
|
|
||
|
V_VT(&v) = VT_DISPATCH;
|
||
|
QueryInterface(IID_IDispatch, (void**)&V_DISPATCH(&v));
|
||
|
|
||
|
if (FAILED(pwin->put_onerror(v)))
|
||
|
{
|
||
|
TRACE(L"Couldn't set the script error hook!");
|
||
|
goto LCleanup;
|
||
|
}
|
||
|
|
||
|
m_fOnErrorWasHooked = TRUE;
|
||
|
|
||
|
LCleanup:
|
||
|
if (V_VT(&v) == VT_DISPATCH)
|
||
|
{
|
||
|
V_DISPATCH(&v)->Release();
|
||
|
}
|
||
|
if (pwin != NULL)
|
||
|
{
|
||
|
pwin->Release();
|
||
|
pwin = NULL;
|
||
|
}
|
||
|
if (pdoc != NULL)
|
||
|
{
|
||
|
pdoc->Release();
|
||
|
pdoc = NULL;
|
||
|
}
|
||
|
if (pdisp != NULL)
|
||
|
{
|
||
|
pdisp->Release();
|
||
|
pdisp = NULL;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// Stop
|
||
|
HRESULT CObWebBrowser::Stop()
|
||
|
{
|
||
|
m_lpWebBrowser->Stop();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// PlayBackgroundMusic
|
||
|
STDMETHODIMP
|
||
|
CObWebBrowser::PlayBackgroundMusic()
|
||
|
{
|
||
|
IWMPSettings* psettings = NULL;
|
||
|
IWMPControls* pcontrols = NULL;
|
||
|
HRESULT hr;
|
||
|
BSTR bstr = NULL;
|
||
|
WCHAR szFile[MAX_PATH];
|
||
|
|
||
|
if (m_pWMPPlayer == NULL)
|
||
|
{
|
||
|
TRACE(L"Couldn't access the media player control.");
|
||
|
goto LExit;
|
||
|
}
|
||
|
|
||
|
ExpandEnvironmentStrings(
|
||
|
L"%SystemRoot%\\system32\\oobe\\images\\title.wma",
|
||
|
szFile,
|
||
|
sizeof(szFile)/sizeof(szFile[0]));
|
||
|
|
||
|
bstr = SysAllocString(szFile);
|
||
|
if (bstr == NULL)
|
||
|
{
|
||
|
TRACE(L"Couldn't allocate the background sound file string.");
|
||
|
goto LExit;
|
||
|
}
|
||
|
|
||
|
hr = m_pWMPPlayer->put_URL(bstr);
|
||
|
|
||
|
SysFreeString(bstr);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
TRACE(L"Couldn't set the movie file.");
|
||
|
goto LExit;
|
||
|
}
|
||
|
|
||
|
// Turn off the WMP error dialogs
|
||
|
|
||
|
hr = m_pWMPPlayer->QueryInterface(__uuidof(IWMPSettings), (LPVOID*)&psettings);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
TRACE(L"Couldn't access WMP settings.");
|
||
|
goto LExit;
|
||
|
}
|
||
|
|
||
|
hr = psettings->put_enableErrorDialogs(VARIANT_FALSE);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
TRACE(L"Couldn't turn off WMP error dialogs.");
|
||
|
goto LExit;
|
||
|
}
|
||
|
|
||
|
// Now, start playing
|
||
|
|
||
|
hr = m_pWMPPlayer->QueryInterface(__uuidof(IWMPControls), (LPVOID*)&pcontrols);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
TRACE(L"Couldn't access WMP controls.");
|
||
|
goto LExit;
|
||
|
}
|
||
|
pcontrols->play();
|
||
|
|
||
|
LExit:
|
||
|
if (pcontrols != NULL)
|
||
|
{
|
||
|
pcontrols->Release();
|
||
|
pcontrols = NULL;
|
||
|
}
|
||
|
if (psettings != NULL)
|
||
|
{
|
||
|
psettings->Release();
|
||
|
psettings = NULL;
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// PlayBackgroundMusic
|
||
|
STDMETHODIMP
|
||
|
CObWebBrowser::StopBackgroundMusic()
|
||
|
{
|
||
|
IWMPControls* pcontrols = NULL;
|
||
|
HRESULT hr;
|
||
|
|
||
|
if (m_pWMPPlayer == NULL)
|
||
|
{
|
||
|
TRACE(L"Couldn't access the media player control.");
|
||
|
goto LExit;
|
||
|
}
|
||
|
|
||
|
hr = m_pWMPPlayer->QueryInterface(__uuidof(IWMPControls), (LPVOID*)&pcontrols);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
TRACE(L"Couldn't access WMP controls.");
|
||
|
goto LExit;
|
||
|
}
|
||
|
pcontrols->stop();
|
||
|
|
||
|
LExit:
|
||
|
if (pcontrols != NULL)
|
||
|
{
|
||
|
pcontrols->Release();
|
||
|
pcontrols = NULL;
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// UnhookScriptErrorHandler
|
||
|
STDMETHODIMP
|
||
|
CObWebBrowser::UnhookScriptErrorHandler()
|
||
|
{
|
||
|
VARIANT v;
|
||
|
IDispatch *pdisp = NULL;
|
||
|
IHTMLWindow2 *pwin = NULL;
|
||
|
IHTMLDocument2 *pdoc = NULL;
|
||
|
|
||
|
if (!m_fOnErrorWasHooked)
|
||
|
{
|
||
|
goto LCleanup;
|
||
|
}
|
||
|
|
||
|
if (FAILED(m_lpWebBrowser->get_Document(&pdisp)) || pdisp == NULL)
|
||
|
{
|
||
|
TRACE(L"Couldn't find the web browser's document object!");
|
||
|
goto LCleanup;
|
||
|
}
|
||
|
|
||
|
if (FAILED(pdisp->QueryInterface(IID_IHTMLDocument2, (void**)&pdoc)))
|
||
|
{
|
||
|
TRACE(L"The web browser's document doesn't support IHTMLDocument2!");
|
||
|
goto LCleanup;
|
||
|
}
|
||
|
|
||
|
if (FAILED(pdoc->get_parentWindow(&pwin)) || pwin == NULL)
|
||
|
{
|
||
|
TRACE(L"There's no window for the web browser's document object!");
|
||
|
goto LCleanup;
|
||
|
}
|
||
|
|
||
|
VariantInit(&v);
|
||
|
V_VT(&v) = VT_DISPATCH;
|
||
|
V_DISPATCH(&v) = NULL;
|
||
|
|
||
|
pwin->put_onerror(v);
|
||
|
|
||
|
LCleanup:
|
||
|
if (pwin != NULL)
|
||
|
{
|
||
|
pwin->Release();
|
||
|
pwin = NULL;
|
||
|
}
|
||
|
if (pdoc != NULL)
|
||
|
{
|
||
|
pdoc->Release();
|
||
|
pdoc = NULL;
|
||
|
}
|
||
|
if (pdisp != NULL)
|
||
|
{
|
||
|
pdisp->Release();
|
||
|
pdisp = NULL;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// IDispatch Implementation
|
||
|
///////////////////////////////////////////////////////////
|
||
|
|
||
|
STDMETHODIMP CObWebBrowser::GetTypeInfoCount(UINT* pcInfo)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CObWebBrowser::GetTypeInfo(UINT, LCID, ITypeInfo** )
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
// CObWebBrowser::GetIDsOfNames
|
||
|
STDMETHODIMP CObWebBrowser::GetIDsOfNames(
|
||
|
/* [in] */ REFIID riid,
|
||
|
/* [size_is][in] */ OLECHAR** rgszNames,
|
||
|
/* [in] */ UINT cNames,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [size_is][out] */ DISPID* rgDispId)
|
||
|
{
|
||
|
return DISP_E_UNKNOWNNAME;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
// CObWebBrowser::Invoke
|
||
|
HRESULT CObWebBrowser::Invoke
|
||
|
(
|
||
|
DISPID dispidMember,
|
||
|
REFIID riid,
|
||
|
LCID lcid,
|
||
|
WORD wFlags,
|
||
|
DISPPARAMS* pdispparams,
|
||
|
VARIANT* pvarResult,
|
||
|
EXCEPINFO* pexcepinfo,
|
||
|
UINT* puArgErr
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
switch(dispidMember)
|
||
|
{
|
||
|
case DISPID_VALUE:
|
||
|
{
|
||
|
if (pdispparams &&
|
||
|
pdispparams->cArgs == 3)
|
||
|
{
|
||
|
VARIANT_BOOL f;
|
||
|
|
||
|
onerror(&pdispparams[0].rgvarg[2],
|
||
|
&pdispparams[0].rgvarg[1],
|
||
|
&pdispparams[0].rgvarg[0],
|
||
|
&f);
|
||
|
if (pvarResult != NULL)
|
||
|
{
|
||
|
V_VT(pvarResult) = VT_BOOL;
|
||
|
V_BOOL(pvarResult) = f;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
{
|
||
|
hr = DISP_E_MEMBERNOTFOUND;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// onerror
|
||
|
STDMETHODIMP
|
||
|
CObWebBrowser::onerror(IN VARIANT* pvarMsg,
|
||
|
IN VARIANT* pvarUrl,
|
||
|
IN VARIANT* pvarLine,
|
||
|
OUT VARIANT_BOOL* pfResult)
|
||
|
{
|
||
|
BSTR bstrMsg, bstrUrl;
|
||
|
int iLine;
|
||
|
|
||
|
*pfResult = Bool2VarBool(FALSE);
|
||
|
|
||
|
if (pvarMsg == NULL || V_VT(pvarMsg) != VT_BSTR)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
bstrMsg = V_BSTR(pvarMsg);
|
||
|
|
||
|
if (pvarUrl == NULL || V_VT(pvarUrl) != VT_BSTR)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
bstrUrl = V_BSTR(pvarUrl);
|
||
|
|
||
|
if (pvarLine == NULL || V_VT(pvarLine) != VT_I4)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
iLine = V_I4(pvarLine);
|
||
|
|
||
|
TRACE3(L"%s: %s: Line %d", bstrMsg, bstrUrl, iLine);
|
||
|
|
||
|
#ifdef PRERELEASE
|
||
|
WCHAR wsz[MAX_PATH];
|
||
|
|
||
|
wsprintf(wsz, L"%s\nLine %d\nPlease notify OOBEDEV.", bstrUrl, iLine);
|
||
|
MessageBox(NULL, wsz, bstrMsg, MB_ICONERROR | MB_OK | MB_DEFAULT_DESKTOP_ONLY | MB_SETFOREGROUND);
|
||
|
#endif
|
||
|
|
||
|
*pfResult = Bool2VarBool(TRUE);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// get_WebBrowserDoc
|
||
|
HRESULT CObWebBrowser::get_WebBrowserDoc(IDispatch** ppDisp)
|
||
|
{
|
||
|
m_lpWebBrowser->get_Document(ppDisp);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// ListenToWebBrowserEvents
|
||
|
HRESULT CObWebBrowser::ListenToWebBrowserEvents(IUnknown* pUnk)
|
||
|
{
|
||
|
//first things first
|
||
|
if (!pUnk)
|
||
|
return E_FAIL;
|
||
|
|
||
|
//Ok, everything looks OK, try to setup a connection point.
|
||
|
// Setup to get WebBrowserEvents
|
||
|
return ConnectToConnectionPoint(pUnk,
|
||
|
DIID_DWebBrowserEvents2,
|
||
|
TRUE,
|
||
|
(IUnknown*)m_lpWebBrowser,
|
||
|
&m_dwcpCookie,
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////
|
||
|
// StopListeningToWebBrowserEvents
|
||
|
HRESULT CObWebBrowser::StopListeningToWebBrowserEvents(IUnknown* pUnk)
|
||
|
{
|
||
|
//first things first
|
||
|
if (!pUnk)
|
||
|
return E_FAIL;
|
||
|
|
||
|
//Ok, everything looks OK, try to setup a connection point.
|
||
|
// Setup to get WebBrowserEvents
|
||
|
return ConnectToConnectionPoint(pUnk,
|
||
|
DIID_DWebBrowserEvents2,
|
||
|
FALSE,
|
||
|
(IUnknown*)m_lpWebBrowser,
|
||
|
&m_dwcpCookie,
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
HRESULT CObWebBrowser::SetExternalInterface(IUnknown* pUnk)
|
||
|
{
|
||
|
m_pOleSite->SetExternalInterface((IDispatch*)pUnk);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
////// Methods
|
||
|
//////
|
||
|
//////
|
||
|
//////
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
// CObWebBrowser::CloseOleObject
|
||
|
void CObWebBrowser::CloseOleObject (void)
|
||
|
{
|
||
|
if (m_lpOleObject)
|
||
|
{
|
||
|
if (m_fInPlaceActive)
|
||
|
{
|
||
|
LPOLEINPLACEOBJECT lpObject = NULL;
|
||
|
LPVIEWOBJECT lpViewObject = NULL;
|
||
|
|
||
|
m_lpOleObject->QueryInterface(IID_IOleInPlaceObject, (LPVOID*)&lpObject);
|
||
|
lpObject->UIDeactivate();
|
||
|
|
||
|
// don't need to worry about inside-out because the object
|
||
|
// is going away.
|
||
|
lpObject->InPlaceDeactivate();
|
||
|
lpObject->Release();
|
||
|
}
|
||
|
m_lpOleObject->Close(OLECLOSE_NOSAVE);
|
||
|
m_hMainWnd = NULL;
|
||
|
m_pOleSite->m_hWnd = NULL;;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
// CObWebBrowser::InitBrowserObject
|
||
|
void CObWebBrowser::InitBrowserObject()
|
||
|
{
|
||
|
// If we don't have a WebBrowser object to initialize, then bail
|
||
|
if (!m_lpWebBrowser)
|
||
|
return;
|
||
|
|
||
|
// Get An OleObject from the WebBrowser Interface
|
||
|
if(SUCCEEDED(m_lpWebBrowser->QueryInterface(IID_IOleObject, (LPVOID*)&m_lpOleObject)) && m_lpOleObject)
|
||
|
{
|
||
|
m_pOleSite->m_lpOleObject = m_lpOleObject;
|
||
|
// inform object handler/DLL object that it is used in the embedding container's context
|
||
|
OleSetContainedObject(m_lpOleObject, TRUE);
|
||
|
|
||
|
// setup the client setup
|
||
|
m_lpOleObject->SetClientSite(m_pOleSite->m_pOleClientSite);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
// CObWebBrowser::InPlaceActivate
|
||
|
void CObWebBrowser::InPlaceActivate()
|
||
|
{
|
||
|
RECT rect;
|
||
|
|
||
|
m_lpOleObject->DoVerb( OLEIVERB_INPLACEACTIVATE,
|
||
|
NULL,
|
||
|
m_pOleSite->m_pOleClientSite,
|
||
|
-1,
|
||
|
m_hMainWnd,
|
||
|
&rect);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
// CObWebBrowser::UIActivate
|
||
|
void CObWebBrowser::UIActivate()
|
||
|
{
|
||
|
RECT rect;
|
||
|
|
||
|
m_lpOleObject->DoVerb( OLEIVERB_UIACTIVATE,
|
||
|
NULL,
|
||
|
m_pOleSite->m_pOleClientSite,
|
||
|
-1,
|
||
|
m_hMainWnd,
|
||
|
&rect);
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////
|
||
|
// CObWebBrowser::ShowWindow
|
||
|
HRESULT CObWebBrowser::ObWebShowWindow()
|
||
|
{
|
||
|
RECT rect;
|
||
|
|
||
|
m_lpOleObject->DoVerb( OLEIVERB_SHOW,
|
||
|
NULL,
|
||
|
m_pOleSite->m_pOleClientSite,
|
||
|
-1,
|
||
|
m_hMainWnd,
|
||
|
&rect);
|
||
|
|
||
|
|
||
|
//InPlaceActivate();
|
||
|
//UIActivate();
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CObWebBrowser::ConnectToConnectionPoint(IUnknown* punkThis,
|
||
|
REFIID riidEvent,
|
||
|
BOOL fConnect,
|
||
|
IUnknown* punkTarget,
|
||
|
DWORD* pdwCookie,
|
||
|
IConnectionPoint** ppcpOut)
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
IConnectionPointContainer* pcpContainer = NULL;
|
||
|
|
||
|
// We always need punkTarget, we only need punkThis on connect
|
||
|
if (!punkTarget || (fConnect && !punkThis))
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
if (ppcpOut)
|
||
|
*ppcpOut = NULL;
|
||
|
|
||
|
if (SUCCEEDED(hr = punkTarget->QueryInterface(IID_IConnectionPointContainer, (void **)&pcpContainer)))
|
||
|
{
|
||
|
IConnectionPoint *pcp;
|
||
|
if(SUCCEEDED(hr = pcpContainer->FindConnectionPoint(riidEvent, &pcp)))
|
||
|
{
|
||
|
if(fConnect)
|
||
|
{
|
||
|
// Add us to the list of people interested...
|
||
|
hr = pcp->Advise(punkThis, pdwCookie);
|
||
|
if (FAILED(hr))
|
||
|
*pdwCookie = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Remove us from the list of people interested...
|
||
|
hr = pcp->Unadvise(*pdwCookie);
|
||
|
*pdwCookie = 0;
|
||
|
}
|
||
|
|
||
|
if (ppcpOut && SUCCEEDED(hr))
|
||
|
*ppcpOut = pcp;
|
||
|
else
|
||
|
pcp->Release();
|
||
|
pcp = NULL;
|
||
|
}
|
||
|
pcpContainer->Release();
|
||
|
pcpContainer = NULL;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|