1294 lines
37 KiB
C++
1294 lines
37 KiB
C++
|
#include "shellprv.h"
|
||
|
#include "mshtml.h"
|
||
|
#include "mshtmhst.h"
|
||
|
#include "mshtmdid.h"
|
||
|
#include "htiframe.h"
|
||
|
#include "exdisp.h"
|
||
|
#include "exdispid.h"
|
||
|
#include "dspsprt.h"
|
||
|
#include "cowsite.h"
|
||
|
#include "ids.h"
|
||
|
#include "inetsmgr.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
|
||
|
// helper functions
|
||
|
|
||
|
typedef BOOL (*pfnDllRegisterWindowClasses)(const SHDRC * pshdrc);
|
||
|
|
||
|
BOOL SHDOCVW_DllRegisterWindowClasses(const SHDRC * pshdrc)
|
||
|
{
|
||
|
static HINSTANCE _hinstShdocvw = NULL;
|
||
|
static pfnDllRegisterWindowClasses _regfunc = NULL;
|
||
|
|
||
|
BOOL fSuccess = FALSE;
|
||
|
|
||
|
if (!_hinstShdocvw)
|
||
|
{
|
||
|
_hinstShdocvw = LoadLibrary(TEXT("shdocvw.dll"));
|
||
|
_regfunc = (pfnDllRegisterWindowClasses) GetProcAddress(_hinstShdocvw, "DllRegisterWindowClasses");
|
||
|
}
|
||
|
|
||
|
if (_regfunc)
|
||
|
fSuccess = _regfunc(pshdrc);
|
||
|
|
||
|
return fSuccess;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Advise point for DIID_DWebBrowserEvents2
|
||
|
// Just an IDispatch implementation that delegates back to the main class. Allows us to have a separate "Invoke".
|
||
|
|
||
|
class CWebWizardPage;
|
||
|
|
||
|
class CWebEventHandler : public IServiceProvider, DWebBrowserEvents2
|
||
|
{
|
||
|
public:
|
||
|
CWebEventHandler(CWebWizardPage *pswp);
|
||
|
~CWebEventHandler(); // TODO: Make this virtual or it will never execute.
|
||
|
|
||
|
// IUnknown
|
||
|
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
|
||
|
STDMETHODIMP_(ULONG) AddRef() {return 2;}
|
||
|
STDMETHODIMP_(ULONG) Release() {return 1;}
|
||
|
|
||
|
// (DwebBrowserEvents)IDispatch
|
||
|
STDMETHODIMP GetTypeInfoCount(/* [out] */ UINT *pctinfo) { return E_NOTIMPL; }
|
||
|
STDMETHODIMP GetTypeInfo(
|
||
|
/* [in] */ UINT iTInfo,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [out] */ ITypeInfo **ppTInfo)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP GetIDsOfNames(
|
||
|
/* [in] */ REFIID riid,
|
||
|
/* [size_is][in] */ LPOLESTR *rgszNames,
|
||
|
/* [in] */ UINT cNames,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [size_is][out] */ DISPID *rgDispId)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
/* [local] */ STDMETHODIMP Invoke(
|
||
|
/* [in] */ DISPID dispIdMember,
|
||
|
/* [in] */ REFIID riid,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [in] */ WORD wFlags,
|
||
|
/* [out][in] */ DISPPARAMS *pDispParams,
|
||
|
/* [out] */ VARIANT *pVarResult,
|
||
|
/* [out] */ EXCEPINFO *pExcepInfo,
|
||
|
/* [out] */ UINT *puArgErr);
|
||
|
|
||
|
HRESULT _Advise(BOOL fConnect);
|
||
|
|
||
|
// IServiceProvider
|
||
|
STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppv);
|
||
|
|
||
|
private:
|
||
|
CWebWizardPage* _pwizPage;
|
||
|
DWORD _dwCPCookie;
|
||
|
IConnectionPoint* _pcpCurrentConnection;
|
||
|
};
|
||
|
|
||
|
#define SHOW_PROGRESS_TIMER 1
|
||
|
#define SHOW_PROGRESS_TIMEOUT 1000 // Start showing the progress indicator after 1 second of dead time.
|
||
|
|
||
|
class CWebWizardPage : public CImpIDispatch,
|
||
|
CObjectWithSite,
|
||
|
IDocHostUIHandler,
|
||
|
IServiceProvider,
|
||
|
IWebWizardExtension,
|
||
|
INewWDEvents
|
||
|
{
|
||
|
public:
|
||
|
CWebWizardPage();
|
||
|
~CWebWizardPage();
|
||
|
|
||
|
// IUnknown
|
||
|
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
|
||
|
STDMETHODIMP_(ULONG) AddRef();
|
||
|
STDMETHODIMP_(ULONG) Release();
|
||
|
|
||
|
// IDocHostUIHandler
|
||
|
STDMETHODIMP ShowContextMenu(
|
||
|
/* [in] */ DWORD dwID,
|
||
|
/* [in] */ POINT *ppt,
|
||
|
/* [in] */ IUnknown *pcmdtReserved,
|
||
|
/* [in] */ IDispatch *pdispReserved)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP GetHostInfo(
|
||
|
/* [out][in] */ DOCHOSTUIINFO *pInfo);
|
||
|
|
||
|
STDMETHODIMP ShowUI(
|
||
|
/* [in] */ DWORD dwID,
|
||
|
/* [in] */ IOleInPlaceActiveObject *pActiveObject,
|
||
|
/* [in] */ IOleCommandTarget *pCommandTarget,
|
||
|
/* [in] */ IOleInPlaceFrame *pFrame,
|
||
|
/* [in] */ IOleInPlaceUIWindow *pDoc)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP HideUI(void)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP UpdateUI(void)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP EnableModeless(
|
||
|
/* [in] */ BOOL fEnable)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP OnDocWindowActivate(
|
||
|
/* [in] */ BOOL fActivate)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP OnFrameWindowActivate(
|
||
|
/* [in] */ BOOL fActivate)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP ResizeBorder(
|
||
|
/* [in] */ LPCRECT prcBorder,
|
||
|
/* [in] */ IOleInPlaceUIWindow *pUIWindow,
|
||
|
/* [in] */ BOOL fRameWindow)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP TranslateAccelerator(
|
||
|
/* [in] */ LPMSG lpMsg,
|
||
|
/* [in] */ const GUID *pguidCmdGroup,
|
||
|
/* [in] */ DWORD nCmdID)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP GetOptionKeyPath(
|
||
|
/* [out] */ LPOLESTR *pchKey,
|
||
|
/* [in] */ DWORD dw)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP GetDropTarget(
|
||
|
/* [in] */ IDropTarget *pDropTarget,
|
||
|
/* [out] */ IDropTarget **ppDropTarget)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP GetExternal(
|
||
|
/* [out] */ IDispatch **ppDispatch);
|
||
|
|
||
|
STDMETHODIMP TranslateUrl(
|
||
|
/* [in] */ DWORD dwTranslate,
|
||
|
/* [in] */ OLECHAR *pchURLIn,
|
||
|
/* [out] */ OLECHAR **ppchURLOut)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP FilterDataObject(
|
||
|
/* [in] */ IDataObject *pDO,
|
||
|
/* [out] */ IDataObject **ppDORet)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
// IServiceProvider
|
||
|
STDMETHODIMP QueryService(
|
||
|
/*[in]*/ REFGUID guidService,
|
||
|
/*[in]*/ REFIID riid,
|
||
|
/*[out]*/ void **ppv);
|
||
|
|
||
|
// INewWDEvents
|
||
|
|
||
|
// (IDispatch)
|
||
|
STDMETHODIMP GetTypeInfoCount(
|
||
|
/* [out] */ UINT *pctinfo)
|
||
|
{ return E_NOTIMPL; }
|
||
|
|
||
|
STDMETHODIMP GetTypeInfo(
|
||
|
/* [in] */ UINT iTInfo,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [out] */ ITypeInfo **ppTInfo)
|
||
|
{
|
||
|
return CImpIDispatch::GetTypeInfo(iTInfo, lcid, ppTInfo);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP GetIDsOfNames(
|
||
|
/* [in] */ REFIID riid,
|
||
|
/* [size_is][in] */ LPOLESTR *rgszNames,
|
||
|
/* [in] */ UINT cNames,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [size_is][out] */ DISPID *rgDispId)
|
||
|
{
|
||
|
return CImpIDispatch::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP Invoke(
|
||
|
/* [in] */ DISPID dispIdMember,
|
||
|
/* [in] */ REFIID riid,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [in] */ WORD wFlags,
|
||
|
/* [out][in] */ DISPPARAMS *pDispParams,
|
||
|
/* [out] */ VARIANT *pVarResult,
|
||
|
/* [out] */ EXCEPINFO *pExcepInfo,
|
||
|
/* [out] */ UINT *puArgErr)
|
||
|
{
|
||
|
return CImpIDispatch::Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP FinalBack(void);
|
||
|
STDMETHODIMP FinalNext(void);
|
||
|
STDMETHODIMP Cancel(void);
|
||
|
|
||
|
STDMETHODIMP put_Caption(
|
||
|
/* [in] */ BSTR bstrCaption);
|
||
|
|
||
|
STDMETHODIMP get_Caption(
|
||
|
/* [retval][out] */ BSTR *pbstrCaption);
|
||
|
|
||
|
STDMETHODIMP put_Property(
|
||
|
/* [in] */ BSTR bstrPropertyName,
|
||
|
/* [in] */ VARIANT *pvProperty);
|
||
|
|
||
|
STDMETHODIMP get_Property(
|
||
|
/* [in] */ BSTR bstrPropertyName,
|
||
|
/* [retval][out] */ VARIANT *pvProperty);
|
||
|
|
||
|
STDMETHODIMP SetWizardButtons(
|
||
|
/* [in] */ VARIANT_BOOL vfEnableBack,
|
||
|
/* [in] */ VARIANT_BOOL vfEnableNext,
|
||
|
/* [in] */ VARIANT_BOOL vfLastPage);
|
||
|
|
||
|
STDMETHODIMP SetHeaderText(
|
||
|
/* [in] */ BSTR bstrHeaderTitle,
|
||
|
/* [in] */ BSTR bstrHeaderSubtitle);
|
||
|
|
||
|
STDMETHODIMP PassportAuthenticate(
|
||
|
/* [in] */ BSTR bstrSignInUrl,
|
||
|
/* [retval][out] */ VARIANT_BOOL * pvfAuthenticated);
|
||
|
|
||
|
// IWizardExtension
|
||
|
STDMETHODIMP AddPages(HPROPSHEETPAGE* aPages, UINT cPages, UINT *pnPages);
|
||
|
STDMETHODIMP GetFirstPage(HPROPSHEETPAGE *phPage);
|
||
|
STDMETHODIMP GetLastPage(HPROPSHEETPAGE *phPage)
|
||
|
{ return GetFirstPage(phPage); }
|
||
|
|
||
|
// IWebWizardExtension
|
||
|
STDMETHODIMP SetInitialURL(LPCWSTR pszDefaultURL);
|
||
|
STDMETHODIMP SetErrorURL(LPCWSTR pszErrorURL);
|
||
|
|
||
|
protected:
|
||
|
friend class CWebEventHandler;
|
||
|
void _OnDownloadBegin();
|
||
|
void _OnDocumentComplete();
|
||
|
|
||
|
private:
|
||
|
void _InitBrowser();
|
||
|
HRESULT _NavigateBrowser(LPCWSTR pszUrl);
|
||
|
HRESULT _CallScript(IWebBrowser2* pbrowser, LPCWSTR pszFunction);
|
||
|
BOOL _IsScriptFunctionOnPage(IWebBrowser2* pbrowser, LPCWSTR pszFunction);
|
||
|
BOOL _IsBrowserVisible();
|
||
|
void _ShowBrowser(BOOL fShow);
|
||
|
void _SizeProgress();
|
||
|
void _ShowProgress(BOOL fShow);
|
||
|
void _StartShowProgressTimer();
|
||
|
void _SetHeaderText(LPCWSTR pszHeader, LPCWSTR pszSubHeader);
|
||
|
|
||
|
virtual INT_PTR DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
static INT_PTR StaticProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
static UINT PropPageProc(HWND hwndDlg, UINT uMsg, PROPSHEETPAGE *ppsp);
|
||
|
|
||
|
BOOL OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam);
|
||
|
BOOL OnDestroy(HWND hwnd);
|
||
|
BOOL OnNotify(HWND hwnd, int idCtrl, LPNMHDR pnmh);
|
||
|
BOOL OnTimer(HWND hwnd, UINT nIDEvent);
|
||
|
|
||
|
LONG _cRef;
|
||
|
CWebEventHandler *_pwebEventHandler;
|
||
|
IWebBrowser2 *_pwebbrowser;
|
||
|
IOleInPlaceActiveObject *_poipao;
|
||
|
HWND _hwndOCHost; // Web browser control window
|
||
|
HWND _hwndFrame; // Wizard frame window
|
||
|
HWND _hwnd; // Dialog window
|
||
|
HPROPSHEETPAGE _hPage;
|
||
|
|
||
|
LPWSTR _pszInitialURL;
|
||
|
LPWSTR _pszErrorURL;
|
||
|
};
|
||
|
|
||
|
|
||
|
INT_PTR CWebWizardPage::StaticProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
CWebWizardPage* pthis = (CWebWizardPage*) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||
|
PROPSHEETPAGE* ppage;
|
||
|
INT_PTR fProcessed;
|
||
|
|
||
|
if (uMsg == WM_INITDIALOG)
|
||
|
{
|
||
|
ppage = (PROPSHEETPAGE*) lParam;
|
||
|
pthis = (CWebWizardPage*) ppage->lParam;
|
||
|
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pthis);
|
||
|
}
|
||
|
|
||
|
if (pthis != NULL)
|
||
|
{
|
||
|
fProcessed = pthis->DialogProc(hwndDlg, uMsg, wParam, lParam);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fProcessed = FALSE;
|
||
|
}
|
||
|
|
||
|
return fProcessed;
|
||
|
}
|
||
|
|
||
|
|
||
|
// construction and IUnknown
|
||
|
|
||
|
CWebEventHandler::CWebEventHandler(CWebWizardPage *pwswp) :
|
||
|
_pcpCurrentConnection(NULL),
|
||
|
_pwizPage(pwswp)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CWebEventHandler::~CWebEventHandler()
|
||
|
{
|
||
|
_Advise(FALSE);
|
||
|
}
|
||
|
|
||
|
HRESULT CWebEventHandler::QueryInterface(REFIID riid, void **ppv)
|
||
|
{
|
||
|
static const QITAB qit[] = {
|
||
|
QITABENTMULTI(CWebEventHandler, IDispatch, DWebBrowserEvents2),
|
||
|
QITABENTMULTI2(CWebEventHandler, DIID_DWebBrowserEvents2, DWebBrowserEvents2),
|
||
|
// QITABENTMULTI2(CWebEventHandler, DIID_DWebBrowserEvents, DWebBrowserEvents),
|
||
|
QITABENT(CWebEventHandler, IServiceProvider),
|
||
|
{ 0 },
|
||
|
};
|
||
|
return QISearch(this, qit, riid, ppv);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CWebEventHandler::QueryService(REFGUID guidService, REFIID riid, void **ppv)
|
||
|
{
|
||
|
HRESULT hr = E_NOINTERFACE;
|
||
|
*ppv = NULL; // no result yet
|
||
|
|
||
|
// we are a site for the OleControlSite interfaces only
|
||
|
if (guidService == SID_OleControlSite)
|
||
|
{
|
||
|
if (riid == IID_IDispatch)
|
||
|
{
|
||
|
hr = this->QueryInterface(riid, ppv);
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebEventHandler_CreateInstance(CWebWizardPage *pwswp, CWebEventHandler **ppweh)
|
||
|
{
|
||
|
*ppweh = new CWebEventHandler(pwswp);
|
||
|
if (!*ppweh)
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebEventHandler::_Advise(BOOL fConnect)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
// If we're already connected, disconnect, since we either want to disconnect or reconnect to
|
||
|
// a different webbrowser.
|
||
|
if (_pcpCurrentConnection)
|
||
|
{
|
||
|
hr = _pcpCurrentConnection->Unadvise(_dwCPCookie);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
ATOMICRELEASE(_pcpCurrentConnection);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// We expect that if _pcpCurrentConnection is NULL, no code earlier would have changed hr, and that it is still S_OK
|
||
|
// The code below expects that if !SUCCEEDED(hr), Unadvise failed above.
|
||
|
ASSERT(SUCCEEDED(hr));
|
||
|
}
|
||
|
|
||
|
if (_pwizPage && _pwizPage->_pwebbrowser)
|
||
|
{
|
||
|
if (SUCCEEDED(hr) && fConnect)
|
||
|
{
|
||
|
IConnectionPointContainer* pcontainer;
|
||
|
hr = _pwizPage->_pwebbrowser->QueryInterface(IID_PPV_ARG(IConnectionPointContainer, &pcontainer));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
IConnectionPoint* pconnpoint;
|
||
|
hr = pcontainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &pconnpoint);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
IDispatch* pDisp;
|
||
|
hr = QueryInterface(IID_PPV_ARG(IDispatch, &pDisp));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = pconnpoint->Advise(pDisp, &_dwCPCookie);
|
||
|
pDisp->Release();
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// TODO: Enable ATOMICRELEASE() to verify we won't leak anything
|
||
|
// ATOMICRELEASE(_pcpCurrentConnection);
|
||
|
_pcpCurrentConnection = pconnpoint;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pconnpoint->Release();
|
||
|
}
|
||
|
}
|
||
|
pcontainer->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebEventHandler::Invoke(
|
||
|
/* [in] */ DISPID dispIdMember,
|
||
|
/* [in] */ REFIID riid,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [in] */ WORD wFlags,
|
||
|
/* [out][in] */ DISPPARAMS *pDispParams,
|
||
|
/* [out] */ VARIANT *pVarResult,
|
||
|
/* [out] */ EXCEPINFO *pExcepInfo,
|
||
|
/* [out] */ UINT *puArgErr)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
switch (dispIdMember)
|
||
|
{
|
||
|
case DISPID_BEFORENAVIGATE2:
|
||
|
_pwizPage->_OnDownloadBegin();
|
||
|
break;
|
||
|
|
||
|
case DISPID_DOCUMENTCOMPLETE:
|
||
|
_pwizPage->_OnDocumentComplete();
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
hr = DISP_E_MEMBERNOTFOUND;
|
||
|
break;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// Object for hosting HTML wizard pages
|
||
|
|
||
|
CWebWizardPage::CWebWizardPage() :
|
||
|
CImpIDispatch(LIBID_Shell32, 0, 0, IID_INewWDEvents),
|
||
|
_cRef(1)
|
||
|
{
|
||
|
// Ensure zero-init happened
|
||
|
ASSERT(NULL == _pwebbrowser);
|
||
|
ASSERT(NULL == _pwebEventHandler);
|
||
|
ASSERT(NULL == _pszInitialURL);
|
||
|
ASSERT(NULL == _pszErrorURL);
|
||
|
}
|
||
|
|
||
|
CWebWizardPage::~CWebWizardPage()
|
||
|
{
|
||
|
ATOMICRELEASE(_pwebbrowser);
|
||
|
ATOMICRELEASE(_pwebEventHandler);
|
||
|
ATOMICRELEASE(_punkSite);
|
||
|
ATOMICRELEASE(_poipao);
|
||
|
|
||
|
Str_SetPtr(&_pszInitialURL, NULL);
|
||
|
Str_SetPtr(&_pszErrorURL, NULL);
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::QueryInterface(REFIID riid, void **ppv)
|
||
|
{
|
||
|
static const QITAB qit[] =
|
||
|
{
|
||
|
QITABENTMULTI(CWebWizardPage, IWizardExtension, IWebWizardExtension),
|
||
|
QITABENT(CWebWizardPage, IWebWizardExtension),
|
||
|
QITABENT(CWebWizardPage, IDocHostUIHandler),
|
||
|
QITABENT(CWebWizardPage, IServiceProvider),
|
||
|
QITABENT(CWebWizardPage, INewWDEvents),
|
||
|
QITABENT(CWebWizardPage, IDispatch),
|
||
|
QITABENT(CWebWizardPage, IWebWizardExtension),
|
||
|
QITABENT(CWebWizardPage, IObjectWithSite),
|
||
|
{ 0 },
|
||
|
};
|
||
|
return QISearch(this, qit, riid, ppv);
|
||
|
}
|
||
|
|
||
|
ULONG CWebWizardPage::AddRef()
|
||
|
{
|
||
|
return InterlockedIncrement(&_cRef);
|
||
|
}
|
||
|
|
||
|
ULONG CWebWizardPage::Release()
|
||
|
{
|
||
|
if (InterlockedDecrement(&_cRef))
|
||
|
return _cRef;
|
||
|
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CWebWizardPage::QueryService(REFGUID guidService, REFIID riid, void **ppv)
|
||
|
{
|
||
|
HRESULT hr = E_NOINTERFACE;
|
||
|
*ppv = NULL;
|
||
|
|
||
|
if (_punkSite)
|
||
|
hr = IUnknown_QueryService(_punkSite, guidService, riid, ppv);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CWebWizardPage::_OnDownloadBegin()
|
||
|
{
|
||
|
_ShowBrowser(FALSE);
|
||
|
_StartShowProgressTimer();
|
||
|
|
||
|
SetWizardButtons(VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE);
|
||
|
}
|
||
|
|
||
|
void CWebWizardPage::_OnDocumentComplete()
|
||
|
{
|
||
|
if (!_IsScriptFunctionOnPage(_pwebbrowser, L"OnBack"))
|
||
|
{
|
||
|
// This is an invalid page; navigate to our private error page
|
||
|
BSTR bstrOldUrl;
|
||
|
if (_pwebbrowser && SUCCEEDED(_pwebbrowser->get_LocationURL(&bstrOldUrl)))
|
||
|
{
|
||
|
#ifdef DEBUG
|
||
|
if (IDYES == ::MessageBox(_hwnd, L"A Web Service Error has occured.\n\nDo you want to load the HTML page anyway so you can debug it?\n\n(This only appears in debug builds)", bstrOldUrl, MB_ICONERROR | MB_YESNO))
|
||
|
{
|
||
|
_ShowBrowser(TRUE);
|
||
|
SysFreeString(bstrOldUrl);
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
BSTR bstrUrl = NULL;
|
||
|
BOOL fUsingCustomError = FALSE;
|
||
|
|
||
|
// If we have a custom error URL and we haven't already failed trying
|
||
|
// to navigate to this custom URL...
|
||
|
if ((NULL != _pszErrorURL) &&
|
||
|
(0 != StrCmpI(_pszErrorURL, bstrOldUrl)))
|
||
|
{
|
||
|
// then use the custom URL.
|
||
|
bstrUrl = SysAllocString(_pszErrorURL);
|
||
|
fUsingCustomError = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bstrUrl = SysAllocString(L"res://shell32.dll/WebServiceError.htm");
|
||
|
}
|
||
|
|
||
|
if (bstrUrl)
|
||
|
{
|
||
|
_pwebbrowser->Navigate(bstrUrl, NULL, NULL, NULL, NULL);
|
||
|
SysFreeString(bstrUrl);
|
||
|
|
||
|
// Custom error URL will provide its own header and subheader
|
||
|
if (!fUsingCustomError)
|
||
|
{
|
||
|
WCHAR szTitle[256];
|
||
|
LoadString(g_hinst, IDS_WEBDLG_ERRTITLE, szTitle, ARRAYSIZE(szTitle));
|
||
|
#ifdef DEBUG
|
||
|
_SetHeaderText(szTitle, bstrOldUrl);
|
||
|
#else
|
||
|
_SetHeaderText(szTitle, L"");
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
SysFreeString(bstrOldUrl);
|
||
|
}
|
||
|
// else out of memory - oops.
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_ShowBrowser(TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::GetHostInfo(DOCHOSTUIINFO *pInfo)
|
||
|
{
|
||
|
ZeroMemory(pInfo, sizeof(*pInfo));
|
||
|
pInfo->cbSize = sizeof(*pInfo);
|
||
|
pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
|
||
|
pInfo->dwFlags = DOCHOSTUIFLAG_DIALOG | DOCHOSTUIFLAG_NO3DBORDER |
|
||
|
DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE | DOCHOSTUIFLAG_THEME |
|
||
|
DOCHOSTUIFLAG_FLAT_SCROLLBAR;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::GetExternal(IDispatch** ppDispatch)
|
||
|
{
|
||
|
return QueryInterface(IID_PPV_ARG(IDispatch, ppDispatch));
|
||
|
}
|
||
|
|
||
|
INT_PTR CWebWizardPage::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
HANDLE_MSG(hwndDlg, WM_INITDIALOG, OnInitDialog);
|
||
|
HANDLE_MSG(hwndDlg, WM_DESTROY, OnDestroy);
|
||
|
HANDLE_MSG(hwndDlg, WM_NOTIFY, OnNotify);
|
||
|
HANDLE_MSG(hwndDlg, WM_TIMER, OnTimer);
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::_CallScript(IWebBrowser2* pbrowser, LPCWSTR pszFunction)
|
||
|
{
|
||
|
HRESULT hr = E_INVALIDARG;
|
||
|
|
||
|
if (pbrowser)
|
||
|
{
|
||
|
IDispatch* pdocDispatch;
|
||
|
|
||
|
hr = pbrowser->get_Document(&pdocDispatch);
|
||
|
if ((S_OK == hr) && pdocDispatch)
|
||
|
{
|
||
|
IHTMLDocument* pdoc;
|
||
|
hr = pdocDispatch->QueryInterface(IID_PPV_ARG(IHTMLDocument, &pdoc));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
IDispatch* pdispScript;
|
||
|
hr = pdoc->get_Script(&pdispScript);
|
||
|
if (S_OK == hr)
|
||
|
{
|
||
|
DISPID dispid;
|
||
|
hr = pdispScript->GetIDsOfNames(IID_NULL, const_cast<LPWSTR*>(&pszFunction), 1, LOCALE_SYSTEM_DEFAULT, &dispid);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
unsigned int uArgErr;
|
||
|
DISPPARAMS dispparams = {0};
|
||
|
hr = pdispScript->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, NULL, &uArgErr);
|
||
|
}
|
||
|
pdispScript->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
pdoc->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
pdocDispatch->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
BOOL CWebWizardPage::_IsScriptFunctionOnPage(IWebBrowser2* pbrowser, LPCWSTR pszFunction)
|
||
|
{
|
||
|
HRESULT hr = E_INVALIDARG;
|
||
|
|
||
|
if (pbrowser)
|
||
|
{
|
||
|
IDispatch* pdocDispatch;
|
||
|
|
||
|
hr = pbrowser->get_Document(&pdocDispatch);
|
||
|
if (S_OK == hr && pdocDispatch)
|
||
|
{
|
||
|
IHTMLDocument* pdoc;
|
||
|
hr = pdocDispatch->QueryInterface(IID_PPV_ARG(IHTMLDocument, &pdoc));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
IDispatch* pdispScript;
|
||
|
hr = pdoc->get_Script(&pdispScript);
|
||
|
if (S_OK == hr)
|
||
|
{
|
||
|
DISPID dispid;
|
||
|
hr = pdispScript->GetIDsOfNames(IID_NULL, const_cast<LPWSTR*>(&pszFunction), 1, LOCALE_SYSTEM_DEFAULT, &dispid);
|
||
|
pdispScript->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
pdoc->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
pdocDispatch->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (S_OK == hr) ? TRUE : FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Uncomment this to NOT pass the LCID on the URL query string - for testing only.
|
||
|
|
||
|
BOOL CWebWizardPage::OnNotify(HWND hwnd, int idCtrl, LPNMHDR pnmh)
|
||
|
{
|
||
|
switch (pnmh->code)
|
||
|
{
|
||
|
case PSN_SETACTIVE:
|
||
|
{
|
||
|
_SizeProgress();
|
||
|
_ShowProgress(FALSE);
|
||
|
_ShowBrowser(FALSE);
|
||
|
|
||
|
// fetch the high contrast flag, and set accordingly for the HTML to read
|
||
|
// its OK for us to fail setting this into the property bag.
|
||
|
|
||
|
HIGHCONTRAST hc = {sizeof(hc)};
|
||
|
if (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(hc), &hc, 0))
|
||
|
{
|
||
|
VARIANT var = {VT_BOOL};
|
||
|
var.boolVal = (hc.dwFlags & HCF_HIGHCONTRASTON) ? VARIANT_TRUE:VARIANT_FALSE;
|
||
|
put_Property(L"HighContrast", &var);
|
||
|
}
|
||
|
|
||
|
// Position the OCHost window
|
||
|
|
||
|
RECT rectClient;
|
||
|
GetClientRect(hwnd, &rectClient);
|
||
|
SetWindowPos(_hwndOCHost, NULL, 0, 0, rectClient.right, rectClient.bottom, SWP_NOMOVE | SWP_NOOWNERZORDER);
|
||
|
|
||
|
// set the initial URL
|
||
|
|
||
|
if (_pszInitialURL)
|
||
|
{
|
||
|
WCHAR szURLWithLCID[INTERNET_MAX_URL_LENGTH];
|
||
|
LPCWSTR pszFormat = StrChr(_pszInitialURL, L'?') ? L"%s&lcid=%d&langid=%d":L"%s?lcid=%d&langid=%d";
|
||
|
if (wnsprintf(szURLWithLCID, ARRAYSIZE(szURLWithLCID), pszFormat, _pszInitialURL, GetUserDefaultLCID(), GetUserDefaultUILanguage()) > 0)
|
||
|
{
|
||
|
_NavigateBrowser(szURLWithLCID);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
// WIZNEXT and WIZBACK don't actually cause a navigation to occur - they instead forward on the message to the
|
||
|
// hosted web page. Real wizard navigations occur when the hosted web page calls our FinalBack() and FinalNext() methods.
|
||
|
|
||
|
case PSN_WIZNEXT:
|
||
|
_CallScript(_pwebbrowser, L"OnNext");
|
||
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1);
|
||
|
return TRUE;
|
||
|
|
||
|
case PSN_WIZBACK:
|
||
|
_CallScript(_pwebbrowser, L"OnBack");
|
||
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1);
|
||
|
return TRUE;
|
||
|
|
||
|
// query cancel results in a call to the site to determine if we are going
|
||
|
// to cancel out and if the site wants to provide a page for us to navigate
|
||
|
// to - in some cases, eg. the web publishing wizard this is important
|
||
|
// so that we can cancel the order being processed etc.
|
||
|
|
||
|
case PSN_QUERYCANCEL:
|
||
|
if (_punkSite)
|
||
|
{
|
||
|
IWizardSite *pws;
|
||
|
if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IWizardSite, &pws))))
|
||
|
{
|
||
|
HPROPSHEETPAGE hpage;
|
||
|
if (S_OK == pws->GetCancelledPage(&hpage))
|
||
|
{
|
||
|
PropSheet_SetCurSel(GetParent(hwnd), hpage, -1);
|
||
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LPARAM)TRUE);
|
||
|
}
|
||
|
pws->Release();
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case PSN_TRANSLATEACCELERATOR:
|
||
|
{
|
||
|
LPPSHNOTIFY ppsn = (LPPSHNOTIFY)pnmh;
|
||
|
MSG *pmsg = (MSG *)ppsn->lParam;
|
||
|
LONG_PTR lres = PSNRET_NOERROR;
|
||
|
|
||
|
if (_poipao && S_OK == _poipao->TranslateAccelerator(pmsg))
|
||
|
{
|
||
|
lres = PSNRET_MESSAGEHANDLED;
|
||
|
}
|
||
|
|
||
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, lres);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CWebWizardPage::OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
|
||
|
{
|
||
|
_hwnd = hwnd;
|
||
|
_hwndFrame = GetParent(hwnd);
|
||
|
|
||
|
// lets remap some of the text in the dialog if we need to
|
||
|
|
||
|
IResourceMap *prm;
|
||
|
HRESULT hr = IUnknown_QueryService(_punkSite, SID_ResourceMap, IID_PPV_ARG(IResourceMap, &prm));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
IXMLDOMNode *pdn;
|
||
|
hr = prm->SelectResourceScope(TEXT("dialog"), TEXT("ws:downloading"), &pdn);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
TCHAR szBuffer[512];
|
||
|
if (SUCCEEDED(prm->LoadString(pdn, TEXT("header"), szBuffer, ARRAYSIZE(szBuffer))))
|
||
|
{
|
||
|
SetDlgItemText(hwnd, IDC_PROGTEXT1, szBuffer);
|
||
|
}
|
||
|
if (SUCCEEDED(prm->LoadString(pdn, TEXT("footer"), szBuffer, ARRAYSIZE(szBuffer))))
|
||
|
{
|
||
|
SetDlgItemText(hwnd, IDC_PROGTEXT2, szBuffer);
|
||
|
}
|
||
|
pdn->Release();
|
||
|
}
|
||
|
prm->Release();
|
||
|
}
|
||
|
|
||
|
// create the web view browser that we will show the providers HTML in
|
||
|
|
||
|
SHDRC shdrc = {0};
|
||
|
shdrc.cbSize = sizeof(shdrc);
|
||
|
shdrc.dwFlags = SHDRCF_OCHOST;
|
||
|
|
||
|
if (SHDOCVW_DllRegisterWindowClasses(&shdrc))
|
||
|
{
|
||
|
RECT rectClient;
|
||
|
GetClientRect(hwnd, &rectClient);
|
||
|
|
||
|
_hwndOCHost = CreateWindow(OCHOST_CLASS, NULL,
|
||
|
WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_TABSTOP,
|
||
|
0, 0, rectClient.right, rectClient.bottom,
|
||
|
hwnd, NULL, g_hinst, NULL);
|
||
|
if (_hwndOCHost)
|
||
|
{
|
||
|
OCHINITSTRUCT ocs = {0};
|
||
|
ocs.cbSize = sizeof(ocs);
|
||
|
ocs.clsidOC = CLSID_WebBrowser;
|
||
|
ocs.punkOwner = SAFECAST(this, IDocHostUIHandler*);
|
||
|
|
||
|
hr = OCHost_InitOC(_hwndOCHost, (LPARAM)&ocs);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
_InitBrowser();
|
||
|
|
||
|
OCHost_DoVerb(_hwndOCHost, OLEIVERB_INPLACEACTIVATE, TRUE);
|
||
|
ShowWindow(_hwndOCHost, TRUE);
|
||
|
|
||
|
IServiceProvider* pSP;
|
||
|
hr = _pwebEventHandler->QueryInterface(IID_PPV_ARG(IServiceProvider, &pSP));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
OCHost_SetServiceProvider(_hwndOCHost, pSP);
|
||
|
pSP->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
EndDialog(hwnd, IDCANCEL);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CWebWizardPage::OnTimer(HWND hwnd, UINT nIDEvent)
|
||
|
{
|
||
|
if (nIDEvent == SHOW_PROGRESS_TIMER)
|
||
|
{
|
||
|
_ShowProgress(TRUE);
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CWebWizardPage::OnDestroy(HWND hwnd)
|
||
|
{
|
||
|
ATOMICRELEASE(_pwebbrowser);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void CWebWizardPage::_InitBrowser(void)
|
||
|
{
|
||
|
ASSERT(IsWindow(_hwndOCHost));
|
||
|
ASSERT(!_pwebbrowser);
|
||
|
|
||
|
HRESULT hr = OCHost_QueryInterface(_hwndOCHost, IID_PPV_ARG(IWebBrowser2, &_pwebbrowser));
|
||
|
if (SUCCEEDED(hr) && _pwebbrowser)
|
||
|
{
|
||
|
ITargetFrame2* ptgf;
|
||
|
if (SUCCEEDED(_pwebbrowser->QueryInterface(IID_PPV_ARG(ITargetFrame2, &ptgf))))
|
||
|
{
|
||
|
DWORD dwOptions;
|
||
|
if (SUCCEEDED(ptgf->GetFrameOptions(&dwOptions)))
|
||
|
{
|
||
|
dwOptions |= FRAMEOPTIONS_BROWSERBAND | FRAMEOPTIONS_SCROLL_AUTO;
|
||
|
ptgf->SetFrameOptions(dwOptions);
|
||
|
}
|
||
|
ptgf->Release();
|
||
|
}
|
||
|
|
||
|
_pwebbrowser->put_RegisterAsDropTarget(VARIANT_FALSE);
|
||
|
|
||
|
// Set up the connection point (including creating the object
|
||
|
|
||
|
if (!_pwebEventHandler)
|
||
|
CWebEventHandler_CreateInstance(this, &_pwebEventHandler);
|
||
|
|
||
|
if (_pwebEventHandler)
|
||
|
_pwebEventHandler->_Advise(TRUE);
|
||
|
|
||
|
OCHost_QueryInterface(_hwndOCHost, IID_PPV_ARG(IOleInPlaceActiveObject, &_poipao));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::_NavigateBrowser(LPCWSTR pszUrl)
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
|
||
|
if (_hwndOCHost && _pwebbrowser)
|
||
|
{
|
||
|
BSTR bstrUrl = SysAllocString(pszUrl);
|
||
|
if (bstrUrl)
|
||
|
{
|
||
|
hr = _pwebbrowser->Navigate(bstrUrl, NULL, NULL, NULL, NULL);
|
||
|
SysFreeString(bstrUrl);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::FinalBack(void)
|
||
|
{
|
||
|
if (_punkSite)
|
||
|
{
|
||
|
IWizardSite *pws;
|
||
|
if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IWizardSite, &pws))))
|
||
|
{
|
||
|
HPROPSHEETPAGE hpage;
|
||
|
HRESULT hr = pws->GetPreviousPage(&hpage);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
PropSheet_SetCurSel(_hwndFrame, hpage, -1);
|
||
|
}
|
||
|
pws->Release();
|
||
|
}
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::FinalNext(void)
|
||
|
{
|
||
|
if (_punkSite)
|
||
|
{
|
||
|
IWizardSite *pws;
|
||
|
if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IWizardSite, &pws))))
|
||
|
{
|
||
|
HPROPSHEETPAGE hpage;
|
||
|
HRESULT hr = pws->GetNextPage(&hpage);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
PropSheet_SetCurSel(_hwndFrame, hpage, -1);
|
||
|
}
|
||
|
pws->Release();
|
||
|
}
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::Cancel(void)
|
||
|
{
|
||
|
PropSheet_PressButton(_hwndFrame, PSBTN_CANCEL); // simulate cancel...
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::put_Caption(
|
||
|
/* [in] */ BSTR bstrCaption)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::get_Caption(
|
||
|
/* [retval][out] */ BSTR *pbstrCaption)
|
||
|
{
|
||
|
WCHAR szCaption[MAX_PATH];
|
||
|
|
||
|
GetWindowText(_hwndFrame, szCaption, ARRAYSIZE(szCaption));
|
||
|
*pbstrCaption = SysAllocString(szCaption);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
// fetch and put properties into the frames property bag. this we do
|
||
|
// by a QueryService call and then we can modify the properties accordingly.
|
||
|
|
||
|
HRESULT CWebWizardPage::put_Property(
|
||
|
/* [in] */ BSTR bstrPropertyName,
|
||
|
/* [in] */ VARIANT *pvProperty)
|
||
|
{
|
||
|
IPropertyBag *ppb;
|
||
|
HRESULT hr = IUnknown_QueryService(_punkSite, SID_WebWizardHost, IID_PPV_ARG(IPropertyBag, &ppb));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = ppb->Write(bstrPropertyName, pvProperty);
|
||
|
ppb->Release();
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::get_Property(
|
||
|
/* [in] */ BSTR bstrPropertyName,
|
||
|
/* [retval][out] */ VARIANT *pvProperty)
|
||
|
{
|
||
|
IPropertyBag *ppb;
|
||
|
HRESULT hr = IUnknown_QueryService(_punkSite, SID_WebWizardHost, IID_PPV_ARG(IPropertyBag, &ppb));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = ppb->Read(bstrPropertyName, pvProperty, NULL);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
// Return a NULL-variant
|
||
|
VariantInit(pvProperty);
|
||
|
pvProperty->vt = VT_NULL;
|
||
|
hr = S_FALSE;
|
||
|
}
|
||
|
|
||
|
ppb->Release();
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::SetWizardButtons(
|
||
|
/* [in] */ VARIANT_BOOL vfEnableBack,
|
||
|
/* [in] */ VARIANT_BOOL vfEnableNext,
|
||
|
/* [in] */ VARIANT_BOOL vfLastPage)
|
||
|
{
|
||
|
// We ignore vfLastPage because it isn't the last page for us!
|
||
|
DWORD dwButtons = 0;
|
||
|
|
||
|
if (vfEnableBack)
|
||
|
dwButtons |= PSWIZB_BACK;
|
||
|
|
||
|
if (vfEnableNext)
|
||
|
dwButtons |= PSWIZB_NEXT;
|
||
|
|
||
|
PropSheet_SetWizButtons(_hwndFrame, dwButtons);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
void CWebWizardPage::_SetHeaderText(LPCWSTR pszHeader, LPCWSTR pszSubHeader)
|
||
|
{
|
||
|
int iPageNumber = PropSheet_HwndToIndex(_hwndFrame, _hwnd);
|
||
|
if (-1 != iPageNumber)
|
||
|
{
|
||
|
PropSheet_SetHeaderTitle(_hwndFrame, iPageNumber, pszHeader);
|
||
|
PropSheet_SetHeaderSubTitle(_hwndFrame, iPageNumber, pszSubHeader);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::SetHeaderText(
|
||
|
/* [in] */ BSTR bstrHeaderTitle,
|
||
|
/* [in] */ BSTR bstrHeaderSubtitle)
|
||
|
{
|
||
|
_SetHeaderText(bstrHeaderTitle, bstrHeaderSubtitle);
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::PassportAuthenticate(
|
||
|
/* [in] */ BSTR bstrURL,
|
||
|
/* [retval][out] */ VARIANT_BOOL * pfAuthenticated)
|
||
|
{
|
||
|
*pfAuthenticated = VARIANT_FALSE; // the user isn't authenticated.
|
||
|
|
||
|
IXMLHttpRequest *preq;
|
||
|
HRESULT hr = CoCreateInstance(CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IXMLHttpRequest, &preq));
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
VARIANT varNULL = {0};
|
||
|
VARIANT varAsync = {VT_BOOL};
|
||
|
varAsync.boolVal = VARIANT_FALSE;
|
||
|
|
||
|
// open a post request to the destination that we have
|
||
|
hr = preq->open(L"GET", bstrURL, varAsync, varNULL, varNULL);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
VARIANT varBody = {0};
|
||
|
hr = preq->send(varBody);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
long lStatus;
|
||
|
hr = preq->get_status(&lStatus);
|
||
|
if (SUCCEEDED(hr) && (lStatus == HTTP_STATUS_OK))
|
||
|
{
|
||
|
*pfAuthenticated = VARIANT_TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
BOOL CWebWizardPage::_IsBrowserVisible()
|
||
|
{
|
||
|
return IsWindowVisible(_hwndOCHost);
|
||
|
}
|
||
|
|
||
|
void CWebWizardPage::_ShowBrowser(BOOL fShow)
|
||
|
{
|
||
|
ShowWindow(_hwndOCHost, fShow ? SW_SHOW : SW_HIDE);
|
||
|
|
||
|
if (fShow)
|
||
|
{
|
||
|
// Can't have these windows overlapping.
|
||
|
_ShowProgress(FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CWebWizardPage::_StartShowProgressTimer()
|
||
|
{
|
||
|
_ShowProgress(FALSE);
|
||
|
|
||
|
if (!SetTimer(_hwnd, SHOW_PROGRESS_TIMER, SHOW_PROGRESS_TIMEOUT, NULL))
|
||
|
{
|
||
|
// Timer failed to set; show progress now;
|
||
|
_ShowProgress(TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Size the progress bar to fit the client area it is in.
|
||
|
void CWebWizardPage::_SizeProgress()
|
||
|
{
|
||
|
HWND hwndProgress = GetDlgItem(_hwnd, IDC_PROGRESS);
|
||
|
|
||
|
RECT rcPage;
|
||
|
GetClientRect(_hwnd, &rcPage);
|
||
|
RECT rcProgress;
|
||
|
GetClientRect(hwndProgress, &rcProgress);
|
||
|
MapWindowPoints(hwndProgress, _hwnd, (LPPOINT) &rcProgress, 2);
|
||
|
|
||
|
rcProgress.right = rcPage.right - rcProgress.left;
|
||
|
|
||
|
SetWindowPos(hwndProgress, NULL, 0, 0, rcProgress.right - rcProgress.left, rcProgress.bottom - rcProgress.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOREPOSITION);
|
||
|
}
|
||
|
|
||
|
void CWebWizardPage::_ShowProgress(BOOL fShow)
|
||
|
{
|
||
|
HWND hwndProgress = GetDlgItem(_hwnd, IDC_PROGRESS);
|
||
|
ShowWindow(hwndProgress, fShow ? SW_SHOW : SW_HIDE);
|
||
|
ShowWindow(GetDlgItem(_hwnd, IDC_PROGTEXT1), fShow ? SW_SHOW : SW_HIDE);
|
||
|
ShowWindow(GetDlgItem(_hwnd, IDC_PROGTEXT2), fShow ? SW_SHOW : SW_HIDE);
|
||
|
|
||
|
KillTimer(_hwnd, SHOW_PROGRESS_TIMER);
|
||
|
|
||
|
if (fShow)
|
||
|
{
|
||
|
SendMessage(hwndProgress, PBM_SETMARQUEE, (WPARAM) TRUE, 0);
|
||
|
|
||
|
// Set the header/subheader to a "Connecting to Internet" message.
|
||
|
WCHAR szTitle[256];
|
||
|
WCHAR szSubtitle[256];
|
||
|
LoadString(g_hinst, IDS_WEBDLG_TITLE, szTitle, ARRAYSIZE(szTitle));
|
||
|
LoadString(g_hinst, IDS_WEBDLG_SUBTITLE, szSubtitle, ARRAYSIZE(szSubtitle));
|
||
|
_SetHeaderText(szTitle, szSubtitle);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SendMessage(hwndProgress, PBM_SETMARQUEE, (WPARAM) FALSE, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// IWizardExtn
|
||
|
|
||
|
UINT CWebWizardPage::PropPageProc(HWND hwndDlg, UINT uMsg, PROPSHEETPAGE *ppsp)
|
||
|
{
|
||
|
CWebWizardPage *pwwp = (CWebWizardPage*)ppsp->lParam;
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case PSPCB_CREATE:
|
||
|
return TRUE;
|
||
|
|
||
|
// we need to release our site in this scenario, we know that we won't be using it
|
||
|
// anymore, and to ensure that clients down have a circular refernce to us we
|
||
|
// release it before they call us for our final destruction.
|
||
|
|
||
|
case PSPCB_RELEASE:
|
||
|
ATOMICRELEASE(pwwp->_punkSite);
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HRESULT CWebWizardPage::AddPages(HPROPSHEETPAGE* aPages, UINT cPages, UINT *pnPages)
|
||
|
{
|
||
|
PROPSHEETPAGE psp = { 0 };
|
||
|
psp.dwSize = sizeof(psp);
|
||
|
psp.hInstance = g_hinst;
|
||
|
psp.dwFlags = PSP_DEFAULT|PSP_USECALLBACK ;
|
||
|
psp.pszTemplate = MAKEINTRESOURCE(DLG_WEBWIZARD);
|
||
|
psp.lParam = (LPARAM) this;
|
||
|
psp.pfnDlgProc = CWebWizardPage::StaticProc;
|
||
|
psp.pfnCallback = PropPageProc;
|
||
|
|
||
|
_hPage = CreatePropertySheetPage(&psp);
|
||
|
if (!_hPage)
|
||
|
return E_FAIL;
|
||
|
|
||
|
// return the page we created.
|
||
|
|
||
|
*aPages = _hPage;
|
||
|
*pnPages = 1;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CWebWizardPage::GetFirstPage(HPROPSHEETPAGE *phPage)
|
||
|
{
|
||
|
*phPage = _hPage;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CWebWizardPage::SetInitialURL(LPCWSTR pszDefaultURL)
|
||
|
{
|
||
|
HRESULT hr = E_INVALIDARG;
|
||
|
if (pszDefaultURL)
|
||
|
{
|
||
|
hr = Str_SetPtr(&_pszInitialURL, pszDefaultURL) ? S_OK:E_OUTOFMEMORY;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CWebWizardPage::SetErrorURL(LPCWSTR pszErrorURL)
|
||
|
{
|
||
|
HRESULT hr = E_INVALIDARG;
|
||
|
if (pszErrorURL)
|
||
|
{
|
||
|
hr = Str_SetPtr(&_pszErrorURL, pszErrorURL) ? S_OK:E_OUTOFMEMORY;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDAPI CWebWizardPage_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void **ppv)
|
||
|
{
|
||
|
if (NULL != pUnkOuter)
|
||
|
{
|
||
|
return CLASS_E_NOAGGREGATION;
|
||
|
}
|
||
|
|
||
|
CWebWizardPage *pwwp = new CWebWizardPage();
|
||
|
if (!pwwp)
|
||
|
{
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
HRESULT hr = pwwp->QueryInterface(riid, ppv);
|
||
|
pwwp->Release();
|
||
|
return hr;
|
||
|
}
|