Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1300 lines
38 KiB

  1. #include "shellprv.h"
  2. #include "mshtml.h"
  3. #include "mshtmhst.h"
  4. #include "mshtmdid.h"
  5. #include "htiframe.h"
  6. #include "exdisp.h"
  7. #include "exdispid.h"
  8. #include "dspsprt.h"
  9. #include "cowsite.h"
  10. #include "ids.h"
  11. #include "inetsmgr.h"
  12. #pragma hdrstop
  13. // helper functions
  14. typedef BOOL (*pfnDllRegisterWindowClasses)(const SHDRC * pshdrc);
  15. BOOL SHDOCVW_DllRegisterWindowClasses(const SHDRC * pshdrc)
  16. {
  17. static HINSTANCE _hinstShdocvw = NULL;
  18. static pfnDllRegisterWindowClasses _regfunc = NULL;
  19. BOOL fSuccess = FALSE;
  20. if (!_hinstShdocvw)
  21. {
  22. _hinstShdocvw = LoadLibrary(TEXT("shdocvw.dll"));
  23. _regfunc = (pfnDllRegisterWindowClasses) GetProcAddress(_hinstShdocvw, "DllRegisterWindowClasses");
  24. }
  25. if (_regfunc)
  26. fSuccess = _regfunc(pshdrc);
  27. return fSuccess;
  28. }
  29. // Advise point for DIID_DWebBrowserEvents2
  30. // Just an IDispatch implementation that delegates back to the main class. Allows us to have a separate "Invoke".
  31. class CWebWizardPage;
  32. class CWebEventHandler : public IServiceProvider, DWebBrowserEvents2
  33. {
  34. public:
  35. CWebEventHandler(CWebWizardPage *pswp);
  36. ~CWebEventHandler(); // TODO: Make this virtual or it will never execute.
  37. // IUnknown
  38. STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
  39. STDMETHODIMP_(ULONG) AddRef() {return 2;}
  40. STDMETHODIMP_(ULONG) Release() {return 1;}
  41. // (DwebBrowserEvents)IDispatch
  42. STDMETHODIMP GetTypeInfoCount(/* [out] */ UINT *pctinfo) { return E_NOTIMPL; }
  43. STDMETHODIMP GetTypeInfo(
  44. /* [in] */ UINT iTInfo,
  45. /* [in] */ LCID lcid,
  46. /* [out] */ ITypeInfo **ppTInfo)
  47. { return E_NOTIMPL; }
  48. STDMETHODIMP GetIDsOfNames(
  49. /* [in] */ REFIID riid,
  50. /* [size_is][in] */ LPOLESTR *rgszNames,
  51. /* [in] */ UINT cNames,
  52. /* [in] */ LCID lcid,
  53. /* [size_is][out] */ DISPID *rgDispId)
  54. { return E_NOTIMPL; }
  55. /* [local] */ STDMETHODIMP Invoke(
  56. /* [in] */ DISPID dispIdMember,
  57. /* [in] */ REFIID riid,
  58. /* [in] */ LCID lcid,
  59. /* [in] */ WORD wFlags,
  60. /* [out][in] */ DISPPARAMS *pDispParams,
  61. /* [out] */ VARIANT *pVarResult,
  62. /* [out] */ EXCEPINFO *pExcepInfo,
  63. /* [out] */ UINT *puArgErr);
  64. HRESULT _Advise(BOOL fConnect);
  65. // IServiceProvider
  66. STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppv);
  67. private:
  68. CWebWizardPage* _pwizPage;
  69. DWORD _dwCPCookie;
  70. IConnectionPoint* _pcpCurrentConnection;
  71. };
  72. #define SHOW_PROGRESS_TIMER 1
  73. #define SHOW_PROGRESS_TIMEOUT 1000 // Start showing the progress indicator after 1 second of dead time.
  74. class CWebWizardPage : public CImpIDispatch,
  75. CObjectWithSite,
  76. IDocHostUIHandler,
  77. IServiceProvider,
  78. IWebWizardExtension,
  79. INewWDEvents
  80. {
  81. public:
  82. CWebWizardPage();
  83. ~CWebWizardPage();
  84. // IUnknown
  85. STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
  86. STDMETHODIMP_(ULONG) AddRef();
  87. STDMETHODIMP_(ULONG) Release();
  88. // IDocHostUIHandler
  89. STDMETHODIMP ShowContextMenu(
  90. /* [in] */ DWORD dwID,
  91. /* [in] */ POINT *ppt,
  92. /* [in] */ IUnknown *pcmdtReserved,
  93. /* [in] */ IDispatch *pdispReserved)
  94. { return E_NOTIMPL; }
  95. STDMETHODIMP GetHostInfo(
  96. /* [out][in] */ DOCHOSTUIINFO *pInfo);
  97. STDMETHODIMP ShowUI(
  98. /* [in] */ DWORD dwID,
  99. /* [in] */ IOleInPlaceActiveObject *pActiveObject,
  100. /* [in] */ IOleCommandTarget *pCommandTarget,
  101. /* [in] */ IOleInPlaceFrame *pFrame,
  102. /* [in] */ IOleInPlaceUIWindow *pDoc)
  103. { return E_NOTIMPL; }
  104. STDMETHODIMP HideUI(void)
  105. { return E_NOTIMPL; }
  106. STDMETHODIMP UpdateUI(void)
  107. { return E_NOTIMPL; }
  108. STDMETHODIMP EnableModeless(
  109. /* [in] */ BOOL fEnable)
  110. { return E_NOTIMPL; }
  111. STDMETHODIMP OnDocWindowActivate(
  112. /* [in] */ BOOL fActivate)
  113. { return E_NOTIMPL; }
  114. STDMETHODIMP OnFrameWindowActivate(
  115. /* [in] */ BOOL fActivate)
  116. { return E_NOTIMPL; }
  117. STDMETHODIMP ResizeBorder(
  118. /* [in] */ LPCRECT prcBorder,
  119. /* [in] */ IOleInPlaceUIWindow *pUIWindow,
  120. /* [in] */ BOOL fRameWindow)
  121. { return E_NOTIMPL; }
  122. STDMETHODIMP TranslateAccelerator(
  123. /* [in] */ LPMSG lpMsg,
  124. /* [in] */ const GUID *pguidCmdGroup,
  125. /* [in] */ DWORD nCmdID)
  126. { return E_NOTIMPL; }
  127. STDMETHODIMP GetOptionKeyPath(
  128. /* [out] */ LPOLESTR *pchKey,
  129. /* [in] */ DWORD dw)
  130. { return E_NOTIMPL; }
  131. STDMETHODIMP GetDropTarget(
  132. /* [in] */ IDropTarget *pDropTarget,
  133. /* [out] */ IDropTarget **ppDropTarget)
  134. { return E_NOTIMPL; }
  135. STDMETHODIMP GetExternal(
  136. /* [out] */ IDispatch **ppDispatch);
  137. STDMETHODIMP TranslateUrl(
  138. /* [in] */ DWORD dwTranslate,
  139. /* [in] */ OLECHAR *pchURLIn,
  140. /* [out] */ OLECHAR **ppchURLOut)
  141. { return E_NOTIMPL; }
  142. STDMETHODIMP FilterDataObject(
  143. /* [in] */ IDataObject *pDO,
  144. /* [out] */ IDataObject **ppDORet)
  145. { return E_NOTIMPL; }
  146. // IServiceProvider
  147. STDMETHODIMP QueryService(
  148. /*[in]*/ REFGUID guidService,
  149. /*[in]*/ REFIID riid,
  150. /*[out]*/ void **ppv);
  151. // INewWDEvents
  152. // (IDispatch)
  153. STDMETHODIMP GetTypeInfoCount(
  154. /* [out] */ UINT *pctinfo)
  155. { return E_NOTIMPL; }
  156. STDMETHODIMP GetTypeInfo(
  157. /* [in] */ UINT iTInfo,
  158. /* [in] */ LCID lcid,
  159. /* [out] */ ITypeInfo **ppTInfo)
  160. {
  161. return CImpIDispatch::GetTypeInfo(iTInfo, lcid, ppTInfo);
  162. }
  163. STDMETHODIMP GetIDsOfNames(
  164. /* [in] */ REFIID riid,
  165. /* [size_is][in] */ LPOLESTR *rgszNames,
  166. /* [in] */ UINT cNames,
  167. /* [in] */ LCID lcid,
  168. /* [size_is][out] */ DISPID *rgDispId)
  169. {
  170. return CImpIDispatch::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId);
  171. }
  172. STDMETHODIMP Invoke(
  173. /* [in] */ DISPID dispIdMember,
  174. /* [in] */ REFIID riid,
  175. /* [in] */ LCID lcid,
  176. /* [in] */ WORD wFlags,
  177. /* [out][in] */ DISPPARAMS *pDispParams,
  178. /* [out] */ VARIANT *pVarResult,
  179. /* [out] */ EXCEPINFO *pExcepInfo,
  180. /* [out] */ UINT *puArgErr)
  181. {
  182. return CImpIDispatch::Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
  183. }
  184. STDMETHODIMP FinalBack(void);
  185. STDMETHODIMP FinalNext(void);
  186. STDMETHODIMP Cancel(void);
  187. STDMETHODIMP put_Caption(
  188. /* [in] */ BSTR bstrCaption);
  189. STDMETHODIMP get_Caption(
  190. /* [retval][out] */ BSTR *pbstrCaption);
  191. STDMETHODIMP put_Property(
  192. /* [in] */ BSTR bstrPropertyName,
  193. /* [in] */ VARIANT *pvProperty);
  194. STDMETHODIMP get_Property(
  195. /* [in] */ BSTR bstrPropertyName,
  196. /* [retval][out] */ VARIANT *pvProperty);
  197. STDMETHODIMP SetWizardButtons(
  198. /* [in] */ VARIANT_BOOL vfEnableBack,
  199. /* [in] */ VARIANT_BOOL vfEnableNext,
  200. /* [in] */ VARIANT_BOOL vfLastPage);
  201. STDMETHODIMP SetHeaderText(
  202. /* [in] */ BSTR bstrHeaderTitle,
  203. /* [in] */ BSTR bstrHeaderSubtitle);
  204. STDMETHODIMP PassportAuthenticate(
  205. /* [in] */ BSTR bstrSignInUrl,
  206. /* [retval][out] */ VARIANT_BOOL * pvfAuthenticated);
  207. // IWizardExtension
  208. STDMETHODIMP AddPages(HPROPSHEETPAGE* aPages, UINT cPages, UINT *pnPages);
  209. STDMETHODIMP GetFirstPage(HPROPSHEETPAGE *phPage);
  210. STDMETHODIMP GetLastPage(HPROPSHEETPAGE *phPage)
  211. { return GetFirstPage(phPage); }
  212. // IWebWizardExtension
  213. STDMETHODIMP SetInitialURL(LPCWSTR pszDefaultURL);
  214. STDMETHODIMP SetErrorURL(LPCWSTR pszErrorURL);
  215. protected:
  216. friend class CWebEventHandler;
  217. void _OnDownloadBegin();
  218. void _OnDocumentComplete();
  219. private:
  220. void _InitBrowser();
  221. HRESULT _NavigateBrowser(LPCWSTR pszUrl);
  222. HRESULT _CallScript(IWebBrowser2* pbrowser, LPCWSTR pszFunction);
  223. BOOL _IsScriptFunctionOnPage(IWebBrowser2* pbrowser, LPCWSTR pszFunction);
  224. BOOL _IsBrowserVisible();
  225. void _ShowBrowser(BOOL fShow);
  226. void _SizeProgress();
  227. void _ShowProgress(BOOL fShow);
  228. void _StartShowProgressTimer();
  229. void _SetHeaderText(LPCWSTR pszHeader, LPCWSTR pszSubHeader);
  230. virtual INT_PTR DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  231. static INT_PTR StaticProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  232. static UINT PropPageProc(HWND hwndDlg, UINT uMsg, PROPSHEETPAGE *ppsp);
  233. BOOL OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam);
  234. BOOL OnDestroy(HWND hwnd);
  235. BOOL OnNotify(HWND hwnd, int idCtrl, LPNMHDR pnmh);
  236. BOOL OnTimer(HWND hwnd, UINT nIDEvent);
  237. LONG _cRef;
  238. CWebEventHandler *_pwebEventHandler;
  239. IWebBrowser2 *_pwebbrowser;
  240. IOleInPlaceActiveObject *_poipao;
  241. HWND _hwndOCHost; // Web browser control window
  242. HWND _hwndFrame; // Wizard frame window
  243. HWND _hwnd; // Dialog window
  244. HPROPSHEETPAGE _hPage;
  245. LPWSTR _pszInitialURL;
  246. LPWSTR _pszErrorURL;
  247. };
  248. INT_PTR CWebWizardPage::StaticProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  249. {
  250. CWebWizardPage* pthis = (CWebWizardPage*) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  251. PROPSHEETPAGE* ppage;
  252. INT_PTR fProcessed;
  253. if (uMsg == WM_INITDIALOG)
  254. {
  255. ppage = (PROPSHEETPAGE*) lParam;
  256. pthis = (CWebWizardPage*) ppage->lParam;
  257. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pthis);
  258. }
  259. if (pthis != NULL)
  260. {
  261. fProcessed = pthis->DialogProc(hwndDlg, uMsg, wParam, lParam);
  262. }
  263. else
  264. {
  265. fProcessed = FALSE;
  266. }
  267. return fProcessed;
  268. }
  269. // construction and IUnknown
  270. CWebEventHandler::CWebEventHandler(CWebWizardPage *pwswp) :
  271. _pcpCurrentConnection(NULL),
  272. _pwizPage(pwswp)
  273. {
  274. }
  275. CWebEventHandler::~CWebEventHandler()
  276. {
  277. _Advise(FALSE);
  278. }
  279. HRESULT CWebEventHandler::QueryInterface(REFIID riid, void **ppv)
  280. {
  281. static const QITAB qit[] = {
  282. QITABENTMULTI(CWebEventHandler, IDispatch, DWebBrowserEvents2),
  283. QITABENTMULTI2(CWebEventHandler, DIID_DWebBrowserEvents2, DWebBrowserEvents2),
  284. // QITABENTMULTI2(CWebEventHandler, DIID_DWebBrowserEvents, DWebBrowserEvents),
  285. QITABENT(CWebEventHandler, IServiceProvider),
  286. { 0 },
  287. };
  288. return QISearch(this, qit, riid, ppv);
  289. }
  290. STDMETHODIMP CWebEventHandler::QueryService(REFGUID guidService, REFIID riid, void **ppv)
  291. {
  292. HRESULT hr = E_NOINTERFACE;
  293. *ppv = NULL; // no result yet
  294. // we are a site for the OleControlSite interfaces only
  295. if (guidService == SID_OleControlSite)
  296. {
  297. if (riid == IID_IDispatch)
  298. {
  299. hr = this->QueryInterface(riid, ppv);
  300. }
  301. }
  302. return hr;
  303. }
  304. HRESULT CWebEventHandler_CreateInstance(CWebWizardPage *pwswp, CWebEventHandler **ppweh)
  305. {
  306. *ppweh = new CWebEventHandler(pwswp);
  307. if (!*ppweh)
  308. return E_OUTOFMEMORY;
  309. return S_OK;
  310. }
  311. HRESULT CWebEventHandler::_Advise(BOOL fConnect)
  312. {
  313. HRESULT hr = S_OK;
  314. // If we're already connected, disconnect, since we either want to disconnect or reconnect to
  315. // a different webbrowser.
  316. if (_pcpCurrentConnection)
  317. {
  318. hr = _pcpCurrentConnection->Unadvise(_dwCPCookie);
  319. if (SUCCEEDED(hr))
  320. {
  321. ATOMICRELEASE(_pcpCurrentConnection);
  322. }
  323. }
  324. else
  325. {
  326. // We expect that if _pcpCurrentConnection is NULL, no code earlier would have changed hr, and that it is still S_OK
  327. // The code below expects that if !SUCCEEDED(hr), Unadvise failed above.
  328. ASSERT(SUCCEEDED(hr));
  329. }
  330. if (_pwizPage && _pwizPage->_pwebbrowser)
  331. {
  332. if (SUCCEEDED(hr) && fConnect)
  333. {
  334. IConnectionPointContainer* pcontainer;
  335. hr = _pwizPage->_pwebbrowser->QueryInterface(IID_PPV_ARG(IConnectionPointContainer, &pcontainer));
  336. if (SUCCEEDED(hr))
  337. {
  338. IConnectionPoint* pconnpoint;
  339. hr = pcontainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &pconnpoint);
  340. if (SUCCEEDED(hr))
  341. {
  342. IDispatch* pDisp;
  343. hr = QueryInterface(IID_PPV_ARG(IDispatch, &pDisp));
  344. if (SUCCEEDED(hr))
  345. {
  346. hr = pconnpoint->Advise(pDisp, &_dwCPCookie);
  347. pDisp->Release();
  348. }
  349. if (SUCCEEDED(hr))
  350. {
  351. // TODO: Enable ATOMICRELEASE() to verify we won't leak anything
  352. // ATOMICRELEASE(_pcpCurrentConnection);
  353. _pcpCurrentConnection = pconnpoint;
  354. }
  355. else
  356. {
  357. pconnpoint->Release();
  358. }
  359. }
  360. pcontainer->Release();
  361. }
  362. }
  363. }
  364. return hr;
  365. }
  366. HRESULT CWebEventHandler::Invoke(
  367. /* [in] */ DISPID dispIdMember,
  368. /* [in] */ REFIID riid,
  369. /* [in] */ LCID lcid,
  370. /* [in] */ WORD wFlags,
  371. /* [out][in] */ DISPPARAMS *pDispParams,
  372. /* [out] */ VARIANT *pVarResult,
  373. /* [out] */ EXCEPINFO *pExcepInfo,
  374. /* [out] */ UINT *puArgErr)
  375. {
  376. HRESULT hr = S_OK;
  377. switch (dispIdMember)
  378. {
  379. case DISPID_BEFORENAVIGATE2:
  380. _pwizPage->_OnDownloadBegin();
  381. break;
  382. case DISPID_DOCUMENTCOMPLETE:
  383. _pwizPage->_OnDocumentComplete();
  384. break;
  385. default:
  386. hr = DISP_E_MEMBERNOTFOUND;
  387. break;
  388. }
  389. return hr;
  390. }
  391. // Object for hosting HTML wizard pages
  392. CWebWizardPage::CWebWizardPage() :
  393. CImpIDispatch(LIBID_Shell32, 0, 0, IID_INewWDEvents),
  394. _cRef(1)
  395. {
  396. // Ensure zero-init happened
  397. ASSERT(NULL == _pwebbrowser);
  398. ASSERT(NULL == _pwebEventHandler);
  399. ASSERT(NULL == _pszInitialURL);
  400. ASSERT(NULL == _pszErrorURL);
  401. }
  402. CWebWizardPage::~CWebWizardPage()
  403. {
  404. ATOMICRELEASE(_pwebbrowser);
  405. ATOMICRELEASE(_pwebEventHandler);
  406. ATOMICRELEASE(_punkSite);
  407. ATOMICRELEASE(_poipao);
  408. Str_SetPtr(&_pszInitialURL, NULL);
  409. Str_SetPtr(&_pszErrorURL, NULL);
  410. }
  411. HRESULT CWebWizardPage::QueryInterface(REFIID riid, void **ppv)
  412. {
  413. static const QITAB qit[] =
  414. {
  415. QITABENTMULTI(CWebWizardPage, IWizardExtension, IWebWizardExtension),
  416. QITABENT(CWebWizardPage, IWebWizardExtension),
  417. QITABENT(CWebWizardPage, IDocHostUIHandler),
  418. QITABENT(CWebWizardPage, IServiceProvider),
  419. QITABENT(CWebWizardPage, INewWDEvents),
  420. QITABENT(CWebWizardPage, IDispatch),
  421. QITABENT(CWebWizardPage, IWebWizardExtension),
  422. QITABENT(CWebWizardPage, IObjectWithSite),
  423. { 0 },
  424. };
  425. return QISearch(this, qit, riid, ppv);
  426. }
  427. ULONG CWebWizardPage::AddRef()
  428. {
  429. return InterlockedIncrement(&_cRef);
  430. }
  431. ULONG CWebWizardPage::Release()
  432. {
  433. ASSERT( 0 != _cRef );
  434. ULONG cRef = InterlockedDecrement(&_cRef);
  435. if ( 0 == cRef )
  436. {
  437. delete this;
  438. }
  439. return cRef;
  440. }
  441. HRESULT CWebWizardPage::QueryService(REFGUID guidService, REFIID riid, void **ppv)
  442. {
  443. *ppv = NULL;
  444. if (_punkSite)
  445. return IUnknown_QueryService(_punkSite, guidService, riid, ppv);
  446. return E_NOINTERFACE;
  447. }
  448. void CWebWizardPage::_OnDownloadBegin()
  449. {
  450. _ShowBrowser(FALSE);
  451. _StartShowProgressTimer();
  452. SetWizardButtons(VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE);
  453. }
  454. void CWebWizardPage::_OnDocumentComplete()
  455. {
  456. if (!_IsScriptFunctionOnPage(_pwebbrowser, L"OnBack"))
  457. {
  458. // This is an invalid page; navigate to our private error page
  459. BSTR bstrOldUrl;
  460. if (_pwebbrowser && SUCCEEDED(_pwebbrowser->get_LocationURL(&bstrOldUrl)))
  461. {
  462. #ifdef DEBUG
  463. 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))
  464. {
  465. _ShowBrowser(TRUE);
  466. SysFreeString(bstrOldUrl);
  467. return;
  468. }
  469. #endif
  470. BSTR bstrUrl = NULL;
  471. BOOL fUsingCustomError = FALSE;
  472. // If we have a custom error URL and we haven't already failed trying
  473. // to navigate to this custom URL...
  474. if ((NULL != _pszErrorURL) &&
  475. (0 != StrCmpI(_pszErrorURL, bstrOldUrl)))
  476. {
  477. // then use the custom URL.
  478. bstrUrl = SysAllocString(_pszErrorURL);
  479. fUsingCustomError = TRUE;
  480. }
  481. else
  482. {
  483. bstrUrl = SysAllocString(L"res://shell32.dll/WebServiceError.htm");
  484. }
  485. if (bstrUrl)
  486. {
  487. _pwebbrowser->Navigate(bstrUrl, NULL, NULL, NULL, NULL);
  488. SysFreeString(bstrUrl);
  489. // Custom error URL will provide its own header and subheader
  490. if (!fUsingCustomError)
  491. {
  492. WCHAR szTitle[256];
  493. LoadString(g_hinst, IDS_WEBDLG_ERRTITLE, szTitle, ARRAYSIZE(szTitle));
  494. #ifdef DEBUG
  495. _SetHeaderText(szTitle, bstrOldUrl);
  496. #else
  497. _SetHeaderText(szTitle, L"");
  498. #endif
  499. }
  500. }
  501. SysFreeString(bstrOldUrl);
  502. }
  503. // else out of memory - oops.
  504. }
  505. else
  506. {
  507. _ShowBrowser(TRUE);
  508. }
  509. }
  510. HRESULT CWebWizardPage::GetHostInfo(DOCHOSTUIINFO* pInfo)
  511. {
  512. ZeroMemory(pInfo, sizeof(*pInfo));
  513. pInfo->cbSize = sizeof(*pInfo);
  514. pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
  515. pInfo->dwFlags = DOCHOSTUIFLAG_DIALOG | DOCHOSTUIFLAG_NO3DBORDER |
  516. DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE | DOCHOSTUIFLAG_THEME |
  517. DOCHOSTUIFLAG_FLAT_SCROLLBAR | DOCHOSTUIFLAG_LOCAL_MACHINE_ACCESS_CHECK;
  518. return S_OK;
  519. }
  520. HRESULT CWebWizardPage::GetExternal(IDispatch** ppDispatch)
  521. {
  522. return QueryInterface(IID_PPV_ARG(IDispatch, ppDispatch));
  523. }
  524. INT_PTR CWebWizardPage::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  525. {
  526. switch (uMsg)
  527. {
  528. HANDLE_MSG(hwndDlg, WM_INITDIALOG, OnInitDialog);
  529. HANDLE_MSG(hwndDlg, WM_DESTROY, OnDestroy);
  530. HANDLE_MSG(hwndDlg, WM_NOTIFY, OnNotify);
  531. HANDLE_MSG(hwndDlg, WM_TIMER, OnTimer);
  532. }
  533. return FALSE;
  534. }
  535. HRESULT CWebWizardPage::_CallScript(IWebBrowser2* pbrowser, LPCWSTR pszFunction)
  536. {
  537. HRESULT hr = E_INVALIDARG;
  538. if (pbrowser)
  539. {
  540. IDispatch* pdocDispatch;
  541. hr = pbrowser->get_Document(&pdocDispatch);
  542. if ((S_OK == hr) && pdocDispatch)
  543. {
  544. IHTMLDocument* pdoc;
  545. hr = pdocDispatch->QueryInterface(IID_PPV_ARG(IHTMLDocument, &pdoc));
  546. if (SUCCEEDED(hr))
  547. {
  548. IDispatch* pdispScript;
  549. hr = pdoc->get_Script(&pdispScript);
  550. if (S_OK == hr)
  551. {
  552. DISPID dispid;
  553. hr = pdispScript->GetIDsOfNames(IID_NULL, const_cast<LPWSTR*>(&pszFunction), 1, LOCALE_SYSTEM_DEFAULT, &dispid);
  554. if (SUCCEEDED(hr))
  555. {
  556. unsigned int uArgErr;
  557. DISPPARAMS dispparams = {0};
  558. hr = pdispScript->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, NULL, &uArgErr);
  559. }
  560. pdispScript->Release();
  561. }
  562. else
  563. {
  564. hr = E_FAIL;
  565. }
  566. pdoc->Release();
  567. }
  568. else
  569. {
  570. hr = E_FAIL;
  571. }
  572. pdocDispatch->Release();
  573. }
  574. }
  575. return hr;
  576. }
  577. BOOL CWebWizardPage::_IsScriptFunctionOnPage(IWebBrowser2* pbrowser, LPCWSTR pszFunction)
  578. {
  579. HRESULT hr = E_INVALIDARG;
  580. if (pbrowser)
  581. {
  582. IDispatch* pdocDispatch;
  583. hr = pbrowser->get_Document(&pdocDispatch);
  584. if (S_OK == hr && pdocDispatch)
  585. {
  586. IHTMLDocument* pdoc;
  587. hr = pdocDispatch->QueryInterface(IID_PPV_ARG(IHTMLDocument, &pdoc));
  588. if (SUCCEEDED(hr))
  589. {
  590. IDispatch* pdispScript;
  591. hr = pdoc->get_Script(&pdispScript);
  592. if (S_OK == hr)
  593. {
  594. DISPID dispid;
  595. hr = pdispScript->GetIDsOfNames(IID_NULL, const_cast<LPWSTR*>(&pszFunction), 1, LOCALE_SYSTEM_DEFAULT, &dispid);
  596. pdispScript->Release();
  597. }
  598. else
  599. {
  600. hr = E_FAIL;
  601. }
  602. pdoc->Release();
  603. }
  604. else
  605. {
  606. hr = E_FAIL;
  607. }
  608. pdocDispatch->Release();
  609. }
  610. }
  611. return (S_OK == hr) ? TRUE : FALSE;
  612. }
  613. // Uncomment this to NOT pass the LCID on the URL query string - for testing only.
  614. BOOL CWebWizardPage::OnNotify(HWND hwnd, int idCtrl, LPNMHDR pnmh)
  615. {
  616. switch (pnmh->code)
  617. {
  618. case PSN_SETACTIVE:
  619. {
  620. _SizeProgress();
  621. _ShowProgress(FALSE);
  622. _ShowBrowser(FALSE);
  623. // fetch the high contrast flag, and set accordingly for the HTML to read
  624. // its OK for us to fail setting this into the property bag.
  625. HIGHCONTRAST hc = {sizeof(hc)};
  626. if (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(hc), &hc, 0))
  627. {
  628. VARIANT var = {VT_BOOL};
  629. var.boolVal = (hc.dwFlags & HCF_HIGHCONTRASTON) ? VARIANT_TRUE:VARIANT_FALSE;
  630. put_Property(L"HighContrast", &var);
  631. }
  632. // Position the OCHost window
  633. RECT rectClient;
  634. GetClientRect(hwnd, &rectClient);
  635. SetWindowPos(_hwndOCHost, NULL, 0, 0, rectClient.right, rectClient.bottom, SWP_NOMOVE | SWP_NOOWNERZORDER);
  636. // set the initial URL
  637. if (_pszInitialURL)
  638. {
  639. WCHAR szURLWithLCID[INTERNET_MAX_URL_LENGTH];
  640. LPCWSTR pszFormat = StrChr(_pszInitialURL, L'?') ? L"%s&lcid=%d&langid=%d":L"%s?lcid=%d&langid=%d";
  641. if (SUCCEEDED(StringCchPrintf(szURLWithLCID,
  642. ARRAYSIZE(szURLWithLCID),
  643. pszFormat,
  644. _pszInitialURL,
  645. GetUserDefaultLCID(),
  646. GetUserDefaultUILanguage())))
  647. {
  648. _NavigateBrowser(szURLWithLCID);
  649. }
  650. }
  651. }
  652. break;
  653. // WIZNEXT and WIZBACK don't actually cause a navigation to occur - they instead forward on the message to the
  654. // hosted web page. Real wizard navigations occur when the hosted web page calls our FinalBack() and FinalNext() methods.
  655. case PSN_WIZNEXT:
  656. _CallScript(_pwebbrowser, L"OnNext");
  657. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1);
  658. return TRUE;
  659. case PSN_WIZBACK:
  660. _CallScript(_pwebbrowser, L"OnBack");
  661. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1);
  662. return TRUE;
  663. // query cancel results in a call to the site to determine if we are going
  664. // to cancel out and if the site wants to provide a page for us to navigate
  665. // to - in some cases, eg. the web publishing wizard this is important
  666. // so that we can cancel the order being processed etc.
  667. case PSN_QUERYCANCEL:
  668. if (_punkSite)
  669. {
  670. IWizardSite *pws;
  671. if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IWizardSite, &pws))))
  672. {
  673. HPROPSHEETPAGE hpage;
  674. if (S_OK == pws->GetCancelledPage(&hpage))
  675. {
  676. PropSheet_SetCurSel(GetParent(hwnd), hpage, -1);
  677. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LPARAM)TRUE);
  678. }
  679. pws->Release();
  680. }
  681. }
  682. return TRUE;
  683. case PSN_TRANSLATEACCELERATOR:
  684. {
  685. LPPSHNOTIFY ppsn = (LPPSHNOTIFY)pnmh;
  686. MSG *pmsg = (MSG *)ppsn->lParam;
  687. LONG_PTR lres = PSNRET_NOERROR;
  688. if (_poipao && S_OK == _poipao->TranslateAccelerator(pmsg))
  689. {
  690. lres = PSNRET_MESSAGEHANDLED;
  691. }
  692. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, lres);
  693. }
  694. break;
  695. }
  696. return TRUE;
  697. }
  698. BOOL CWebWizardPage::OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
  699. {
  700. _hwnd = hwnd;
  701. _hwndFrame = GetParent(hwnd);
  702. // lets remap some of the text in the dialog if we need to
  703. IResourceMap *prm;
  704. HRESULT hr = IUnknown_QueryService(_punkSite, SID_ResourceMap, IID_PPV_ARG(IResourceMap, &prm));
  705. if (SUCCEEDED(hr))
  706. {
  707. IXMLDOMNode *pdn;
  708. hr = prm->SelectResourceScope(TEXT("dialog"), TEXT("ws:downloading"), &pdn);
  709. if (SUCCEEDED(hr))
  710. {
  711. TCHAR szBuffer[512];
  712. if (SUCCEEDED(prm->LoadString(pdn, TEXT("header"), szBuffer, ARRAYSIZE(szBuffer))))
  713. {
  714. SetDlgItemText(hwnd, IDC_PROGTEXT1, szBuffer);
  715. }
  716. if (SUCCEEDED(prm->LoadString(pdn, TEXT("footer"), szBuffer, ARRAYSIZE(szBuffer))))
  717. {
  718. SetDlgItemText(hwnd, IDC_PROGTEXT2, szBuffer);
  719. }
  720. pdn->Release();
  721. }
  722. prm->Release();
  723. }
  724. // create the web view browser that we will show the providers HTML in
  725. SHDRC shdrc = {0};
  726. shdrc.cbSize = sizeof(shdrc);
  727. shdrc.dwFlags = SHDRCF_OCHOST;
  728. if (SHDOCVW_DllRegisterWindowClasses(&shdrc))
  729. {
  730. RECT rectClient;
  731. GetClientRect(hwnd, &rectClient);
  732. _hwndOCHost = CreateWindow(OCHOST_CLASS, NULL,
  733. WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_TABSTOP,
  734. 0, 0, rectClient.right, rectClient.bottom,
  735. hwnd, NULL, g_hinst, NULL);
  736. if (_hwndOCHost)
  737. {
  738. OCHINITSTRUCT ocs = {0};
  739. ocs.cbSize = sizeof(ocs);
  740. ocs.clsidOC = CLSID_WebBrowser;
  741. ocs.punkOwner = SAFECAST(this, IDocHostUIHandler*);
  742. hr = OCHost_InitOC(_hwndOCHost, (LPARAM)&ocs);
  743. if (SUCCEEDED(hr))
  744. {
  745. _InitBrowser();
  746. OCHost_DoVerb(_hwndOCHost, OLEIVERB_INPLACEACTIVATE, TRUE);
  747. ShowWindow(_hwndOCHost, TRUE);
  748. IServiceProvider* pSP;
  749. hr = _pwebEventHandler->QueryInterface(IID_PPV_ARG(IServiceProvider, &pSP));
  750. if (SUCCEEDED(hr))
  751. {
  752. OCHost_SetServiceProvider(_hwndOCHost, pSP);
  753. pSP->Release();
  754. }
  755. }
  756. }
  757. }
  758. if (FAILED(hr))
  759. EndDialog(hwnd, IDCANCEL);
  760. return TRUE;
  761. }
  762. BOOL CWebWizardPage::OnTimer(HWND hwnd, UINT nIDEvent)
  763. {
  764. if (nIDEvent == SHOW_PROGRESS_TIMER)
  765. {
  766. _ShowProgress(TRUE);
  767. }
  768. return TRUE;
  769. }
  770. BOOL CWebWizardPage::OnDestroy(HWND hwnd)
  771. {
  772. ATOMICRELEASE(_pwebbrowser);
  773. return TRUE;
  774. }
  775. void CWebWizardPage::_InitBrowser(void)
  776. {
  777. ASSERT(IsWindow(_hwndOCHost));
  778. ASSERT(!_pwebbrowser);
  779. HRESULT hr = OCHost_QueryInterface(_hwndOCHost, IID_PPV_ARG(IWebBrowser2, &_pwebbrowser));
  780. if (SUCCEEDED(hr) && _pwebbrowser)
  781. {
  782. ITargetFrame2* ptgf;
  783. if (SUCCEEDED(_pwebbrowser->QueryInterface(IID_PPV_ARG(ITargetFrame2, &ptgf))))
  784. {
  785. DWORD dwOptions;
  786. if (SUCCEEDED(ptgf->GetFrameOptions(&dwOptions)))
  787. {
  788. dwOptions |= FRAMEOPTIONS_BROWSERBAND | FRAMEOPTIONS_SCROLL_AUTO;
  789. ptgf->SetFrameOptions(dwOptions);
  790. }
  791. ptgf->Release();
  792. }
  793. _pwebbrowser->put_RegisterAsDropTarget(VARIANT_FALSE);
  794. // Set up the connection point (including creating the object
  795. if (!_pwebEventHandler)
  796. CWebEventHandler_CreateInstance(this, &_pwebEventHandler);
  797. if (_pwebEventHandler)
  798. _pwebEventHandler->_Advise(TRUE);
  799. OCHost_QueryInterface(_hwndOCHost, IID_PPV_ARG(IOleInPlaceActiveObject, &_poipao));
  800. }
  801. }
  802. HRESULT CWebWizardPage::_NavigateBrowser(LPCWSTR pszUrl)
  803. {
  804. HRESULT hr = E_FAIL;
  805. if (_hwndOCHost && _pwebbrowser)
  806. {
  807. BSTR bstrUrl = SysAllocString(pszUrl);
  808. if (bstrUrl)
  809. {
  810. hr = _pwebbrowser->Navigate(bstrUrl, NULL, NULL, NULL, NULL);
  811. SysFreeString(bstrUrl);
  812. }
  813. }
  814. return hr;
  815. }
  816. HRESULT CWebWizardPage::FinalBack(void)
  817. {
  818. if (_punkSite)
  819. {
  820. IWizardSite *pws;
  821. if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IWizardSite, &pws))))
  822. {
  823. HPROPSHEETPAGE hpage;
  824. HRESULT hr = pws->GetPreviousPage(&hpage);
  825. if (SUCCEEDED(hr))
  826. {
  827. PropSheet_SetCurSel(_hwndFrame, hpage, -1);
  828. }
  829. pws->Release();
  830. }
  831. }
  832. return S_OK;
  833. }
  834. HRESULT CWebWizardPage::FinalNext(void)
  835. {
  836. if (_punkSite)
  837. {
  838. IWizardSite *pws;
  839. if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IWizardSite, &pws))))
  840. {
  841. HPROPSHEETPAGE hpage;
  842. HRESULT hr = pws->GetNextPage(&hpage);
  843. if (SUCCEEDED(hr))
  844. {
  845. PropSheet_SetCurSel(_hwndFrame, hpage, -1);
  846. }
  847. pws->Release();
  848. }
  849. }
  850. return S_OK;
  851. }
  852. HRESULT CWebWizardPage::Cancel(void)
  853. {
  854. PropSheet_PressButton(_hwndFrame, PSBTN_CANCEL); // simulate cancel...
  855. return S_OK;
  856. }
  857. HRESULT CWebWizardPage::put_Caption(
  858. /* [in] */ BSTR bstrCaption)
  859. {
  860. return S_OK;
  861. }
  862. HRESULT CWebWizardPage::get_Caption(
  863. /* [retval][out] */ BSTR *pbstrCaption)
  864. {
  865. WCHAR szCaption[MAX_PATH];
  866. GetWindowText(_hwndFrame, szCaption, ARRAYSIZE(szCaption));
  867. *pbstrCaption = SysAllocString(szCaption);
  868. return S_OK;
  869. }
  870. // fetch and put properties into the frames property bag. this we do
  871. // by a QueryService call and then we can modify the properties accordingly.
  872. HRESULT CWebWizardPage::put_Property(
  873. /* [in] */ BSTR bstrPropertyName,
  874. /* [in] */ VARIANT *pvProperty)
  875. {
  876. IPropertyBag *ppb;
  877. HRESULT hr = IUnknown_QueryService(_punkSite, SID_WebWizardHost, IID_PPV_ARG(IPropertyBag, &ppb));
  878. if (SUCCEEDED(hr))
  879. {
  880. hr = ppb->Write(bstrPropertyName, pvProperty);
  881. ppb->Release();
  882. }
  883. return hr;
  884. }
  885. HRESULT CWebWizardPage::get_Property(
  886. /* [in] */ BSTR bstrPropertyName,
  887. /* [retval][out] */ VARIANT *pvProperty)
  888. {
  889. IPropertyBag *ppb;
  890. HRESULT hr = IUnknown_QueryService(_punkSite, SID_WebWizardHost, IID_PPV_ARG(IPropertyBag, &ppb));
  891. if (SUCCEEDED(hr))
  892. {
  893. hr = ppb->Read(bstrPropertyName, pvProperty, NULL);
  894. if (FAILED(hr))
  895. {
  896. // Return a NULL-variant
  897. VariantInit(pvProperty);
  898. pvProperty->vt = VT_NULL;
  899. hr = S_FALSE;
  900. }
  901. ppb->Release();
  902. }
  903. return hr;
  904. }
  905. HRESULT CWebWizardPage::SetWizardButtons(
  906. /* [in] */ VARIANT_BOOL vfEnableBack,
  907. /* [in] */ VARIANT_BOOL vfEnableNext,
  908. /* [in] */ VARIANT_BOOL vfLastPage)
  909. {
  910. // We ignore vfLastPage because it isn't the last page for us!
  911. DWORD dwButtons = 0;
  912. if (vfEnableBack)
  913. dwButtons |= PSWIZB_BACK;
  914. if (vfEnableNext)
  915. dwButtons |= PSWIZB_NEXT;
  916. PropSheet_SetWizButtons(_hwndFrame, dwButtons);
  917. return S_OK;
  918. }
  919. void CWebWizardPage::_SetHeaderText(LPCWSTR pszHeader, LPCWSTR pszSubHeader)
  920. {
  921. int iPageNumber = PropSheet_HwndToIndex(_hwndFrame, _hwnd);
  922. if (-1 != iPageNumber)
  923. {
  924. PropSheet_SetHeaderTitle(_hwndFrame, iPageNumber, pszHeader);
  925. PropSheet_SetHeaderSubTitle(_hwndFrame, iPageNumber, pszSubHeader);
  926. }
  927. }
  928. HRESULT CWebWizardPage::SetHeaderText(
  929. /* [in] */ BSTR bstrHeaderTitle,
  930. /* [in] */ BSTR bstrHeaderSubtitle)
  931. {
  932. _SetHeaderText(bstrHeaderTitle, bstrHeaderSubtitle);
  933. return S_OK;
  934. }
  935. HRESULT CWebWizardPage::PassportAuthenticate(
  936. /* [in] */ BSTR bstrURL,
  937. /* [retval][out] */ VARIANT_BOOL * pfAuthenticated)
  938. {
  939. *pfAuthenticated = VARIANT_FALSE; // the user isn't authenticated.
  940. IXMLHttpRequest *preq;
  941. HRESULT hr = CoCreateInstance(CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IXMLHttpRequest, &preq));
  942. if (SUCCEEDED(hr))
  943. {
  944. VARIANT varNULL = {0};
  945. VARIANT varAsync = {VT_BOOL};
  946. varAsync.boolVal = VARIANT_FALSE;
  947. // open a post request to the destination that we have
  948. hr = preq->open(L"GET", bstrURL, varAsync, varNULL, varNULL);
  949. if (SUCCEEDED(hr))
  950. {
  951. VARIANT varBody = {0};
  952. hr = preq->send(varBody);
  953. if (SUCCEEDED(hr))
  954. {
  955. long lStatus;
  956. hr = preq->get_status(&lStatus);
  957. if (SUCCEEDED(hr) && (lStatus == HTTP_STATUS_OK))
  958. {
  959. *pfAuthenticated = VARIANT_TRUE;
  960. }
  961. }
  962. }
  963. preq->Release();
  964. }
  965. return S_OK;
  966. }
  967. BOOL CWebWizardPage::_IsBrowserVisible()
  968. {
  969. return IsWindowVisible(_hwndOCHost);
  970. }
  971. void CWebWizardPage::_ShowBrowser(BOOL fShow)
  972. {
  973. ShowWindow(_hwndOCHost, fShow ? SW_SHOW : SW_HIDE);
  974. if (fShow)
  975. {
  976. // Can't have these windows overlapping.
  977. _ShowProgress(FALSE);
  978. }
  979. }
  980. void CWebWizardPage::_StartShowProgressTimer()
  981. {
  982. _ShowProgress(FALSE);
  983. if (!SetTimer(_hwnd, SHOW_PROGRESS_TIMER, SHOW_PROGRESS_TIMEOUT, NULL))
  984. {
  985. // Timer failed to set; show progress now;
  986. _ShowProgress(TRUE);
  987. }
  988. }
  989. // Size the progress bar to fit the client area it is in.
  990. void CWebWizardPage::_SizeProgress()
  991. {
  992. HWND hwndProgress = GetDlgItem(_hwnd, IDC_PROGRESS);
  993. RECT rcPage;
  994. GetClientRect(_hwnd, &rcPage);
  995. RECT rcProgress;
  996. GetClientRect(hwndProgress, &rcProgress);
  997. MapWindowPoints(hwndProgress, _hwnd, (LPPOINT) &rcProgress, 2);
  998. rcProgress.right = rcPage.right - rcProgress.left;
  999. SetWindowPos(hwndProgress, NULL, 0, 0, rcProgress.right - rcProgress.left, rcProgress.bottom - rcProgress.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOREPOSITION);
  1000. }
  1001. void CWebWizardPage::_ShowProgress(BOOL fShow)
  1002. {
  1003. HWND hwndProgress = GetDlgItem(_hwnd, IDC_PROGRESS);
  1004. ShowWindow(hwndProgress, fShow ? SW_SHOW : SW_HIDE);
  1005. ShowWindow(GetDlgItem(_hwnd, IDC_PROGTEXT1), fShow ? SW_SHOW : SW_HIDE);
  1006. ShowWindow(GetDlgItem(_hwnd, IDC_PROGTEXT2), fShow ? SW_SHOW : SW_HIDE);
  1007. KillTimer(_hwnd, SHOW_PROGRESS_TIMER);
  1008. if (fShow)
  1009. {
  1010. SendMessage(hwndProgress, PBM_SETMARQUEE, (WPARAM) TRUE, 0);
  1011. // Set the header/subheader to a "Connecting to Internet" message.
  1012. WCHAR szTitle[256];
  1013. WCHAR szSubtitle[256];
  1014. LoadString(g_hinst, IDS_WEBDLG_TITLE, szTitle, ARRAYSIZE(szTitle));
  1015. LoadString(g_hinst, IDS_WEBDLG_SUBTITLE, szSubtitle, ARRAYSIZE(szSubtitle));
  1016. _SetHeaderText(szTitle, szSubtitle);
  1017. }
  1018. else
  1019. {
  1020. SendMessage(hwndProgress, PBM_SETMARQUEE, (WPARAM) FALSE, 0);
  1021. }
  1022. }
  1023. // IWizardExtn
  1024. UINT CWebWizardPage::PropPageProc(HWND hwndDlg, UINT uMsg, PROPSHEETPAGE *ppsp)
  1025. {
  1026. CWebWizardPage *pwwp = (CWebWizardPage*)ppsp->lParam;
  1027. switch (uMsg)
  1028. {
  1029. case PSPCB_CREATE:
  1030. return TRUE;
  1031. // we need to release our site in this scenario, we know that we won't be using it
  1032. // anymore, and to ensure that clients down have a circular refernce to us we
  1033. // release it before they call us for our final destruction.
  1034. case PSPCB_RELEASE:
  1035. ATOMICRELEASE(pwwp->_punkSite);
  1036. break;
  1037. }
  1038. return FALSE;
  1039. }
  1040. HRESULT CWebWizardPage::AddPages(HPROPSHEETPAGE* aPages, UINT cPages, UINT *pnPages)
  1041. {
  1042. PROPSHEETPAGE psp = { 0 };
  1043. psp.dwSize = sizeof(psp);
  1044. psp.hInstance = g_hinst;
  1045. psp.dwFlags = PSP_DEFAULT|PSP_USECALLBACK ;
  1046. psp.pszTemplate = MAKEINTRESOURCE(DLG_WEBWIZARD);
  1047. psp.lParam = (LPARAM) this;
  1048. psp.pfnDlgProc = CWebWizardPage::StaticProc;
  1049. psp.pfnCallback = PropPageProc;
  1050. _hPage = CreatePropertySheetPage(&psp);
  1051. if (!_hPage)
  1052. return E_FAIL;
  1053. // return the page we created.
  1054. *aPages = _hPage;
  1055. *pnPages = 1;
  1056. return S_OK;
  1057. }
  1058. STDMETHODIMP CWebWizardPage::GetFirstPage(HPROPSHEETPAGE *phPage)
  1059. {
  1060. *phPage = _hPage;
  1061. return S_OK;
  1062. }
  1063. STDMETHODIMP CWebWizardPage::SetInitialURL(LPCWSTR pszDefaultURL)
  1064. {
  1065. HRESULT hr = E_INVALIDARG;
  1066. if (pszDefaultURL)
  1067. {
  1068. hr = Str_SetPtr(&_pszInitialURL, pszDefaultURL) ? S_OK:E_OUTOFMEMORY;
  1069. }
  1070. return hr;
  1071. }
  1072. STDMETHODIMP CWebWizardPage::SetErrorURL(LPCWSTR pszErrorURL)
  1073. {
  1074. HRESULT hr = E_INVALIDARG;
  1075. if (pszErrorURL)
  1076. {
  1077. hr = Str_SetPtr(&_pszErrorURL, pszErrorURL) ? S_OK:E_OUTOFMEMORY;
  1078. }
  1079. return hr;
  1080. }
  1081. STDAPI CWebWizardPage_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void **ppv)
  1082. {
  1083. if (NULL != pUnkOuter)
  1084. {
  1085. return CLASS_E_NOAGGREGATION;
  1086. }
  1087. CWebWizardPage *pwwp = new CWebWizardPage();
  1088. if (!pwwp)
  1089. {
  1090. return E_OUTOFMEMORY;
  1091. }
  1092. HRESULT hr = pwwp->QueryInterface(riid, ppv);
  1093. pwwp->Release();
  1094. return hr;
  1095. }